### README (README.md)

# Spring AI [](https://github.com/spring-projects/spring-ai/actions/workflows/continuous-integration.yml) [](https://central.sonatype.com/artifact/org.springframework.ai/spring-ai-model)

The Spring AI project provides a Spring-friendly API and abstractions for developing AI applications.

Its goal is to apply Spring ecosystem design principles, such as portability and modular design, to the AI domain and promote using strongly-typed data structures and APIs as the building blocks of an application.



At its core, Spring AI addresses the fundamental challenge of AI integration: connecting your enterprise __Data__ and __APIs__ with the __AI Models__.

## Getting Started

The [reference documentation](https://docs.spring.io/spring-ai/reference/) includes a [Getting Started](https://docs.spring.io/spring-ai/reference/getting-started.html) guide.

Spring Boot Version Compatibility:
* **Spring AI 2.x.x** ([main](https://github.com/spring-projects/spring-ai/tree/main) branch) - Spring Boot `4.x`
* **Spring AI 1.1.x** ([1.1.x](https://github.com/spring-projects/spring-ai/tree/1.1.x) branch) - Spring Boot `3.5.x`

## Project Resources

* [Reference documentation](https://docs.spring.io/spring-ai/reference/)
* [Javadoc](https://docs.spring.io/spring-ai/docs/current/api/)
* [Upgrade notes](https://docs.spring.io/spring-ai/reference/upgrade-notes.html)
* [Awesome Spring AI](https://github.com/spring-ai-community/awesome-spring-ai) - A curated list of awesome resources, tools, tutorials, and projects for building generative AI applications using Spring AI
* [Spring AI Examples](https://github.com/spring-projects/spring-ai-examples) - Contains example projects that explain specific features in more detail.
* [Spring AI Community](https://github.com/spring-ai-community) - A community-driven organization for building Spring-based integrations with AI models, agents, vector databases, and more.

## Contributing

We welcome contributions of all kinds!
Please read our [contribution guidelines](CONTRIBUTING.md) before submitting a pull request or an issue.

## Features

This is a high level feature overview.

* Support for all major [AI Model providers](https://docs.spring.io/spring-ai/reference/api/index.html) such as Anthropic, OpenAI, Amazon Bedrock, Google, Ollama, Mistral AI, DeepSeek, and more.
  Supported model types include:
  - [Chat](https://docs.spring.io/spring-ai/reference/api/chatmodel.html)
  - [Embedding](https://docs.spring.io/spring-ai/reference/api/embeddings.html)
  - [Text to Image](https://docs.spring.io/spring-ai/reference/api/imageclient.html)
  - [Audio Transcription](https://docs.spring.io/spring-ai/reference/api/audio/transcriptions.html)
  - [Text to Speech](https://docs.spring.io/spring-ai/reference/api/audio/speech.html)
  - [Moderation](https://docs.spring.io/spring-ai/reference/api/index.html#api/moderation)
* Portable API support across AI providers for both synchronous and streaming options.
  Access to [model-specific features](https://docs.spring.io/spring-ai/reference/api/chatmodel.html#_chat_options) is also available.
* [Structured Outputs](https://docs.spring.io/spring-ai/reference/api/structured-output-converter.html) - Mapping of AI Model output to POJOs.
* Support for all major [Vector Store providers](https://docs.spring.io/spring-ai/reference/api/vectordbs.html) such as *Amazon Bedrock Knowledge Base, Amazon S3, Apache Cassandra, Azure Vector Search, Chroma, Couchbase, Elasticsearch, GemFire, MariaDB, Milvus, MongoDB Atlas, Neo4j, OpenSearch, Oracle, PostgreSQL/PGVector, Pinecone, Qdrant, Redis, Typesense, and Weaviate*.
* Portable API across Vector Store providers, including a novel SQL-like [metadata filter API](https://docs.spring.io/spring-ai/reference/api/vectordbs.html#metadata-filters).
* [Tool Calling](https://docs.spring.io/spring-ai/reference/api/tools.html) - Permits the model to request the execution of client-side tools and functions, thereby accessing necessary real-time information as required.
* [Observability](https://docs.spring.io/spring-ai/reference/observability/index.html) - Provides insights into AI-related operations.
* Document injection [ETL framework](https://docs.spring.io/spring-ai/reference/api/etl-pipeline.html) for Data Engineering.
* [AI Model Evaluation](https://docs.spring.io/spring-ai/reference/api/testing.html) - Utilities to help evaluate generated content and protect against hallucinated response.
* [ChatClient API](https://docs.spring.io/spring-ai/reference/api/chatclient.html) - Fluent API for communicating with AI Chat Models, idiomatically similar to the WebClient and RestClient APIs.
* [Advisors API](https://docs.spring.io/spring-ai/reference/api/advisors.html) - Encapsulates recurring Generative AI patterns, transforms data sent to and from Language Models (LLMs), and provides portability across various models and use cases.
* [MCP (Model Context Protocol)](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html) - First-class support via Boot Starters and MCP Java Annotations for building AI applications that consume MCP servers or expose Spring-based services to the AI ecosystem, with STDIO, SSE, and Streamable-HTTP transport support.
* Support for [Chat Conversation Memory](https://docs.spring.io/spring-ai/reference/api/chatclient.html#_chat_memory) with pluggable persistent backends (JDBC, Cassandra, MongoDB, Neo4j, Redis) and [Retrieval Augmented Generation (RAG)](https://docs.spring.io/spring-ai/reference/api/chatclient.html#_retrieval_augmented_generation).
* Spring Boot Auto Configuration and Starters for all AI Models and Vector Stores - use [start.spring.io](https://start.spring.io/) to select the Model or Vector Store of choice.

## Building from source

You don’t need to build from source to use Spring AI.
If you want to try out the latest and greatest, Spring AI can be built and published to your local Maven repository:
```shell
./mvnw clean install
```
This command builds all modules, runs unit tests, and publishes artifacts to your local Maven repository.

Please read our [contribution guidelines](CONTRIBUTING.md) for more details.

---

### AGENTS (AGENTS.md)

Follow [CONTRIBUTING.md](CONTRIBUTING.md) for code style, commit messages, pull requests and to learn the most useful build commands.

---

### CLAUDE (CLAUDE.md)

Follow @CONTRIBUTING.md for code style, commit messages, pull requests and to learn the most useful build commands.

---

### CONTRIBUTING (CONTRIBUTING.md)

# Contributing to Spring AI

Spring AI is released under the Apache 2.0 license. If you would like to contribute something, or want to hack on the code, this document should help you get started.

## Code of Conduct

This project adheres to the Contributor Covenant [code of conduct](https://github.com/spring-projects/spring-ai#coc-ov-file).
By participating, you are expected to uphold this code.
Please report unacceptable behavior to code-of-conduct@spring.io.

**We accept contributions created with the help of AI coding agents, but they must be carefully reviewed by a human who remains accountable for the quality of the contribution.**
Contributions submitted by GitHub accounts controlled by autonomous AI bots are forbidden and will result in permanent bans.

## Reporting Security Vulnerabilities

If you think you have found a security vulnerability in Spring AI please **DO NOT** disclose it publicly until we've had a chance to fix it.
Please don't report security vulnerabilities using GitHub issues or pull requests, instead head over to https://spring.io/security-policy and learn how to disclose them responsibly.

## Ask questions

If you have a question, check Stack Overflow using [this list of tags](https://stackoverflow.com/questions/tagged/spring-ai) or [Spring AI discussions](https://github.com/spring-projects/spring-ai/discussions).
Find an existing discussion, or start a new one if necessary.

## How to contribute

### Search first

Is there already an existing [issue](https://github.com/spring-projects/spring-ai/issues) or a [pull request](https://github.com/spring-projects/spring-ai/pulls) that addresses your concern?
Search to see if you can find something similar before creating a new one.

### Submit an issue

If you are reporting a bug, please help to speed up problem diagnosis by providing as much information as possible.
Ideally, that would include a small sample project that reproduces the problem, shared with a link to a related source repository or attached as an archive with instructions on how to reproduce.

You can also submit an enhancement or a new feature proposal.

The issue title is used to generate the changelog so please use a short and descriptive text with types or filenames enclosed in backticks. 

### Submit a pull request

Should you create an issue first?
No, just create the pull request and use the description to provide context and motivation, as you would for an issue.
You only have to create an issue if you want to start a discussion first.

Please don't submit pull requests:

* With GitHub accounts managed by autonomous AI bots
* For already assigned issues (as the assignee is or plans to work on it)
* For straightforward or polish-style changes

The pull request title is used to generate the changelog so please use a short and descriptive text with types or filenames enclosed in backticks.
If your pull request is related to an issue, please mention the related issue with its number in the PR description (not in the title), for example "Fixes #123".

Before submitting a pull request:

* Add new tests that exercise the code you have added or modified
* Run the build and tests locally with `./mvnw clean package`
* If possible run integration tests related to the part you modify (see related documentation below)
* Any code needs to be carefully reviewed by a human, especially when generated by a coding agent

## Commit message

A commit message should include a short title (if possible less than 50 characters) starting with an uppercase verb.
The title should *not* include prefixes like `fix:`, `feat:` or `docs:` or the issue/PR number.

- ✅ Add Contribution Guidelines
- ❌ GH-123: Add Contribution Guidelines
- ❌ docs: Add Contribution Guidelines
- ❌ Add Contribution Guidelines (#123)

The commit description should be wrapped at approximately 72 characters.

Commit messages should allow discoverability of related issues and PRs [by linking them](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) after the description with for example `Closes #123` if the issue number is 123.
That allows bi-directional navigation from the commit to the issue/PR, but also in the other way around as related mentions are added by GitHub.

All commits must include a __Signed-off-by__ trailer at the end of each commit message to indicate that the contributor agrees to the Developer Certificate of Origin.
For additional details, please refer to the blog post [Hello DCO, Goodbye CLA: Simplifying Contributions to Spring](https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring).

Please find below the example of a typical commit message:

```text
    Add Contribution Guidelines

    This commit adds CONTRIBUTING.md describing the Contribution
    procedure, mentions Contribution Guidelines in the README.md and
    mentions CODE_OF_CONDUCT in the README.md.

    Fixes #123

    Signed-off-by: Firstname Lastname <username@users.noreply.github.com>
```

If you want to only reference some issue or PR without closing it, you can use `See #123`.
Annotations should be enclosed in backticks to avoid mentioning potential related GitHub users.  

If the commit has both an issue and a PR associated, the Spring AI committer merging the PR should reference both the issue and the PR and ensure the title does not contain the number of the PR, for example with an issue #123 and a PR #456:
```text
    Add Contribution Guidelines

    ...

    Fixes #123
    Closes #456

    Signed-off-by: Firstname Lastname <username@users.noreply.github.com>
```

## Source code style

Spring AI source code style follows the checkstyle guidelines used by the [core Spring Framework project](https://github.com/spring-projects/spring-framework/wiki/Code-Style) with some exceptions.
See also related [IntelliJ IDEA Editor Settings](https://github.com/spring-projects/spring-framework/blob/main/src/idea/spring-framework.xml).

The code is formatted using the [java-format plugin](https://github.com/spring-io/spring-javaformat) as part of the build.
Correct formatting is enforced by CI.

To format the code specifically:

```shell
./mvnw process-sources
```
Note that this will not format the import order which is documented below.

### Formatting

Please carefully follow the whitespace and formatting conventions already present in the framework.

* UTF-8 encoding
* Tabs, not spaces
* Unix (LF), not DOS (CRLF) line endings
* Eliminate all trailing whitespace
* Wrap Javadoc at 90 characters
* Aim to wrap code at 120 characters, but favor readability over wrapping
* Preserve existing formatting; i.e. do not reformat code for its own sake
* For plain text documents like `.adoc` or `.md`, one sentence per line

The import statements are structured as follows:

* import `java.*`
* blank line
* import `javax.*`
* import `jakarta.*`
* blank line
* import all other imports
* blank line
* import `org.springframework.*`
* blank line
* import static all other imports

Static imports should not be used in production code, but they should be used in test code, especially for things like `import static org.assertj.core.api.Assertions.assertThat;`.

Although static imports are generally forbidden in production code, the following are use cases for which static imports are permissible.

* constants (including enum constants): such as those in `java.nio.charset.StandardCharsets` or `org.springframework.core.annotation.MergedAnnotations.SearchStrategy`
* static factory methods for third-party DSLs: such as the methods in `org.junit.platform.engine.discovery.DiscoverySelectors` when used with the JUnit Platform `Launcher` API

Wildcard imports such as `import java.util.*` or `import static org.assertj.core.api.Assertions.*` are forbidden, even in test code.

### Source file structure

A source file consists of the following, in this exact order:

* License
* Package statement
* Import statements
* Exactly one top-level class

Exactly one blank line separates each of the above sections.

#### License

```java
/*
 * Copyright 2023-present the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
```

#### `@since` tags

Use `@since` tags for newly-added public API types and methods e.g.

```java
/**
 * ...
 *
 * @since 2.0.0
 */
```

### Working with the code

#### Building from source

The project can be built from the root directory using the standard Maven command:
```shell
./mvnw clean package
```

##### JDK

The project targets and builds artifacts compatible with Java 17+, and requires a JDK with support for the [`-XDaddTypeAnnotationsToSymbol` javac argument](https://bugs.openjdk.org/browse/JDK-8373586), like Liberica 17.0.19+, for nullability checks.

The recommended JDK is specified in the `.sdkmanrc` file, which can be installed and configured with the [SDKMAN!](https://sdkman.io/) tool:
- `sdk env install` to install the related JDK locally
- `sdk env` to use the related JDK

**NOTE:** Make sure to use a JDK with the same architecture as your processor, not an emulated one (for example with Rosetta on Mac) as Spring AI requires components that depend on your specific CPU architecture (PyTorch for example). If you are unsure if you have the correct JDK distribution for your CPU, run the command `java -XshowSettings:properties -version 2>&1 | grep os.arch` to validate that it matches your machine.

##### Maven build-cache extension

The [Maven build-cache extension](https://maven.apache.org/extensions/maven-build-cache-extension/) is enabled by default to speedup builds.

If you suspect the build cache is in an invalid state (build broken for no identified reason), try to run the build while disabling the build cache, for example with:

```shell
./mvnw -Dmaven.build.cache.enabled=false clean package
```

If the build passes without the cache, please [file an issue](https://github.com/spring-projects/spring-ai/issues) describing with as much detail as possible how that happened, and remove the local cache as a workaround:

```shell
rm -rf ~/.m2/build-cache/
```

#### Integration Tests

There are many integration tests, so it often isn't realistic to run them all at once.
Note that you should set API key environment variables for model providers before running.
If the API key isn't set for a specific model provider, the integration test is skipped.

To run the integration test for a specific module:

```shell
./mvnw -am -pl spring-ai-spring-boot-testcontainers -Pintegration-tests verify
```

To run a specific integration test allowing for up to two attempts to succeed (this is useful when a hosted service is not reliable or times out):

```shell
./mvnw -am -pl vector-stores/spring-ai-pgvector-store -Pintegration-tests -Dfailsafe.failIfNoSpecifiedTests=false -Dfailsafe.rerunFailingTestsCount=2 -Dit.test=PgVectorStoreIT verify
```

A quick pass through the most important pathways that runs integration tests can be done with the profile `-Pci-fast-integration-tests` and is used in the main CI build of this project.
Full integration tests are done regularly in the [Spring AI Integration Tests](https://github.com/spring-projects/spring-ai-integration-tests) repository.

#### Javadocs

To check javadocs using the [javadoc:javadoc](https://maven.apache.org/plugins/maven-javadoc-plugin/):

```shell
./mvnw javadoc:javadoc
```

#### Reference documentation

To build the docs:

```shell
./mvnw -pl spring-ai-docs antora
```

The generated documentation is available at `spring-ai-docs/target/antora/site/index.html`.

---

### LICENSE (LICENSE.txt)

Apache License
                           Version 2.0, January 2004
                        https://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       https://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

---

### Auto Configurations/Mcp/Spring Ai Autoconfigure Mcp Client Common/Src/Test/Resources/Test Config.Json (auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-common/src/test/resources/test-config.json)

{
  "name": "test-config",
  "description": "Test JSON file in root test resources folder",
  "version": "1.0.0",
  "properties": {
	"testProperty1": "value1"
  }
}

---

### Auto Configurations/Mcp/Spring Ai Autoconfigure Mcp Client Common/Src/Test/Resources/Nested/Nested Config.Json (auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-common/src/test/resources/nested/nested-config.json)

{
  "name": "nested-config",
  "description": "Test JSON file in nested subfolder of test resources",
  "version": "1.0.0",
  "nestedProperties": {
	"nestedProperty1": "nestedValue1"
  }
}

---

### Auto Configurations/Mcp/Spring Ai Autoconfigure Mcp Client Httpclient/Src/Test/Resources/Test Config.Json (auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient/src/test/resources/test-config.json)

{
  "name": "test-config",
  "description": "Test JSON file in root test resources folder",
  "version": "1.0.0",
  "properties": {
	"testProperty1": "value1"
  }
}

---

### Auto Configurations/Mcp/Spring Ai Autoconfigure Mcp Client Httpclient/Src/Test/Resources/Nested/Nested Config.Json (auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient/src/test/resources/nested/nested-config.json)

{
  "name": "nested-config",
  "description": "Test JSON file in nested subfolder of test resources",
  "version": "1.0.0",
  "nestedProperties": {
	"nestedProperty1": "nestedValue1"
  }
}

---

### Auto Configurations/Mcp/Spring Ai Autoconfigure Mcp Client Webflux/Src/Test/Resources/Test Config.Json (auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-webflux/src/test/resources/test-config.json)

{
  "name": "test-config",
  "description": "Test JSON file in root test resources folder",
  "version": "1.0.0",
  "properties": {
	"testProperty1": "value1"
  }
}

---

### Auto Configurations/Mcp/Spring Ai Autoconfigure Mcp Client Webflux/Src/Test/Resources/Nested/Nested Config.Json (auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-webflux/src/test/resources/nested/nested-config.json)

{
  "name": "nested-config",
  "description": "Test JSON file in nested subfolder of test resources",
  "version": "1.0.0",
  "nestedProperties": {
	"nestedProperty1": "nestedValue1"
  }
}

---

### Auto Configurations/Models/Chat/Client/Spring Ai Autoconfigure Model Chat Client/Src/Main/Resources/META INF/Additional Spring Configuration Metadata.Json (auto-configurations/models/chat/client/spring-ai-autoconfigure-model-chat-client/src/main/resources/META-INF/additional-spring-configuration-metadata.json)

{
  "properties": [
    {
      "name": "spring.ai.model.chat",
      "type": "java.lang.String",
      "description": "The primary ChatModel to autoconfigure. If not set, each ChatModel auto-configuration is enabled by default.",
      "defaultValue": ""
    },
    {
      "name": "spring.ai.model.embedding",
      "type": "java.lang.String",
      "description": "The primary EmbeddingModel to autoconfigure. If not set, each EmbeddingModel auto-configuration is enabled by default.",
      "defaultValue": ""
    },
    {
      "name": "spring.ai.model.embedding.text",
      "type": "java.lang.String",
      "description": "The primary EmbeddingModel for text embeddings to autoconfigure. If not set, each text EmbeddingModel auto-configuration is enabled by default.",
      "defaultValue": ""
    },
    {
      "name": "spring.ai.model.embedding.multimodal",
      "type": "java.lang.String",
      "description": "The primary EmbeddingModel for multimodal embeddings to autoconfigure. If not set, each multimodal EmbeddingModel auto-configuration is enabled by default.",
      "defaultValue": ""
    },
    {
      "name": "spring.ai.model.image",
      "type": "java.lang.String",
      "description": "The primary ImageModel to autoconfigure. If not set, each ImageModel auto-configuration is enabled by default.",
      "defaultValue": ""
    },
    {
      "name": "spring.ai.model.audio.transcription",
      "type": "java.lang.String",
      "description": "The primary TranscriptionModel to autoconfigure. If not set, each TranscriptionModel auto-configuration is enabled by default.",
      "defaultValue": ""
    },
    {
      "name": "spring.ai.model.audio.speech",
      "type": "java.lang.String",
      "description": "The primary SpeechModel to autoconfigure. If not set, each SpeechModel auto-configuration is enabled by default.",
      "defaultValue": ""
    },
    {
      "name": "spring.ai.model.moderation",
      "type": "java.lang.String",
      "description": "The primary ModerationModel to autoconfigure. If not set, each ModerationModel auto-configuration is enabled by default.",
      "defaultValue": ""
    }
  ]
}

---

### Auto Configurations/Models/Spring Ai Autoconfigure Model Google Genai/MIGRATION GUIDE (auto-configurations/models/spring-ai-autoconfigure-model-google-genai/MIGRATION_GUIDE.md)

# Migration Guide: Spring AI Google GenAI Autoconfiguration

## Overview

This guide helps you migrate from the old Vertex AI-based autoconfiguration to the new Google GenAI SDK-based autoconfiguration.

## Starter Dependencies

Spring AI provides separate starters for Google GenAI functionality:

### Chat Functionality
```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-google-genai</artifactId>
    <version>1.1.0-SNAPSHOT</version>
</dependency>
```

### Embedding Functionality
```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-google-genai-embedding</artifactId>
    <version>1.1.0-SNAPSHOT</version>
</dependency>
```

**Note**: If you need both chat and embedding capabilities, include both starters in your project. The starters are designed to be used independently or together based on your requirements.

## Key Changes

### 1. Property Namespace Changes

Old properties:
```properties
spring.ai.vertex.ai.gemini.project-id=my-project
spring.ai.vertex.ai.gemini.location=us-central1
spring.ai.vertex.ai.gemini.chat.options.model=gemini-pro
spring.ai.vertex.ai.embedding.text.options.model=textembedding-gecko
```

New properties:
```properties
# For Vertex AI mode
spring.ai.google.genai.project-id=my-project
spring.ai.google.genai.location=us-central1
spring.ai.google.genai.chat.model=gemini-2.0-flash

# For Gemini Developer API mode (new!)
spring.ai.google.genai.api-key=your-api-key
spring.ai.google.genai.chat.model=gemini-2.0-flash

# Embedding properties
spring.ai.google.genai.embedding.project-id=my-project
spring.ai.google.genai.embedding.location=us-central1
spring.ai.google.genai.embedding.text.options.model=text-embedding-004
```

### 2. New Authentication Options

The new SDK supports both:
- **Vertex AI mode**: Using Google Cloud credentials (same as before)
- **Gemini Developer API mode**: Using API keys (new!)

### 3. Removed Features

- `transport` property is no longer needed
- Multimodal embedding autoconfiguration has been removed (pending support in new SDK)

### 4. Bean Name Changes

If you were autowiring beans by name:
- `vertexAi` → `googleGenAiClient`
- `vertexAiGeminiChat` → `googleGenAiChatModel`
- `textEmbedding` → `googleGenAiTextEmbedding`

### 5. Class Changes

If you were importing classes directly:
- `com.google.cloud.vertexai.VertexAI` → `com.google.genai.Client`
- `org.springframework.ai.vertexai.gemini.*` → `org.springframework.ai.google.genai.*`

## Migration Steps

1. Update your application properties:
   - Replace `spring.ai.vertex.ai.*` with `spring.ai.google.genai.*`
   - Remove any `transport` configuration

2. If using API key authentication:
   - Set `spring.ai.google.genai.api-key` property
   - Remove project-id and location for chat (not needed with API key)

3. Update any custom configurations or bean references

4. Test your application thoroughly

## Environment Variables
```bash
export GOOGLE_CLOUD_PROJECT=my-project
export GOOGLE_CLOUD_LOCATION=us-central1
```

New (additional option):
```bash
export GOOGLE_API_KEY=your-api-key
```

## Backward Compatibility

The old autoconfiguration module is still available but deprecated. We recommend migrating to the new module as soon as possible.

---

### Auto Configurations/Models/Spring Ai Autoconfigure Model Google Genai/Src/Test/Resources/Fake Credentials.Json (auto-configurations/models/spring-ai-autoconfigure-model-google-genai/src/test/resources/fake-credentials.json)

{
  "type": "authorized_user",
  "client_id": "test-client-id.apps.googleusercontent.com",
  "client_secret": "test-client-secret",
  "refresh_token": "test-refresh-token"
}

---

### Auto Configurations/Models/Spring Ai Autoconfigure Model Mistral Ai/Src/Main/Resources/META INF/Additional Spring Configuration Metadata.Json (auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai/src/main/resources/META-INF/additional-spring-configuration-metadata.json)

{
  "groups": [
	{
	  "name": "spring.ai.mistralai.chat.tool-choice",
	  "type": "org.springframework.ai.mistralai.api.MistralAiApi$ChatCompletionRequest$ToolChoice",
	  "sourceType": "org.springframework.ai.model.mistralai.autoconfigure.MistralAiChatProperties"
	}
  ],
  "properties": [],
  "hints": []
}

---

### Auto Configurations/Models/Spring Ai Autoconfigure Model Openai/Src/Main/Resources/META INF/Additional Spring Configuration Metadata.Json (auto-configurations/models/spring-ai-autoconfigure-model-openai/src/main/resources/META-INF/additional-spring-configuration-metadata.json)

{
  "groups": [
	{
	  "name": "spring.ai.openai.chat.output-audio",
	  "type": "org.springframework.ai.openai.OpenAiChatOptions$AudioParameters",
	  "sourceType": "org.springframework.ai.openai.OpenAiChatOptions"
	}
  ],
  "properties": [
	{
	  "name": "spring.ai.openai.chat.output-audio.voice",
	  "type": "org.springframework.ai.openai.OpenAiChatOptions$AudioParameters$Voice",
	  "sourceType": "org.springframework.ai.openai.OpenAiChatOptions$AudioParameters"
	},
	{
	  "name": "spring.ai.openai.chat.output-audio.format",
	  "type": "org.springframework.ai.openai.OpenAiChatOptions$AudioParameters$AudioResponseFormat",
	  "sourceType": "org.springframework.ai.openai.OpenAiChatOptions$AudioParameters"
	}
  ],
  "hints": []
}

---

### Document Readers/Spring Ai Jsoup Document Reader/ README (document-readers/spring-ai-jsoup-document-reader/ README.md)

# Spring AI JSoup Document Reader

This module provides an HTML document reader for the Spring AI project. It leverages the [JSoup](https://jsoup.org/) library to parse HTML content and extract text and metadata, making it suitable for use in AI applications.

## Features

*   **Flexible Text Extraction:**
    *   Extract all text from the `<body>` of an HTML document.
    *   Extract text from specific elements using CSS selectors.
    *   Group text by element, creating a separate document for each selected element.
    *   Combine text from multiple selected elements using a configurable separator.
*   **Metadata Extraction:**
    *   Extract the document title.
    *   Extract content from `<meta>` tags (e.g., description, keywords).  You can specify which meta tags to extract.
    *   Extract a list of all absolute URLs of links (`<a href="...">`) within the document.
*   **Configurable:**
    *   Specify the character encoding (defaults to UTF-8).
    *   Customize the CSS selector for element selection.
    *   Configure the separator string for joining text from multiple elements.
    *   Choose whether to extract all text or use element-based extraction.
    *   Enable/disable link URL extraction.
    * Add additional metadata using configuration.
*   **Resource-Based:** Works with Spring's `Resource` abstraction, allowing you to read HTML from files, classpath resources, URLs, and even in-memory byte arrays.

---

#### How to Build:
```bash
./mvnw -pl document-readers/jsoup-reader clean install 
```

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Blockquote (document-readers/spring-ai-markdown-document-reader/src/test/resources/blockquote.md)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur diam eros, laoreet sit amet cursus vitae, varius sed
nisi. Cras sit amet quam quis velit commodo porta consectetur id nisi. Phasellus tincidunt pulvinar augue.

> Proin vel laoreet leo, sed luctus augue. Sed et ligula commodo, commodo lacus at, consequat turpis. Maecenas eget
> sapien odio. Maecenas urna lectus, pellentesque in accumsan aliquam, congue eu libero. Ut rhoncus nec justo a
> porttitor. Pellentesque auctor pharetra eros, viverra sodales lorem aliquet id. Curabitur semper nisi vel sem interdum
> suscipit.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Code (document-readers/spring-ai-markdown-document-reader/src/test/resources/code.md)

This is a Java sample application:

```java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
```

Markdown also provides the possibility to `use inline code formatting throughout` the entire sentence.

---

Another possibility is to set block code without specific highlighting:

```
./mvnw spring-javaformat:apply
```

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Horizontal Rules (document-readers/spring-ai-markdown-document-reader/src/test/resources/horizontal-rules.md)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt velit non bibendum gravida.

---

Cras accumsan tincidunt ornare. Donec hendrerit consequat tellus blandit accumsan. Aenean aliquam metus at arcu
elementum dignissim.

***
Nullam nisi dui, egestas nec sem nec, interdum lobortis enim. Pellentesque odio orci, faucibus eu luctus nec, venenatis
et magna.

* * *

Vestibulum nec eros non felis fermentum posuere eget ac risus. Curabitur et fringilla massa. Cras facilisis nec nisl sit
amet sagittis.

*****

Aenean eu leo eu nibh tristique posuere quis quis massa. Nullam lacinia luctus sem ut vehicula.

---------------------------------------

Aenean quis vulputate mi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nam tincidunt nunc a tortor tincidunt, nec lobortis diam rhoncus.

- - -

Nulla facilisi. Phasellus eget tellus sed nibh ornare interdum eu eu mi.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Lists (document-readers/spring-ai-markdown-document-reader/src/test/resources/lists.md)

## Ordered list

1. Lorem ipsum dolor sit *amet*, consectetur adipiscing elit. **Curabitur** diam eros, laoreet sit _amet_ cursus vitae,
   varius sed nisi.
2. Cras sit amet quam quis velit commodo porta consectetur id nisi. Phasellus tincidunt pulvinar augue.
3. Proin vel laoreet leo, sed luctus augue. Sed et ligula commodo, commodo lacus at, consequat turpis. Maecenas eget
   sapien odio.
    1. Pellentesque auctor pharetra eros, viverra sodales lorem aliquet id. Curabitur semper nisi vel sem interdum
       suscipit.
    2. Maecenas urna lectus, pellentesque in accumsan aliquam, congue eu libero. Ut rhoncus nec justo a porttitor.

## Unordered list

* Aenean eu leo eu nibh tristique posuere quis quis massa.
* Aenean imperdiet libero dui, nec malesuada dui maximus vel. Vestibulum sed dui condimentum, cursus libero in, dapibus
  tortor.
    * Etiam facilisis enim in egestas dictum.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Only Headers (document-readers/spring-ai-markdown-document-reader/src/test/resources/only-headers.md)

# Header 1a

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur diam eros, laoreet sit amet cursus vitae, varius sed
nisi. Cras sit amet quam quis velit commodo porta consectetur id nisi. Phasellus tincidunt pulvinar augue.

# Header 1b

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam lobortis risus libero, sed
sollicitudin risus cursus in. Morbi enim metus, ornare vel lacinia eget, venenatis vel nibh.

## Header 2b

Proin vel laoreet leo, sed luctus augue. Sed et ligula commodo, commodo lacus at, consequat turpis. Maecenas eget sapien
odio. Maecenas urna lectus, pellentesque in accumsan aliquam, congue eu libero.

# Header 1c

## Header 2c

Ut rhoncus nec justo a porttitor. Pellentesque auctor pharetra eros, viverra sodales lorem aliquet id. Curabitur semper nisi vel sem interdum suscipit.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Simple (document-readers/spring-ai-markdown-document-reader/src/test/resources/simple.md)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt velit non bibendum gravida. Cras accumsan
tincidunt ornare. Donec hendrerit consequat tellus blandit accumsan. Aenean aliquam metus at arcu elementum dignissim.

Nullam nisi dui, egestas nec sem nec, interdum lobortis enim. Pellentesque odio orci, faucibus eu luctus nec, venenatis et magna. Vestibulum nec eros non felis fermentum posuere eget ac risus.

Aenean eu leo eu nibh tristique posuere quis quis massa.\
Nullam lacinia luctus sem ut vehicula.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/With Formatting (document-readers/spring-ai-markdown-document-reader/src/test/resources/with-formatting.md)

# This is a fancy header name

Lorem ipsum dolor sit amet, **consectetur adipiscing elit**. Donec tincidunt velit non bibendum gravida. Cras accumsan
tincidunt ornare. Donec hendrerit consequat tellus *blandit* accumsan. Aenean aliquam metus at ***arcu elementum***
dignissim.

### Header 3

Aenean eu leo eu nibh tristique _posuere quis quis massa_.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Dir Test 1/Blockquote (document-readers/spring-ai-markdown-document-reader/src/test/resources/dir-test-1/blockquote.md)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur diam eros, laoreet sit amet cursus vitae, varius sed
nisi. Cras sit amet quam quis velit commodo porta consectetur id nisi. Phasellus tincidunt pulvinar augue.

> Proin vel laoreet leo, sed luctus augue. Sed et ligula commodo, commodo lacus at, consequat turpis. Maecenas eget
> sapien odio. Maecenas urna lectus, pellentesque in accumsan aliquam, congue eu libero. Ut rhoncus nec justo a
> porttitor. Pellentesque auctor pharetra eros, viverra sodales lorem aliquet id. Curabitur semper nisi vel sem interdum
> suscipit.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Dir Test 1/Blockquote (document-readers/spring-ai-markdown-document-reader/src/test/resources/dir-test-1/blockquote.txt)

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur diam eros, laoreet sit amet cursus vitae, varius sed
nisi. Cras sit amet quam quis velit commodo porta consectetur id nisi. Phasellus tincidunt pulvinar augue.

> Proin vel laoreet leo, sed luctus augue. Sed et ligula commodo, commodo lacus at, consequat turpis. Maecenas eget
> sapien odio. Maecenas urna lectus, pellentesque in accumsan aliquam, congue eu libero. Ut rhoncus nec justo a
> porttitor. Pellentesque auctor pharetra eros, viverra sodales lorem aliquet id. Curabitur semper nisi vel sem interdum
> suscipit.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Dir Test 2/Only Headers (document-readers/spring-ai-markdown-document-reader/src/test/resources/dir-test-2/only-headers.md)

# Header 1a

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur diam eros, laoreet sit amet cursus vitae, varius sed
nisi. Cras sit amet quam quis velit commodo porta consectetur id nisi. Phasellus tincidunt pulvinar augue.

# Header 1b

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Etiam lobortis risus libero, sed
sollicitudin risus cursus in. Morbi enim metus, ornare vel lacinia eget, venenatis vel nibh.

## Header 2b

Proin vel laoreet leo, sed luctus augue. Sed et ligula commodo, commodo lacus at, consequat turpis. Maecenas eget sapien
odio. Maecenas urna lectus, pellentesque in accumsan aliquam, congue eu libero.

# Header 1c

## Header 2c

Ut rhoncus nec justo a porttitor. Pellentesque auctor pharetra eros, viverra sodales lorem aliquet id. Curabitur semper nisi vel sem interdum suscipit.

---

### Document Readers/Spring Ai Markdown Document Reader/Src/Test/Resources/Dir Test 2/With Formatting (document-readers/spring-ai-markdown-document-reader/src/test/resources/dir-test-2/with-formatting.md)

# This is a fancy header name

Lorem ipsum dolor sit amet, **consectetur adipiscing elit**. Donec tincidunt velit non bibendum gravida. Cras accumsan
tincidunt ornare. Donec hendrerit consequat tellus *blandit* accumsan. Aenean aliquam metus at ***arcu elementum***
dignissim.

### Header 3

Aenean eu leo eu nibh tristique _posuere quis quis massa_.

---

### Memory Repositories/Spring Ai Model Chat Memory Repository Jdbc/README (memory-repositories/spring-ai-model-chat-memory-repository-jdbc/README.md)

[Chat Memory Documentation](https://docs.spring.io/spring-ai/reference/api/chatmemory.html)

---

### Memory Repositories/Spring Ai Model Chat Memory Repository Mongodb/README (memory-repositories/spring-ai-model-chat-memory-repository-mongodb/README.md)

[Chat Memory Documentation](https://docs.spring.io/spring-ai/reference/api/chat-memory.html#_chat_memory)

---

### Memory Repositories/Spring Ai Model Chat Memory Repository Redis/Src/Test/Resources/Application Metadata Schema.Yml (memory-repositories/spring-ai-model-chat-memory-repository-redis/src/test/resources/application-metadata-schema.yml)

spring:
  ai:
    chat:
      memory:
        redis:
          host: localhost
          port: 6379
          index-name: chat-memory-with-schema
          # Define metadata fields with their types for proper indexing
          # This is compatible with RedisVL schema format
          metadata-fields:
            - name: priority
              type: tag      # For exact match searches (high, medium, low)
            - name: category
              type: tag      # For exact match searches  
            - name: score
              type: numeric  # For numeric range queries
            - name: confidence
              type: numeric  # For numeric comparisons
            - name: model
              type: tag      # For exact match on model names
            - name: description
              type: text     # For full-text search

---

### Models/Spring Ai Anthropic/README (models/spring-ai-anthropic/README.md)

# Anthropic Java SDK Integration

This module integrates the official Anthropic Java SDK with Spring AI, providing access to Claude models through Anthropic's API.

[Anthropic Java SDK GitHub repository](https://github.com/anthropics/anthropic-sdk-java)

## Authentication

Configure your Anthropic API key either programmatically or via environment variable:

```java
AnthropicChatOptions options = AnthropicChatOptions.builder()
    .apiKey("<your-api-key>")
    .build();
```

Or using the environment variable (automatically detected):

```bash
export ANTHROPIC_API_KEY=<your-api-key>
```

## Features

This module supports:

- **Chat Completions** - Synchronous and streaming responses
- **Tool Calling** - Function calling with automatic tool execution
- **Streaming Tool Calling** - Tool calls in streaming mode with partial JSON accumulation
- **Multi-Modal** - Images and PDF documents
- **Extended Thinking** - Claude's thinking/reasoning feature with full streaming support
- **Citations** - Document-grounded responses with source attribution
- **Prompt Caching** - Reduce costs for repeated context with configurable strategies
- **Structured Output** - JSON schema-constrained responses with effort control
- **Per-Request HTTP Headers** - Custom headers per API call for tracking, beta features, and routing
- **Observability** - Micrometer-based metrics and tracing

### Planned Features

- **Amazon Bedrock** - Access Claude through AWS Bedrock
- **Google Vertex AI** - Access Claude through Google Cloud

## Basic Usage

```java
// Create chat model with default options
AnthropicChatModel chatModel = new AnthropicChatModel(
    AnthropicChatOptions.builder()
        .model("claude-sonnet-4-20250514")
        .maxTokens(1024)
        .build()
);

// Synchronous call
ChatResponse response = chatModel.call(new Prompt("Hello, Claude!"));

// Streaming call
Flux<ChatResponse> stream = chatModel.stream(new Prompt("Tell me a story"));
```

## Tool Calling

```java
var options = AnthropicChatOptions.builder()
    .model("claude-sonnet-4-20250514")
    .toolCallbacks(FunctionToolCallback.builder("getWeather", new WeatherService())
        .description("Get the current weather for a location")
        .inputType(WeatherRequest.class)
        .build())
    .build();

ChatResponse response = chatModel.call(new Prompt("What's the weather in Paris?", options));
```

## Extended Thinking

Enable Claude's reasoning feature to see step-by-step thinking before the final answer:

```java
var options = AnthropicChatOptions.builder()
    .model("claude-sonnet-4-20250514")
    .temperature(1.0) // required when thinking is enabled
    .maxTokens(16000)
    .thinkingEnabled(10000L) // budget must be >= 1024 and < maxTokens
    .build();

ChatResponse response = chatModel.call(new Prompt("Solve this step by step...", options));
```

Three thinking modes are available via convenience builders:
- `thinkingEnabled(budgetTokens)` - Enable with a specific token budget
- `thinkingAdaptive()` - Let Claude decide whether to think
- `thinkingDisabled()` - Explicitly disable thinking

Thinking is fully supported in both synchronous and streaming modes, including signature capture for thinking block verification.

## Citations

Anthropic's Citations API allows Claude to reference specific parts of provided documents when generating responses. Three document types are supported: plain text, PDF, and custom content blocks.

```java
// Create a citation document
AnthropicCitationDocument document = AnthropicCitationDocument.builder()
    .plainText("The Eiffel Tower was completed in 1889 in Paris, France. " +
               "It stands 330 meters tall and was designed by Gustave Eiffel.")
    .title("Eiffel Tower Facts")
    .citationsEnabled(true)
    .build();

// Call the model with the document
ChatResponse response = chatModel.call(
    new Prompt(
        "When was the Eiffel Tower built?",
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4-20250514")
            .maxTokens(1024)
            .citationDocuments(document)
            .build()
    )
);

// Access citations from response metadata
List<Citation> citations = (List<Citation>) response.getMetadata().get("citations");
for (Citation citation : citations) {
    System.out.println("Document: " + citation.getDocumentTitle());
    System.out.println("Cited text: " + citation.getCitedText());
}
```

PDF and custom content block documents are also supported via `pdfFile()`, `pdf()`, and `customContent()` builders.

## Prompt Caching

Prompt caching reduces costs and latency by caching repeated context (system prompts, tool definitions, conversation history) across API calls. Five caching strategies are available:

| Strategy | Description |
|----------|-------------|
| `NONE` | No caching (default) |
| `SYSTEM_ONLY` | Cache system message content |
| `TOOLS_ONLY` | Cache tool definitions |
| `SYSTEM_AND_TOOLS` | Cache both system messages and tool definitions |
| `CONVERSATION_HISTORY` | Cache system messages, tools, and conversation messages |

```java
// Cache system messages to reduce costs for repeated prompts
var options = AnthropicChatOptions.builder()
    .model("claude-sonnet-4-20250514")
    .maxTokens(1024)
    .cacheOptions(AnthropicCacheOptions.builder()
        .strategy(AnthropicCacheStrategy.SYSTEM_AND_TOOLS)
        .build())
    .build();

ChatResponse response = chatModel.call(
    new Prompt(List.of(
        new SystemMessage("You are an expert assistant with deep domain knowledge..."),
        new UserMessage("What is the capital of France?")),
        options));

// Access cache token usage via native SDK usage
com.anthropic.models.messages.Usage sdkUsage =
    (com.anthropic.models.messages.Usage) response.getMetadata().getUsage().getNativeUsage();
long cacheCreation = sdkUsage.cacheCreationInputTokens().orElse(0L);
long cacheRead = sdkUsage.cacheReadInputTokens().orElse(0L);
```

You can also configure TTL (5 minutes or 1 hour), minimum content length thresholds, and multi-block system caching for static vs. dynamic system message segments:

```java
var options = AnthropicCacheOptions.builder()
    .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
    .messageTypeTtl(MessageType.SYSTEM, AnthropicCacheTtl.ONE_HOUR)
    .messageTypeMinContentLength(MessageType.SYSTEM, 100)
    .multiBlockSystemCaching(true)
    .build();
```

## Structured Output

Structured output constrains Claude to produce responses conforming to a JSON schema. The SDK module also supports Anthropic's effort control for tuning response quality vs speed.

> **Model Requirement:** Structured output and effort control require `claude-sonnet-4-6` or newer. Older models like `claude-sonnet-4-20250514` do not support these features.

### JSON Schema Output

```java
var options = AnthropicChatOptions.builder()
    .model("claude-sonnet-4-6")
    .outputSchema("""
        {
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "capital": {"type": "string"},
                "population": {"type": "integer"}
            },
            "required": ["name", "capital"],
            "additionalProperties": false
        }
        """)
    .build();

ChatResponse response = chatModel.call(new Prompt("Tell me about France.", options));
// Response text will be valid JSON conforming to the schema
```

### Effort Control

Control how much compute Claude spends on its response. Lower effort means faster, cheaper responses; higher effort means more thorough reasoning.

```java
var options = AnthropicChatOptions.builder()
    .model("claude-sonnet-4-6")
    .effort(OutputConfig.Effort.LOW) // LOW, MEDIUM, HIGH, or MAX
    .build();
```

### Combined Schema + Effort

```java
var options = AnthropicChatOptions.builder()
    .model("claude-sonnet-4-6")
    .outputSchema("{\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"integer\"}},\"required\":[\"answer\"],\"additionalProperties\":false}")
    .effort(OutputConfig.Effort.HIGH)
    .build();
```

### Direct OutputConfig

For full control, use the SDK's `OutputConfig` directly:

```java
import com.anthropic.models.messages.OutputConfig;
import com.anthropic.models.messages.JsonOutputFormat;
import com.anthropic.core.JsonValue;

var outputConfig = OutputConfig.builder()
    .effort(OutputConfig.Effort.HIGH)
    .format(JsonOutputFormat.builder()
        .schema(JsonOutputFormat.Schema.builder()
            .putAdditionalProperty("type", JsonValue.from("object"))
            .putAdditionalProperty("properties", JsonValue.from(Map.of(
                "name", Map.of("type", "string"))))
            .putAdditionalProperty("additionalProperties", JsonValue.from(false))
            .build())
        .build())
    .build();

var options = AnthropicChatOptions.builder()
    .model("claude-sonnet-4-6")
    .outputConfig(outputConfig)
    .build();
```

## Per-Request HTTP Headers

Add custom HTTP headers to individual API calls. Unlike `customHeaders` (which apply to all requests at the client level), `httpHeaders` are set per request.

```java
var options = AnthropicChatOptions.builder()
    .httpHeaders(Map.of(
        "X-Request-Id", "req-12345",
        "X-Custom-Tracking", "my-value"))
    .build();

ChatResponse response = chatModel.call(new Prompt("Hello", options));
```

## Logging

Enable SDK logging by setting the environment variable:

```bash
export ANTHROPIC_LOG=debug
```

## Documentation

For comprehensive documentation, see:
- [Spring AI Anthropic Reference Documentation](https://docs.spring.io/spring-ai/reference/api/chat/anthropic-chat.html)
- [Anthropic API Documentation](https://docs.anthropic.com/)
- [Anthropic Java SDK Documentation](https://github.com/anthropics/anthropic-sdk-java)

---

### Models/Spring Ai Anthropic/Src/Test/Resources/Prompts/Conversation History Cache Prompt (models/spring-ai-anthropic/src/test/resources/prompts/conversation-history-cache-prompt.txt)

You are an experienced career counselor and professional development expert with over 15 years of experience 
helping technology professionals advance their careers in software engineering, data science, and emerging tech fields.
Your expertise spans career transitions, skill development, industry trends, and strategic career planning.

When providing career guidance, always consider these essential dimensions:
1. Current market trends and emerging technologies affecting career trajectories
2. Skills gap analysis and strategic upskilling recommendations for competitive advantage
3. Industry-specific compensation benchmarks and negotiation strategies
4. Professional networking approaches and personal brand development
5. Leadership development pathways and technical career progression options
6. Work-life balance considerations and remote work best practices
7. Interview preparation strategies and portfolio development guidance
8. Career transition planning including timing, risk mitigation, and bridge strategies
9. Performance evaluation optimization and promotion pathway planning
10. Entrepreneurial opportunities and freelancing vs full-time employment trade-offs

## Career Development Framework for Conversation History Caching

### Technical Skills Assessment and Development
Provide comprehensive technical skill evaluation:
- Current technology stack assessment with market relevance analysis
- Emerging technology identification and learning prioritization strategies
- Certification and formal education recommendations with ROI calculations
- Hands-on project suggestions to demonstrate competency and build portfolios
- Open source contribution strategies for visibility and community engagement
- Technical writing and speaking opportunities for thought leadership development
- Mentorship and reverse mentoring opportunities for skill exchange

### Career Progression Strategy Planning
Develop strategic career advancement plans:
- Individual contributor vs management track decision frameworks
- Technical leadership roles and architectural responsibility progression
- Cross-functional collaboration skills for broader organizational impact
- Product management and business strategy understanding for technical leaders
- Agile and project management methodologies for delivery excellence
- Stakeholder communication and executive presentation skills development
- International and remote work opportunities for global career expansion

### Industry and Market Analysis
Analyze technology industry trends comprehensively:
- Startup vs enterprise career path comparisons with risk-reward analysis
- Industry sector analysis including fintech, healthcare, education, and government
- Geographic market opportunities and cost of living considerations
- Remote work impact on career opportunities and compensation structures
- Freelancing and consulting market dynamics with rate optimization
- Technology adoption cycles and their impact on career longevity
- Economic factors affecting technology hiring and investment patterns

### Professional Development and Networking
Guide strategic professional relationship building:
- Conference attendance and speaking engagement strategies for visibility
- Professional association participation and leadership opportunities
- Alumni network activation and industry meetup engagement tactics
- Social media presence optimization for professional brand building
- Mentorship relationship development both as mentor and mentee
- Cross-industry networking for diverse perspective and opportunity access
- International professional relationships for global career opportunities

### Performance and Compensation Optimization
Optimize career advancement and compensation:
- Performance review preparation and goal-setting strategies for maximum impact
- Compensation negotiation tactics with market research and timing considerations
- Equity and stock option evaluation for startup and growth company positions
- Benefits package optimization including health, retirement, and professional development
- Professional development budget utilization for strategic skill building
- Side project and passive income development for financial diversification
- Career pivoting strategies with income protection and transition planning

Always provide personalized, actionable advice based on individual circumstances and career goals.
Consider market conditions, personal constraints, and long-term career sustainability.
Focus on building transferable skills and maintaining adaptability in a rapidly changing technology landscape.

This system prompt is specifically designed for testing conversation history caching strategies and contains sufficient tokens
to trigger Anthropic's prompt caching mechanism with Claude Sonnet 4 (1024+ token threshold).

---

### Models/Spring Ai Anthropic/Src/Test/Resources/Prompts/Extended Ttl Cache Prompt (models/spring-ai-anthropic/src/test/resources/prompts/extended-ttl-cache-prompt.txt)

You are a comprehensive mathematical assistant specializing in arithmetic, algebra, calculus, statistics, and advanced mathematical concepts.
Your expertise spans elementary mathematics through graduate-level topics, with particular strength in problem-solving methodologies.

When addressing mathematical problems, always consider these fundamental aspects:
1. Problem comprehension and identification of given information and unknowns
2. Selection of appropriate mathematical methods and solution strategies
3. Step-by-step solution development with clear logical progression
4. Verification of results through alternative methods or sanity checks
5. Interpretation of solutions in context with practical applications
6. Common error identification and prevention strategies
7. Conceptual understanding reinforcement through analogies and examples
8. Connections to broader mathematical principles and theorems
9. Computational accuracy and precision considerations
10. Communication of mathematical reasoning in accessible language

## Mathematical Problem-Solving Framework for Extended TTL Caching

### Arithmetic and Number Theory
Provide comprehensive arithmetic analysis:
- Basic operations with integers, fractions, and decimal number systems
- Prime factorization and greatest common divisor calculations
- Modular arithmetic applications in cryptography and computer science
- Number base conversions between binary, octal, decimal, and hexadecimal systems
- Rational and irrational number properties with proof techniques
- Complex number operations including polar and rectangular forms
- Mathematical induction proofs for number theory propositions

### Algebraic Problem Solving
Develop algebraic solution strategies:
- Linear equation systems using substitution, elimination, and matrix methods
- Quadratic equation solutions with discriminant analysis and graphical interpretation
- Polynomial factorization techniques including synthetic division and rational root theorem
- Exponential and logarithmic equation solving with change of base formulas
- Inequality solving with graphical representation and interval notation
- Function composition and inverse function determination
- Abstract algebra concepts including groups, rings, and fields

### Calculus and Analysis
Analyze calculus problems comprehensively:
- Limit evaluation using algebraic manipulation and L'Hôpital's rule
- Derivative calculations with chain rule, product rule, and quotient rule applications
- Integration techniques including substitution, parts, and partial fractions
- Applications of derivatives in optimization and related rate problems
- Definite integral applications in area, volume, and physics problems
- Series convergence analysis with ratio, root, and integral tests
- Multivariable calculus including partial derivatives and multiple integrals

### Statistical Analysis and Probability
Examine statistical methods thoroughly:
- Descriptive statistics including measures of central tendency and dispersion
- Probability distributions with normal, binomial, and Poisson applications
- Hypothesis testing with Type I and Type II error analysis
- Confidence interval construction and interpretation
- Regression analysis with correlation coefficient interpretation
- Analysis of variance (ANOVA) for comparing multiple groups
- Bayesian inference and conditional probability applications

### Applied Mathematics and Modeling
Model real-world problems mathematically:
- Linear programming with simplex method and graphical solutions
- Differential equation modeling for population growth and decay
- Game theory applications in economics and strategic decision making
- Graph theory for network analysis and optimization problems
- Numerical analysis methods for approximation and error estimation
- Operations research techniques for resource allocation and scheduling
- Financial mathematics including compound interest and annuity calculations

Always provide clear explanations with multiple solution approaches where applicable.
Include graphical representations and real-world applications to enhance understanding.
Emphasize mathematical reasoning and proof techniques to develop analytical thinking skills.

### Additional Mathematical Problem-Solving Strategies for Extended TTL Testing

#### Advanced Topics and Specialized Areas
Explore comprehensive mathematical domains:
- Abstract Algebra: Group theory, ring theory, field theory applications
- Real Analysis: Measure theory, functional analysis, topology concepts
- Complex Analysis: Analytic functions, contour integration, residue theory
- Discrete Mathematics: Graph theory, combinatorics, number theory applications
- Linear Algebra: Matrix decompositions, eigenvalue problems, vector spaces
- Differential Geometry: Manifolds, curvature, tensor calculus applications
- Optimization Theory: Linear programming, nonlinear optimization, convex analysis
- Probability Theory: Stochastic processes, measure-theoretic probability, limit theorems
- Mathematical Logic: Set theory, model theory, proof theory foundations

#### Computational Mathematics and Numerical Methods
Address computational aspects thoroughly:
- Numerical Linear Algebra: LU decomposition, QR factorization, singular value decomposition
- Numerical Integration: Gaussian quadrature, adaptive quadrature methods, Monte Carlo integration
- Ordinary Differential Equations: Runge-Kutta methods, multistep methods, boundary value problems
- Partial Differential Equations: Finite difference methods, finite element analysis, spectral methods
- Interpolation and Approximation: Spline interpolation, Chebyshev polynomials, least squares approximation
- Root Finding: Newton-Raphson method, bisection method, secant method applications
- Optimization Algorithms: Gradient descent, Newton's method, simplex algorithm implementations

#### Mathematical Modeling and Real-World Applications
Connect theory to practical implementations:
- Engineering Mathematics: Fourier analysis, Laplace transforms, control theory applications
- Mathematical Biology: Population dynamics, epidemic modeling, biochemical reaction networks
- Mathematical Physics: Quantum mechanics, relativity theory, statistical mechanics principles
- Mathematical Economics: Game theory, optimization in economics, financial mathematics modeling
- Actuarial Mathematics: Life insurance, annuities, pension fund calculations, risk assessment
- Cryptography: Number theory applications, elliptic curve cryptography, hash functions
- Signal Processing: Digital signal processing, wavelets, time-frequency analysis techniques

This system prompt is specifically designed for testing extended TTL caching strategies and contains sufficient tokens
to trigger Anthropic's prompt caching mechanism with Claude Sonnet 4 (1024+ token threshold). The expanded content
ensures we exceed the minimum token requirement significantly to guarantee cache creation rather than relying on
borderline token counts that might fail cache threshold requirements.

---

### Models/Spring Ai Anthropic/Src/Test/Resources/Prompts/System And Tools Cache Prompt (models/spring-ai-anthropic/src/test/resources/prompts/system-and-tools-cache-prompt.txt)

You are a comprehensive weather analysis assistant specializing in meteorological data interpretation and outdoor activity recommendations.
Your expertise encompasses understanding complex weather patterns, atmospheric conditions, and their impact on various outdoor activities.

When analyzing weather data, always consider these critical factors:
1. Temperature variations throughout the day and their impact on comfort levels
2. Precipitation probability, intensity, and duration affecting outdoor plans
3. Wind speed and direction influencing perceived temperature and activity safety
4. Humidity levels affecting comfort and heat index calculations
5. UV index and sun exposure recommendations for health and safety
6. Atmospheric pressure changes indicating weather pattern shifts
7. Visibility conditions for driving and outdoor navigation
8. Air quality indices for respiratory health considerations
9. Seasonal patterns and historical weather trends for context
10. Local microclimate effects in urban vs rural environments

## Weather Analysis Framework for System and Tools Caching

### Temperature Analysis
Provide detailed temperature assessments:
- Current temperature readings with heat index or wind chill calculations
- Daily temperature ranges including minimum and maximum predictions
- Comfort zone analysis for different age groups and activity levels
- Thermal comfort indices considering humidity, wind, and solar radiation
- Clothing recommendations based on effective temperature measurements
- Risk assessments for heat-related illnesses or cold exposure
- Optimal timing recommendations for temperature-sensitive activities

### Precipitation Assessment
Analyze precipitation patterns comprehensively:
- Current precipitation type, intensity, and accumulation rates
- Probability forecasts with confidence intervals and timing predictions
- Impact assessments on outdoor activities, transportation, and infrastructure
- Flood risk evaluations for low-lying areas and drainage systems
- Snow and ice formation potential with safety implications
- Seasonal precipitation trends and drought or flood pattern analysis
- Agricultural and ecological impacts of current and forecast precipitation

### Wind Conditions Evaluation
Assess wind impacts thoroughly:
- Current wind speed, direction, and gust measurements
- Wind chill calculations and perceived temperature effects
- Safety considerations for high-wind activities and structural concerns
- Maritime and aviation wind impact assessments
- Dust and pollen dispersion patterns affected by wind conditions
- Energy generation potential for wind-powered systems
- Fire weather conditions and wildfire risk assessments

### Atmospheric Monitoring
Monitor comprehensive atmospheric conditions:
- Barometric pressure trends indicating weather system movements
- Humidity levels with comfort and health impact assessments
- Air quality measurements including particulate matter and pollutants
- UV radiation levels with skin protection recommendations
- Visibility assessments for transportation and outdoor activities
- Lightning detection and severe weather warning systems
- Climate change indicators and long-term trend analysis

### Activity Recommendations
Provide specific outdoor activity guidance:
- Walking, hiking, and running condition assessments with safety protocols
- Sports and recreational activity suitability ratings
- Gardening and agricultural work timing recommendations
- Construction and outdoor work safety guidelines
- Travel and transportation condition evaluations
- Photography and outdoor event planning considerations
- Emergency preparedness and severe weather response protocols

### Severe Weather Protocols
Apply rigorous severe weather analysis procedures:
- Thunderstorm development tracking with lightning frequency and storm cell motion
- Tornado watch and warning interpretation with shelter-in-place guidance
- Hurricane and tropical storm trajectory analysis with evacuation timing windows
- Flash flood potential based on rainfall rates, soil saturation, and terrain
- Winter storm classification covering snowfall accumulation, ice loading, and blizzard criteria
- Heat wave and cold snap duration forecasting with public health advisory thresholds
- Coastal storm surge estimation and tidal interaction effects on low-lying areas

### Data Quality and Confidence
Communicate forecast reliability transparently:
- Distinguish observed measurements from model-derived predictions
- Report confidence intervals and forecast uncertainty for each variable
- Note model disagreement between major numerical weather prediction systems
- Flag data gaps from sensor outages or sparse observation networks
- Explain how forecast skill degrades with lead time for each parameter
- Reconcile conflicting indicators rather than averaging them uncritically
- Provide ranges rather than single point estimates when uncertainty is high

### Regional and Seasonal Context
Ground every assessment in local context:
- Adjust thresholds for regional climate norms and acclimatization
- Account for elevation, proximity to large bodies of water, and urban heat islands
- Incorporate seasonal baselines so anomalies are interpreted correctly
- Reference historical analogs for comparable weather setups
- Consider prevailing wind regimes and orographic effects on precipitation
- Factor in diurnal patterns specific to the location and time of year

### Communication and Response Structure
Structure every response for clarity and usefulness:
- Lead with the single most decision-relevant takeaway for the user's question
- Follow with supporting detail organized from highest to lowest impact
- Use concrete numbers with units rather than vague qualitative descriptions
- Separate what is known now from what is forecast and how far out
- Call out any safety-critical condition explicitly and early in the response
- Offer a clear recommended action, not just a description of conditions
- Close with the most relevant caveat or condition that would change the advice

### Outdoor Activity Risk Tiers
Classify recommendations into consistent risk tiers:
- Favorable conditions where the activity can proceed without special precautions
- Marginal conditions requiring specific mitigations such as timing or equipment
- Hazardous conditions where the activity should be postponed or relocated
- Dangerous conditions where outdoor exposure itself is the primary risk
- For each tier, name the dominant limiting factor driving the classification
- Re-evaluate the tier whenever a key variable crosses a documented threshold

Always provide specific, actionable recommendations with safety considerations paramount.
Include quantitative data where available and explain the reasoning behind recommendations.
Consider vulnerable populations including children, elderly, and individuals with health conditions.

This system prompt is specifically designed for testing system and tools caching strategies and contains sufficient tokens
to trigger Anthropic's prompt caching mechanism with current Claude Sonnet models (1024+ token threshold).

---

### Models/Spring Ai Anthropic/Src/Test/Resources/Prompts/System Only Cache Prompt (models/spring-ai-anthropic/src/test/resources/prompts/system-only-cache-prompt.txt)

You are an expert software architect specializing in distributed systems and cloud-native applications.
Your responses should be detailed, technically accurate, and include comprehensive best practices
for scalability, reliability, maintainability, and cost-effectiveness in modern software systems.

When discussing architecture patterns, always consider these critical aspects:
1. Scalability implications and potential bottlenecks across multiple dimensions including compute, storage, network, and database resources
2. Fault tolerance and error handling strategies including circuit breakers, bulkheads, timeouts, retries, and graceful degradation
3. Data consistency and transaction management including eventual consistency patterns, saga patterns, and distributed transaction challenges
4. Security considerations and access patterns including authentication, authorization, encryption at rest and in transit, and zero-trust principles
5. Monitoring and observability requirements including distributed tracing, structured logging, metrics collection, and alerting strategies
6. Performance optimization opportunities including caching strategies, CDN usage, database indexing, and query optimization
7. Cost optimization strategies including resource rightsizing, reserved capacity planning, and multi-cloud cost management
8. Team structure and Conway's Law implications including microservice boundaries, team autonomy, and communication patterns
9. DevOps and deployment strategies including CI/CD pipelines, infrastructure as code, and automated testing approaches
10. Compliance and governance requirements including data privacy regulations, audit trails, and regulatory compliance frameworks

## Detailed Architecture Guidelines for System-Only Caching

### Microservices Design Patterns
When designing microservices, implement these essential patterns:
- API Gateway pattern for centralized request routing and cross-cutting concerns
- Service mesh for inter-service communication, security, and observability
- Event sourcing for maintaining audit trails and enabling event-driven architectures
- CQRS (Command Query Responsibility Segregation) for optimal read/write performance
- Bulkhead pattern to isolate critical resources and prevent cascade failures
- Circuit breaker pattern with exponential backoff for external service resilience
- Saga pattern for distributed transaction management across service boundaries

### Data Management Strategies
Implement robust data management approaches:
- Database per service pattern to ensure data encapsulation and service autonomy
- Event-driven data synchronization using message queues and event streams
- Polyglot persistence choosing optimal data stores for specific use cases
- Read replicas and sharding strategies for horizontal scaling
- Data versioning and schema evolution strategies for backward compatibility
- Distributed caching with Redis or similar for improved performance
- Data governance frameworks ensuring data quality, lineage, and compliance

### Security Best Practices
Implement defense-in-depth security measures:
- OAuth 2.0 and OpenID Connect for authentication and authorization
- JWT tokens with proper expiration and refresh token mechanisms
- API rate limiting and throttling to prevent abuse and DDoS attacks
- Encryption at rest using AES-256 and encryption in transit with TLS 1.3
- Secret management using HashiCorp Vault or AWS Secrets Manager
- Network segmentation with VPCs, subnets, and security groups
- Regular security audits, vulnerability scanning, and penetration testing

### Monitoring and Observability
Establish comprehensive observability:
- Distributed tracing with OpenTelemetry or Jaeger for request flow analysis
- Centralized logging with ELK stack or similar for log aggregation and analysis
- Application metrics using Prometheus and Grafana for monitoring and alerting
- Health checks and readiness probes for service availability monitoring
- SLA/SLO definitions with error budgets for reliability measurements
- Alert management with PagerDuty or similar for incident response
- Performance monitoring with APM tools like New Relic or AppDynamics

### Infrastructure and DevOps
Implement modern infrastructure practices:
- Infrastructure as Code using Terraform, CloudFormation, or Pulumi
- Container orchestration with Kubernetes for scalable deployments
- GitOps workflows with ArgoCD or Flux for automated deployments
- Blue-green or canary deployment strategies for zero-downtime releases
- Automated testing pipelines including unit, integration, and end-to-end tests
- Code quality gates with SonarQube and static analysis tools
- Disaster recovery planning with backup strategies and failover procedures

Always provide concrete examples, architectural diagrams when helpful, code snippets in relevant programming languages,
and real-world case studies from companies like Netflix, Amazon, Google, Microsoft, and other technology leaders.
Consider both the technical and business implications of architectural decisions, including time-to-market,
development velocity, operational overhead, and long-term maintainability costs.

This system prompt is specifically designed for testing system-only caching strategies and contains sufficient tokens
to trigger Anthropic's prompt caching mechanism with Claude Sonnet 4 (1024+ token threshold).

---

### Models/Spring Ai Bedrock/README (models/spring-ai-bedrock/README.md)

[Amazon Bedrock Overview](https://docs.spring.io/spring-ai/reference/api/bedrock-chat.html)

- [Anthropic3 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-anthropic3.html)
- [Anthropic2 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-anthropic.html)
- [Cohere Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-cohere.html)
- [Cohere Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/bedrock-cohere-embedding.html)
- [Llama Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-llama.html)
- [Titan Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-titan.html)
- [Titan Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/bedrock-titan-embedding.html)
- [Jurassic2 Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/bedrock/bedrock-jurassic2.html)

---

### Models/Spring Ai Deepseek/README (models/spring-ai-deepseek/README.md)

[DeepSeek Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/deepseek-chat.html)

---

### Models/Spring Ai Elevenlabs/README (models/spring-ai-elevenlabs/README.md)

# Spring AI - ElevenLabs Text-to-Speech

[ElevenLabs Text-to-Speech Documentation](https://docs.spring.io/spring-ai/reference/api/audio/speech/elevenlabs-speech.html)

---

### Models/Spring Ai Elevenlabs/Src/Test/Resources/Voices.Json (models/spring-ai-elevenlabs/src/test/resources/voices.json)

{
  "voices": [
    {
      "voice_id": "9BWtsMINqrJLrRacOk9x",
      "name": "Aria",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_multilingual_v2": "fine_tuned",
          "eleven_turbo_v2_5": "fine_tuned",
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_flash_v2": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "expressive",
        "age": "middle-aged",
        "gender": "female",
        "use_case": "social media"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/9BWtsMINqrJLrRacOk9x/405766b8-1f4e-4d3c-aba1-6f25333823ec.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "CwhRBWXzGAHq8TQ4Fs17",
      "name": "Roger",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_multilingual_v2": "fine_tuned",
          "eleven_turbo_v2_5": "failed",
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_flash_v2": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "confident",
        "age": "middle-aged",
        "gender": "male",
        "use_case": "social media"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/CwhRBWXzGAHq8TQ4Fs17/58ee3ff5-f6f2-4628-93b8-e38eb31806b0.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "EXAVITQu4vr4xnSDxMaL",
      "name": "Sarah",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {},
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {},
        "message": {},
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "american",
        "description": "soft",
        "age": "young",
        "gender": "female",
        "use_case": "news"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/EXAVITQu4vr4xnSDxMaL/01a3e33c-6e99-4ee7-8543-ff2216a32186.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_turbo_v2",
        "eleven_multilingual_v2",
        "eleven_turbo_v2_5"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "FGY2WhTYpPnrIDTdsKH5",
      "name": "Laura",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_multilingual_v2": "fine_tuned",
          "eleven_turbo_v2_5": "fine_tuned",
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_flash_v2": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "upbeat",
        "age": "young",
        "gender": "female",
        "use_case": "social media"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/FGY2WhTYpPnrIDTdsKH5/67341759-ad08-41a5-be6e-de12fe448618.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "IKne3meq5aSn9XLyUdCD",
      "name": "Charlie",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "Australian",
        "description": "natural",
        "age": "middle aged",
        "gender": "male",
        "use_case": "conversational"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/IKne3meq5aSn9XLyUdCD/102de6f2-22ed-43e0-a1f1-111fa75c5481.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_multilingual_v1",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "JBFqnCBsd6RMkjVDRZzb",
      "name": "George",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_turbo_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_v2_flash": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_turbo_v2": "",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "British",
        "description": "warm",
        "age": "middle aged",
        "gender": "male",
        "use_case": "narration"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/JBFqnCBsd6RMkjVDRZzb/e6206d1a-0721-4787-aafb-06a6e705cac5.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "N2lVS1w4EtoT3dr4eOWO",
      "name": "Callum",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "Transatlantic",
        "description": "intense",
        "age": "middle-aged",
        "gender": "male",
        "use_case": "characters"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/N2lVS1w4EtoT3dr4eOWO/ac833bd8-ffda-4938-9ebc-b0f99ca25481.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_multilingual_v1",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "SAz9YHcvj6GT2YYXdXww",
      "name": "River",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_multilingual_v2": "fine_tuned",
          "eleven_turbo_v2_5": "fine_tuned",
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned",
          "eleven_multilingual_sts_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_flash_v2": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "confident",
        "age": "middle-aged",
        "gender": "non-binary",
        "use_case": "social media"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/SAz9YHcvj6GT2YYXdXww/e6c95f0b-2227-491a-b3d7-2249240decb7.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_sts_v2",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "TX3LPaxmHKxFdv7VOQHJ",
      "name": "Liam",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_turbo_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_v2_flash": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_turbo_v2": "",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "articulate",
        "age": "young",
        "gender": "male",
        "use_case": "narration"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/TX3LPaxmHKxFdv7VOQHJ/63148076-6363-42db-aea8-31424308b92c.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_multilingual_v1",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "XB0fDUnXU5powFXDhCwa",
      "name": "Charlotte",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_multilingual_v2": "",
          "eleven_turbo_v2_5": "",
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "Swedish",
        "description": "seductive",
        "age": "young",
        "gender": "female",
        "use_case": "characters"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/XB0fDUnXU5powFXDhCwa/942356dc-f10d-4d89-bda5-4f8505ee038b.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_multilingual_v1",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "Xb7hH8MSUJpSbSDYk0k2",
      "name": "Alice",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "British",
        "description": "confident",
        "age": "middle-aged",
        "gender": "female",
        "use_case": "news"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/Xb7hH8MSUJpSbSDYk0k2/d10f7534-11f6-41fe-a012-2de1e482d336.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "XrExE9yKIg1WjnnlVkGX",
      "name": "Matilda",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_turbo_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_v2_flash": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_turbo_v2": "",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "friendly",
        "age": "middle-aged",
        "gender": "female",
        "use_case": "narration"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/XrExE9yKIg1WjnnlVkGX/b930e18d-6b4d-466e-bab2-0ae97c6d8535.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_multilingual_v1",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "bIHbv24MWmeRgasZH58o",
      "name": "Will",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_multilingual_v2": "fine_tuned",
          "eleven_turbo_v2_5": "fine_tuned",
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_flash_v2": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "friendly",
        "age": "young",
        "gender": "male",
        "use_case": "social media"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/bIHbv24MWmeRgasZH58o/8caf8f3d-ad29-4980-af41-53f20c72d7a4.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "cgSgspJ2msm6clMCkdW9",
      "name": "Jessica",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_multilingual_v2": "fine_tuned",
          "eleven_turbo_v2_5": "fine_tuned",
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_flash_v2": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "expressive",
        "age": "young",
        "gender": "female",
        "use_case": "conversational"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/cgSgspJ2msm6clMCkdW9/56a97bf8-b69b-448f-846c-c3a11683d45a.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "cjVigY5qzO86Huf0OWal",
      "name": "Eric",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_multilingual_v2": "fine_tuned",
          "eleven_turbo_v2_5": "fine_tuned",
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_flash_v2": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "friendly",
        "age": "middle-aged",
        "gender": "male",
        "use_case": "conversational"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/cjVigY5qzO86Huf0OWal/d098fda0-6456-4030-b3d8-63aa048c9070.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "iP95p4xoKVk53GoZ742B",
      "name": "Chris",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "casual",
        "age": "middle-aged",
        "gender": "male",
        "use_case": "conversational"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/iP95p4xoKVk53GoZ742B/3f4bde72-cc48-40dd-829f-57fbf906f4d7.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "nPczCjzI2devNBz1zQrb",
      "name": "Brian",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "deep",
        "age": "middle-aged",
        "gender": "male",
        "use_case": "narration"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/nPczCjzI2devNBz1zQrb/2dd3e72c-4fd3-42f1-93ea-abc5d4e5aa1d.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "onwK4e9ZLuTAKqWW03F9",
      "name": "Daniel",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "British",
        "description": "authoritative",
        "age": "middle-aged",
        "gender": "male",
        "use_case": "news"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/onwK4e9ZLuTAKqWW03F9/7eee0236-1a72-4b86-b303-5dcadc007ba9.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_multilingual_v1",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "pFZP5JQG7iQjIQuC4Bku",
      "name": "Lily",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "British",
        "description": "warm",
        "age": "middle-aged",
        "gender": "female",
        "use_case": "narration"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/pFZP5JQG7iQjIQuC4Bku/89b68b35-b3dd-4348-a84a-a3c13a3c2b30.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    },
    {
      "voice_id": "pqHfZKP75CvOlQylNhV4",
      "name": "Bill",
      "samples": null,
      "category": "premade",
      "fine_tuning": {
        "is_allowed_to_fine_tune": true,
        "state": {
          "eleven_flash_v2_5": "fine_tuned",
          "eleven_turbo_v2": "fine_tuned",
          "eleven_flash_v2": "fine_tuned",
          "eleven_v2_flash": "fine_tuned",
          "eleven_v2_5_flash": "fine_tuned"
        },
        "verification_failures": [],
        "verification_attempts_count": 0,
        "manual_verification_requested": false,
        "language": "en",
        "progress": {
          "eleven_flash_v2_5": 1,
          "eleven_v2_flash": 1,
          "eleven_flash_v2": 1,
          "eleven_v2_5_flash": 1
        },
        "message": {
          "eleven_flash_v2_5": "Done!",
          "eleven_turbo_v2": "",
          "eleven_flash_v2": "Done!",
          "eleven_v2_flash": "Done!",
          "eleven_v2_5_flash": "Done!"
        },
        "dataset_duration_seconds": null,
        "verification_attempts": null,
        "slice_ids": null,
        "manual_verification": null,
        "max_verification_attempts": 5,
        "next_max_verification_attempts_reset_unix_ms": 1700000000000
      },
      "labels": {
        "accent": "American",
        "description": "trustworthy",
        "age": "old",
        "gender": "male",
        "use_case": "narration"
      },
      "description": null,
      "preview_url": "https://storage.googleapis.com/eleven-public-prod/premade/voices/pqHfZKP75CvOlQylNhV4/d782b3ff-84ba-4029-848c-acf01285524d.mp3",
      "available_for_tiers": [],
      "settings": null,
      "sharing": null,
      "high_quality_base_model_ids": [
        "eleven_v2_flash",
        "eleven_flash_v2",
        "eleven_turbo_v2_5",
        "eleven_multilingual_v2",
        "eleven_v2_5_flash",
        "eleven_flash_v2_5",
        "eleven_turbo_v2"
      ],
      "verified_languages": [],
      "safety_control": null,
      "voice_verification": {
        "requires_verification": false,
        "is_verified": false,
        "verification_failures": [],
        "verification_attempts_count": 0,
        "language": null,
        "verification_attempts": null
      },
      "permission_on_resource": null,
      "is_owner": false,
      "is_legacy": false,
      "is_mixed": false,
      "created_at_unix": null
    }
  ]
}

---

### Models/Spring Ai Google Genai/README (models/spring-ai-google-genai/README.md)

[Google GenAI Chat](https://docs.spring.io/spring-ai/reference/api/chat/google-genai-chat.html)

### Starter
```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-google-genai</artifactId>
</dependency>
```

### Manual config
```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-google-genai</artifactId>
</dependency>
```

### Environment variables
```shell
export GOOGLE_GENAI_USE_VERTEXAI=true
export GOOGLE_CLOUD_PROJECT='your-project-id'
export GOOGLE_CLOUD_LOCATION='your-region'
```

## Extended Usage Metadata

The Google GenAI module provides comprehensive usage metadata tracking through the `GoogleGenAiUsage` class, which extends the standard `Usage` interface with additional token tracking capabilities specific to Google GenAI models.

### Features

#### Thinking Tokens
Track reasoning tokens for thinking-enabled models like Gemini 2.0 Flash Thinking:
```java
ChatResponse response = chatModel.call(prompt);
GoogleGenAiUsage usage = (GoogleGenAiUsage) response.getMetadata().getUsage();
Integer thoughtsTokens = usage.getThoughtsTokenCount(); // Reasoning tokens
```

#### Cached Content Tokens
Monitor tokens from cached context to optimize API costs:
```java
Integer cachedTokens = usage.getCachedContentTokenCount(); // Cached context tokens
```

#### Tool-Use Tokens
Track tokens consumed by function calling and tool use:
```java
Integer toolUseTokens = usage.getToolUsePromptTokenCount(); // Tool-use tokens
```

#### Modality Breakdowns
Get detailed token counts by modality (text, image, audio, video):
```java
List<GoogleGenAiModalityTokenCount> promptDetails = usage.getPromptTokensDetails();
for (GoogleGenAiModalityTokenCount detail : promptDetails) {
    System.out.println(detail.getModality() + ": " + detail.getTokenCount());
}
```

#### Traffic Type
Identify whether requests use Pay-As-You-Go or Provisioned Throughput:
```java
GoogleGenAiTrafficType trafficType = usage.getTrafficType();
// Returns: ON_DEMAND, PROVISIONED_THROUGHPUT, or UNKNOWN
```

### Configuration

Control whether to include extended metadata (enabled by default):
```java
GoogleGenAiChatOptions options = GoogleGenAiChatOptions.builder()
    .model("gemini-2.0-flash")
    .includeExtendedUsageMetadata(true) // Enable extended metadata
    .build();
```

### Complete Example

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Backward Compatibility

The extended usage metadata maintains full backward compatibility with the standard `Usage` interface. Code using the basic interface continues to work without modification:

```java
// Works with any Spring AI model
Usage usage = response.getMetadata().getUsage();
Long promptTokens = usage.getPromptTokens();
Long completionTokens = usage.getCompletionTokens();
```

---

### Models/Spring Ai Google Genai Embedding/README (models/spring-ai-google-genai-embedding/README.md)

# Google GenAI Embeddings Module

[Google GenAI Text Embeddings Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/google-genai-embeddings-text.html)

## Overview

The Google GenAI Embeddings module provides text embedding generation using Google's embedding models through either the Gemini Developer API or Vertex AI.

## Current Support

Please note that at this time the *spring-ai-google-genai-embedding* module supports **text embeddings only**.

This is due to the fact that the Google GenAI SDK currently supports text embeddings only, with multimodal embeddings support pending.

## Starter Dependency

```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-google-genai-embedding</artifactId>
</dependency>
```

## Manual Configuration

```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-google-genai-embedding</artifactId>
</dependency>
```

## Authentication Modes

The module supports two authentication modes:
- **Gemini Developer API**: Use an API key for quick prototyping
- **Vertex AI**: Use Google Cloud credentials for production deployments

See the [documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/google-genai-embeddings-text.html) for detailed configuration instructions.

---

### Models/Spring Ai Mistral Ai/README (models/spring-ai-mistral-ai/README.md)

[Mistral AI Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/mistralai-chat.html)

[Mistral AI Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/mistralai-embeddings.html)

---

### Models/Spring Ai Mistral Ai/Src/Test/Resources/References.Json (models/spring-ai-mistral-ai/src/test/resources/references.json)

{
  "0": {
    "url": "https://en.wikipedia.org/wiki/2024_Nobel_Peace_Prize",
    "title": "2024 Nobel Peace Prize",
    "snippets": [
      [
        "The 2024 Nobel Peace Prize, an international peace prize established according to Alfred Nobel's will, was awarded to Nihon Hidankyo (the Japan Confederation of A- and H-Bomb Sufferers Organizations), for their activism against nuclear weapons, assisted by victim/survivors (known as Hibakusha) of the atomic bombings of Hiroshima and Nagasaki in 1945.",
        "They will receive the prize at a ceremony on 10 December 2024 at Oslo, Norway."
      ]
    ],
    "description": null,
    "date": "2024-11-26T17:39:55.057454",
    "source": "wikipedia"
  },
  "1": {
    "url": "https://en.wikipedia.org/wiki/Climate_Change",
    "title": "Climate Change",
    "snippets": [
      [
        "Present-day climate change includes both global warming—the ongoing increase in global average temperature—and its wider effects on Earth’s climate system. Climate change in a broader sense also includes previous long-term changes to Earth's climate. The current rise in global temperatures is driven by human activities, especially fossil fuel burning since the Industrial Revolution. Fossil fuel use, deforestation, and some agricultural and industrial practices release greenhouse gases. These gases absorb some of the heat that the Earth radiates after it warms from sunlight, warming the lower atmosphere. Carbon dioxide, the primary gas driving global warming, has increased in concentration by about 50% since the pre-industrial era to levels not seen for millions of years."
      ]
    ],
    "description": null,
    "date": "2024-11-26T17:39:55.057454",
    "source": "wikipedia"
  },
  "2": {
    "url": "https://en.wikipedia.org/wiki/Artificial_Intelligence",
    "title": "Artificial Intelligence",
    "snippets": [
      [
        "Artificial intelligence (AI) refers to the capability of computational systems to perform tasks typically associated with human intelligence, such as learning, reasoning, problem-solving, perception, and decision-making. It is a field of research in computer science that develops and studies methods and software that enable machines to perceive their environment and use learning and intelligence to take actions that maximize their chances of achieving defined goals. Such machines may be called AIs."
      ]
    ],
    "description": null,
    "date": "2024-11-26T17:39:55.057454",
    "source": "wikipedia"
  }
}

---

### Models/Spring Ai Mistral Ai/Src/Test/Resources/Contents/Content Chunks.Json (models/spring-ai-mistral-ai/src/test/resources/contents/content_chunks.json)

[
  {
    "type": "image_url",
    "image_url": {
      "url": "https://example.com/image.png",
      "detail": "auto"
    }
  },
  {
    "type": "reference",
    "reference_ids": [
      1,
      2,
      3
    ]
  },
  {
    "type": "text",
    "text": "content text"
  },
  {
    "type": "thinking",
    "thinking": [
      {
        "type": "reference",
        "reference_ids": [
          4,
          5,
          6
        ]
      },
      {
        "type": "text",
        "text": "thinking text"
      }
    ],
    "closed": true
  }
]

---

### Models/Spring Ai Mistral Ai/Src/Test/Resources/Messages/Content Chunks Message.Json (models/spring-ai-mistral-ai/src/test/resources/messages/content_chunks_message.json)

{
  "role": "user",
  "content": [
    {
      "type": "image_url",
      "image_url": {
        "url": "https://example.com/image.png",
        "detail": "auto"
      }
    },
    {
      "type": "reference",
      "reference_ids": [
        1,
        2,
        3
      ]
    },
    {
      "type": "text",
      "text": "content text"
    },
    {
      "type": "thinking",
      "thinking": [
        {
          "type": "reference",
          "reference_ids": [
            4,
            5,
            6
          ]
        },
        {
          "type": "text",
          "text": "thinking text"
        }
      ],
      "closed": true
    }
  ]
}

---

### Models/Spring Ai Ollama/README (models/spring-ai-ollama/README.md)

[Ollama Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/ollama-chat.html)

[Ollama Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/ollama-embeddings.html)

---

### Models/Spring Ai Ollama/Src/Test/Resources/Country Json Schema.Json (models/spring-ai-ollama/src/test/resources/country-json-schema.json)

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "capital": {
      "type": "string"
    },
    "languages": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": [
    "name",
    "capital",
    "languages"
  ]
}

---

### Models/Spring Ai Openai/README (models/spring-ai-openai/README.md)

[OpenAI Chat Documentation](https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html)

[OpenAI Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/openai-embeddings.html)

[OpenAI Image Generation](https://docs.spring.io/spring-ai/reference/api/image/openai-image.html)

[OpenAI Transcription Generation](https://docs.spring.io/spring-ai/reference/api/audio/transcriptions/openai-transcriptions.html)

[OpenAI Text-to-Speech (TTS)](https://docs.spring.io/spring-ai/reference/api/audio/speech/openai-speech.html)

---

### Models/Spring Ai Openai/Src/Test/Resources/Text Source (models/spring-ai-openai/src/test/resources/text_source.txt)

Spring                 Framework                               Documentation


                                                                                                                        Version    6.0.0

            Chapter                1.    Spring              Framework                         Overview


            Spring makes it easy to create Java enterprise applications. It provides everything you need to
            embrace    the  Java   language    in  an  enterprise    environment,      with   support   for  Groovy    and   Kotlin   as
            alternative languages on the JVM, and with the flexibility to create many kinds of architectures
            depending     on  an  application’s    needs.  As  of  Spring   Framework      5.1, Spring   requires    JDK  8+  (Java  SE
            8+) and provides out-of-the-box support for JDK 11 LTS. Java SE 8 update 60 is suggested as the
            minimum      patch  release   for Java  8, but  it is  generally  recommended       to  use a  recent  patch   release.

            Spring  supports    a wide   range   of application    scenarios.   In  a large  enterprise,   applications    often  exist
            for a  long  time   and   have   to run   on  a  JDK  and   application    server   whose    upgrade     cycle  is beyond
            developer    control.   Others   may    run  as  a single   jar with   the  server   embedded,      possibly   in  a cloud
            environment.      Yet others   may    be standalone     applications    (such   as  batch   or integration    workloads)
            that do  not  need   a server.


            Spring  is open   source.   It  has  a large  and active  community      that  provides   continuous     feedback    based
            on a  diverse   range  of  real-world   use  cases.  This  has  helped    Spring  to  successfully   evolve   over  a  very
            long  time.

            1.1.    What          We      Mean          by    "Spring"


            The  term   "Spring"   means    different   things  in  different   contexts.  It can  be  used   to refer  to the  Spring
            Framework      project   itself,  which  is where    it  all  started.  Over time,  other  Spring   projects   have   been
            built on  top  of  the Spring    Framework.      Most   often,  when    people   say  "Spring",   they  mean    the  entire
            family  of  projects.  This  reference    documentation       focuses   on  the foundation:     the  Spring   Framework
            itself.


            The  Spring   Framework      is divided   into  modules.    Applications     can  choose   which    modules    they  need.
            At the heart are the modules of the core container, including a configuration model and a
            dependency injection mechanism. Beyond that, the Spring Framework provides foundational
            support    for   different    application     architectures,     including    messaging,      transactional     data   and
            persistence, and web. It also includes the Servlet-based Spring MVC web framework and, in
            parallel, the  Spring   WebFlux     reactive   web   framework.


            A note about modules: Spring’s framework jars allow for deployment to JDK 9’s module path
            ("Jigsaw"). For use in Jigsaw-enabled applications, the Spring Framework 5 jars come with
            "Automatic-Module-Name" manifest entries which define stable language-level module names
            ("spring.core",   "spring.context",     etc.) independent     from    jar artifact  names    (the  jars follow   the  same
            naming    pattern   with   "-" instead   of  ".",  e.g.  "spring-core"  and   "spring-context").    Of  course,   Spring’s
            framework     jars  keep  working    fine  on  the  classpath   on  both  JDK  8  and  9+.

            1.2.    History            of   Spring          and       the      Spring          Framework


            Spring came into being in 2003 as a response to the complexity of the early J2EE specifications.
            While   some    consider   Java   EE  and   its modern-day      successor    Jakarta   EE  to  be  in  competition     with
            Spring, they are in fact complementary. The Spring programming model does not embrace the
            Jakarta    EE   platform      specification;    rather,    it  integrates     with    carefully    selected    individual

            specifications   from   the  traditional   EE  umbrella:


              • Servlet  API   (JSR 340)

              • WebSocket     API  (JSR  356)

              • Concurrency      Utilities (JSR  236)

              • JSON   Binding    API  (JSR 367)

              • Bean   Validation   (JSR  303)

              • JPA  (JSR  338)

              • JMS   (JSR 914)

              • as well  as  JTA/JCA   setups  for  transaction    coordination,    if necessary.


            The  Spring   Framework      also  supports    the Dependency       Injection   (JSR 330)  and   Common      Annotations
            (JSR 250) specifications, which application developers may choose to use instead of the Spring-
            specific  mechanisms      provided     by the  Spring   Framework.       Originally,  those   were   based   on  common
            javax  packages.

            As  of Spring   Framework       6.0, Spring   has  been   upgraded     to  the Jakarta   EE   9 level  (e.g. Servlet   5.0+,
            JPA  3.0+), based    on  the  jakarta   namespace      instead   of the  traditional   javax   packages.    With   EE  9  as
            the  minimum      and   EE  10  supported     already,   Spring   is prepared     to provide    out-of-the-box     support
            for the further evolution of the Jakarta EE APIs. Spring Framework 6.0 is fully compatible with
            Tomcat   10.1,  Jetty 11  and  Undertow     2.3  as web   servers,   and  also  with  Hibernate    ORM    6.1.


            Over   time,  the role  of  Java/Jakarta    EE  in application    development      has  evolved.    In the  early  days   of
            J2EE  and   Spring,  applications    were   created   to  be deployed     to an  application    server.  Today,   with  the
            help  of Spring   Boot,   applications    are  created   in a  devops-   and   cloud-friendly     way,  with   the  Servlet
            container   embedded      and   trivial  to change.   As  of  Spring   Framework      5, a  WebFlux     application    does
            not  even   use  the  Servlet   API  directly   and   can  run   on  servers   (such   as  Netty)  that  are  not   Servlet
            containers.


            Spring  continues    to  innovate   and   to evolve.  Beyond     the Spring   Framework,      there  are  other   projects,
            such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch, among others. It’s
            important to remember that each project has its own source code repository, issue tracker, and
            release  cadence.    See  spring.io/projects    for the  complete    list of Spring   projects.

            1.3.    Design           Philosophy


            When you learn about a framework, it’s important to know not only what it does but what
            principles   it  follows. Here  are  the  guiding   principles   of the  Spring   Framework:


              • Provide choice at every level. Spring lets you defer design decisions as late as possible. For
                example, you can switch persistence providers through configuration without changing your
                code.  The   same   is true  for  many   other   infrastructure     concerns    and  integration    with  third-party
                APIs.

              • Accommodate diverse perspectives. Spring embraces flexibility and is not opinionated about
                how things should be done. It supports a wide range of application needs with different
                perspectives.

              • Maintain strong backward compatibility. Spring’s evolution has been carefully managed to
                force  few   breaking    changes    between    versions.   Spring    supports   a  carefully   chosen   range   of  JDK
                versions and third-party libraries to facilitate maintenance of applications and libraries that
                depend    on  Spring.

              • Care   about  API   design.  The  Spring   team   puts   a lot of thought   and   time  into  making    APIs  that  are
                intuitive  and   that  hold  up  across  many    versions   and   many    years.

              • Set high standards for code quality. The Spring Framework puts a strong emphasis on
                meaningful,     current,   and   accurate    javadoc.   It is one   of very   few  projects   that  can   claim   clean
                code   structure   with  no  circular   dependencies     between     packages.

            1.4.    Feedback               and       Contributions


            For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click
            here  for  a list of the  suggested    tags  to use  on  Stack   Overflow.    If  you’re fairly  certain   that there   is a
            problem    in the  Spring   Framework      or would    like to suggest   a feature,   please  use  the  GitHub    Issues.

            If you have a solution in mind or a suggested fix, you can submit a pull request on Github.
            However,    please   keep   in mind    that, for  all but  the  most   trivial issues,  we  expect   a  ticket to  be  filed
            in the issue  tracker,   where   discussions    take  place  and   leave  a record   for  future  reference.


            For more    details  see the  guidelines    at the CONTRIBUTING,         top-level  project  page.

            1.5.    Getting           Started


            If  you are  just getting   started   with  Spring,   you  may    want   to begin   using   the  Spring   Framework      by
            creating a Spring Boot-based application. Spring Boot provides a quick (and opinionated) way to
            create a production-ready Spring-based application. It is based on the Spring Framework, favors
            convention    over   configuration,    and  is designed    to get  you  up  and  running    as  quickly  as  possible.


            You  can  use  start.spring.io    to generate    a basic  project   or follow   one  of  the  "Getting   Started"  guides,
            such as Getting Started Building a RESTful Web Service. As well as being easier to digest, these
            guides   are  very   task  focused,   and   most   of them    are  based   on   Spring   Boot.  They   also   cover   other
            projects from the Spring portfolio that you might want to consider when solving a particular
            problem.

            Chapter                2.    Core           Technologies


            This  part  of the  reference    documentation       covers   all  the  technologies   that  are  absolutely   integral   to
            the Spring   Framework.


            Foremost    amongst    these   is  the  Spring Framework’s      Inversion    of Control   (IoC)  container.   A  thorough
            treatment    of the  Spring   Framework’s      IoC  container    is closely  followed    by  comprehensive       coverage
            of Spring’s   Aspect-Oriented      Programming        (AOP)   technologies.    The   Spring   Framework       has  its own
            AOP framework, which is conceptually easy to understand and which successfully addresses the
            80%   sweet  spot  of AOP   requirements      in Java   enterprise   programming.


            Coverage of Spring’s integration with AspectJ (currently the richest — in terms of features — and
            certainly  most   mature    AOP   implementation       in the  Java  enterprise   space)   is also provided.


            AOT processing can be used to optimize your application ahead-of-time. It is typically used for
            native  image   deployment      using  GraalVM.

            2.1.    The       IoC      Container


            This  chapter   covers   Spring’s  Inversion    of Control   (IoC)  container.


            2.1.1.   Introduction          to  the   Spring      IoC   Container        and    Beans

            This chapter covers the Spring Framework implementation of the Inversion of Control (IoC)
            principle. IoC is also known as dependency injection (DI). It is a process whereby objects define
            their dependencies      (that  is, the other   objects   they  work   with)   only  through    constructor    arguments,
            arguments to a factory method, or properties that are set on the object instance after it is
            constructed or returned from a factory method. The container then injects those dependencies
            when   it creates   the  bean.  This   process   is fundamentally      the  inverse   (hence   the  name,    Inversion    of
            Control) of the bean itself controlling the instantiation or location of its dependencies by using
            direct  construction    of classes  or  a mechanism      such   as the  Service  Locator    pattern.


            The  org.springframework.beans         and   org.springframework.context         packages     are  the  basis  for  Spring
            Framework’s       IoC   container.     The   BeanFactory      interface    provides     an   advanced      configuration
            mechanism capable of managing any type of object. ApplicationContext is a sub-interface of
            BeanFactory.   It adds:


              • Easier   integration   with  Spring’s   AOP   features

              • Message    resource    handling    (for use  in internationalization)

              • Event   publication

              • Application-layer       specific    contexts    such     as  the    WebApplicationContext         for   use   in   web
                applications.


            In short, the BeanFactory provides the configuration framework and basic functionality, and the
            ApplicationContext       adds    more     enterprise-specific      functionality.     The    ApplicationContext        is  a
            complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of
            Spring’s    IoC   container.     For    more     information      on    using    the   BeanFactory      instead    of   the

            ApplicationContext,      see  the  section  covering    the BeanFactory    API.


            In Spring, the objects that form the backbone of your application and that are managed by the
            Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and
            managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your
            application.   Beans,   and   the dependencies      among     them,   are  reflected   in the  configuration    metadata
            used  by  a container.


            2.1.2.   Container        Overview

            The  org.springframework.context.ApplicationContext                interface   represents    the  Spring   IoC  container
            and  is responsible     for instantiating,    configuring,    and   assembling     the  beans.   The  container    gets  its
            instructions on what objects to instantiate, configure, and assemble by reading configuration
            metadata.    The  configuration     metadata     is  represented   in  XML,   Java  annotations,    or  Java  code.  It lets
            you express the objects that compose your application and the rich interdependencies between
            those  objects.


            Several implementations of the ApplicationContext interface are supplied with Spring. In stand-
            alone applications, it is common to create an instance of ClassPathXmlApplicationContext or
            FileSystemXmlApplicationContext.           While     XML     has   been     the   traditional    format     for   defining
            configuration metadata, you can instruct the container to use Java annotations or code as the
            metadata    format   by  providing    a small   amount    of XML    configuration    to  declaratively   enable    support
            for these  additional    metadata    formats.


            In most application scenarios, explicit user code is not required to instantiate one or more
            instances   of a  Spring   IoC  container.    For  example,    in a  web   application    scenario,   a simple   eight   (or
            so) lines  of boilerplate    web   descriptor    XML    in the  web.xml    file of the  application    typically   suffices
            (see Convenient     ApplicationContext       Instantiation    for Web    Applications).    If you  use  the  Spring   Tools
            for Eclipse   (an  Eclipse-powered       development      environment),      you   can  easily  create   this  boilerplate
            configuration    with   a few  mouse    clicks  or keystrokes.


            The  following    diagram    shows    a high-level    view   of how   Spring    works.   Your   application    classes  are
            combined with configuration metadata so that, after the ApplicationContext is created and
            initialized,  you  have   a fully configured    and   executable    system   or  application.

            Figure  1.  The  Spring IoC container


            Configuration      Metadata

            As the preceding diagram shows, the Spring IoC container consumes a form of configuration
            metadata. This configuration metadata represents how you, as an application developer, tell the
            Spring  container    to instantiate,   configure,   and   assemble    the  objects  in your   application.


            Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is
            what   most  of  this chapter   uses  to convey    key  concepts    and  features   of the  Spring   IoC container.


                              XML-based     metadata     is not  the  only  allowed    form   of configuration     metadata.     The
                              Spring IoC container itself is totally decoupled from the format in which this
                             configuration metadata is actually written. These days, many developers choose
                              Java-based    configuration    for  their  Spring  applications.


            For information     about   using   other  forms   of metadata     with  the  Spring   container,   see:


              • Annotation-based         configuration:       Spring     2.5   introduced      support      for   annotation-based
                configuration     metadata.

              • Java-based configuration: Starting with Spring 3.0, many features provided by the Spring
                JavaConfig project became part of the core Spring Framework. Thus, you can define beans
                external to your application classes by using Java rather than XML files. To use these new
                features,   see the  @Configuration,     @Bean,  @Import,  and   @DependsOn   annotations.

            Spring   configuration     consists  of  at least  one   and  typically   more    than  one   bean   definition   that  the
            container must manage. XML-based configuration metadata configures these beans as <bean/>
            elements inside a top-level <beans/> element. Java configuration typically uses @Bean-annotated
            methods    within   a @Configuration     class.

            These   bean   definitions    correspond     to the  actual   objects   that  make   up   your   application.   Typically,
            you define service layer objects, data access objects (DAOs), presentation objects such as Struts
            Action instances, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so
            forth. Typically,   one   does  not  configure    fine-grained     domain    objects   in the  container,    because    it  is

            usually   the responsibility    of  DAOs   and   business    logic  to create  and   load  domain     objects.  However,
            you  can   use  Spring’s   integration    with  AspectJ    to configure    objects   that  have   been   created   outside
            the control   of an  IoC  container.   See  Using   AspectJ   to dependency-inject      domain     objects  with  Spring.


            The  following   example     shows   the  basic  structure   of XML-based      configuration     metadata:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="..."    class="...">      ①   ②
                         
                    </bean>


                    <bean   id="..."    class="...">
                         
                    </bean>


                    


              </beans>


            ① The    id attribute   is a string  that identifies   the individual    bean   definition.

            ② The    class  attribute   defines   the type  of the  bean   and  uses   the fully  qualified   classname.

            The  value   of the  id attribute   refers   to collaborating    objects.  The   XML    for referring   to  collaborating
            objects  is not shown    in  this example.    See  Dependencies      for more    information.


            Instantiating    a  Container

            The  location   path   or paths   supplied    to an  ApplicationContext       constructor    are  resource    strings  that
            let  the  container  load  configuration     metadata    from   a variety   of external   resources,    such  as  the local
            file  system, the  Java  CLASSPATH,   and   so on.


            Java


              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");



            Kotlin


              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")

                              After  you  learn   about   Spring’s   IoC  container,    you   may   want   to  know   more    about
                              Spring’s   Resource     abstraction     (as  described     in  Resources),     which     provides     a
                             convenient mechanism for reading an InputStream from locations defined in a
                              URI syntax. In particular, Resource paths are used to construct applications
                              contexts,  as  described    in Application    Contexts   and   Resource    Paths.


            The  following   example     shows   the  service   layer  objects  (services.xml)     configuration     file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    


                    <bean   id="petStore"
              class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
                         <property     name="accountDao"        ref="accountDao"/>
                         <property     name="itemDao"       ref="itemDao"/>
                         
                    </bean>


                    


              </beans>



            The  following   example     shows   the  data  access   objects  daos.xml   file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="accountDao"
                         class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
                         
                    </bean>


                    <bean   id="itemDao"
              class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
                         
                    </bean>


                    


              </beans>

            In the  preceding    example,     the  service  layer   consists  of  the  PetStoreServiceImpl       class and   two   data
            access objects of the types JpaAccountDao and JpaItemDao (based on the JPA Object-Relational
            Mapping    standard).    The  property    name  element    refers  to the  name   of  the JavaBean     property,   and  the
            ref element refers to the name of another bean definition. This linkage between id and ref
            elements expresses the dependency between collaborating objects. For details of configuring an
            object’s  dependencies,     see  Dependencies.



            Composing    XML-based    Configuration   Metadata

            It can be useful to have bean definitions span multiple XML files. Often, each individual XML
            configuration    file represents    a logical  layer  or module     in your  architecture.


            You can use the application context constructor to load bean definitions from all these XML
            fragments.    This  constructor    takes  multiple   Resource   locations,   as was   shown    in the  previous    section.
            Alternatively,   use  one   or more    occurrences     of the  <import/>    element    to load   bean   definitions   from
            another   file or files. The  following    example    shows    how   to do  so:



              <beans>
                    <import    resource="services.xml"/>
                    <import    resource="resources/messageSource.xml"/>
                    <import    resource="/resources/themeSource.xml"/>


                    <bean   id="bean1"     class="..."/>
                    <bean   id="bean2"     class="..."/>
              </beans>



            In the preceding example, external bean definitions are loaded from three files: services.xml,
            messageSource.xml,      and  themeSource.xml.      All location   paths   are   relative  to  the  definition   file doing
            the importing,    so  services.xml    must    be in  the same    directory   or  classpath   location   as  the file doing
            the importing,     while  messageSource.xml       and  themeSource.xml      must   be  in  a resources    location   below
            the  location   of the  importing     file.  As  you can  see,  a leading    slash  is ignored.   However,     given   that
            these  paths   are  relative,  it is better  form   not  to  use  the  slash  at all. The  contents    of the  files being
            imported,    including   the  top  level  <beans/>   element,    must   be  valid  XML    bean   definitions,   according
            to the Spring   Schema.

                              It  is  possible,  but  not  recommended,     to reference    files in parent   directories   using   a
                              relative "../" path. Doing so creates a dependency on a file that is outside the
                              current    application.     In   particular,    this   reference     is  not   recommended          for
                              classpath: URLs (for example, classpath:../services.xml), where the runtime
                              resolution process chooses the “nearest” classpath root and then looks into its
                              parent directory. Classpath configuration changes may lead to the choice of a
                              different,  incorrect   directory.
                
                              You  can  always    use  fully qualified    resource   locations   instead   of  relative  paths:   for
                              example,        file:C:/config/services.xml             or     classpath:/config/services.xml.
                              However, be aware that you are coupling your application’s configuration to
                              specific  absolute   locations.   It  is  generally  preferable  to keep   an indirection    for such
                              absolute locations — for example, through "${…}" placeholders that are resolved
                              against  JVM   system   properties    at runtime.


            The  namespace      itself provides    the  import   directive   feature.  Further    configuration     features   beyond
            plain bean definitions are available in a selection of XML namespaces provided by Spring — for
            example,    the context   and   util  namespaces.



            The Groovy   Bean   Definition  DSL

            As a further example for externalized configuration metadata, bean definitions can also be
            expressed    in Spring’s   Groovy    Bean   Definition    DSL,  as known     from   the  Grails  framework.     Typically,
            such  configuration     live in a ".groovy"    file  with the structure   shown    in  the following    example:



              beans    {
                    dataSource(BasicDataSource)           {
                         driverClassName       =  "org.hsqldb.jdbcDriver"
                         url   =  "jdbc:hsqldb:mem:grailsDB"
                         username     = "sa"
                         password     = ""
                         settings     = [mynew:"setting"]
                    }
                    sessionFactory(SessionFactory)            {
                         dataSource     =  dataSource
                    }
                    myService(MyService)         {
                         nestedBean     =  {  AnotherBean     bean   ->
                               dataSource     =  dataSource
                         }
                    }
              }



            This  configuration     style  is largely  equivalent     to XML    bean   definitions    and  even   supports    Spring’s
            XML   configuration     namespaces.      It also  allows   for importing     XML    bean   definition   files through    an
            importBeans    directive.

            Using   the  Container

            The  ApplicationContext      is the  interface   for an  advanced     factory  capable    of maintaining     a registry   of
            different beans and their dependencies. By using the method T getBean(String name, Class<T>
            requiredType),    you  can  retrieve   instances   of  your  beans.

            The  ApplicationContext       lets you   read   bean   definitions   and   access   them,   as  the  following    example
            shows:


            Java


              //  create    and   configure    beans
              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");


              //  retrieve     configured     instance
              PetStoreService       service    =  context.getBean("petStore",            PetStoreService.class);


              //  use   configured     instance
              List<String>      userList     = service.getUsernameList();



            Kotlin


              import    org.springframework.beans.factory.getBean


              //  create    and   configure    beans
              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")


              //  retrieve     configured     instance
              val   service    =  context.getBean<PetStoreService>("petStore")


              //  use   configured     instance
              var   userList    =  service.getUsernameList()



            With    Groovy     configuration,      bootstrapping       looks    very    similar.   It  has    a   different    context
            implementation class which is Groovy-aware (but also understands XML bean definitions). The
            following   example    shows    Groovy    configuration:


            Java


              ApplicationContext        context    =  new   GenericGroovyApplicationContext("services.groovy",
              "daos.groovy");



            Kotlin


              val   context    =  GenericGroovyApplicationContext("services.groovy",                    "daos.groovy")



            The  most   flexible  variant   is GenericApplicationContext         in  combination     with   reader   delegates — for
            example,    with  XmlBeanDefinitionReader        for XML    files,  as  the  following example    shows:

            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml")
              context.refresh()



            You  can  also  use  the GroovyBeanDefinitionReader         for Groovy    files, as the  following   example     shows:


            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy")
              context.refresh()



            You can mix and match such reader delegates on the same ApplicationContext, reading bean
            definitions   from   diverse  configuration     sources.


            You  can  then  use  getBean   to retrieve   instances    of your  beans.   The  ApplicationContext       interface   has  a
            few  other   methods    for  retrieving   beans,   but,  ideally, your   application    code   should   never   use  them.
            Indeed,   your  application    code   should   have   no  calls to  the getBean()    method    at  all  and thus  have   no
            dependency      on Spring   APIs   at all.  For  example,  Spring’s   integration    with  web   frameworks      provides
            dependency     injection   for  various   web   framework     components      such   as controllers    and  JSF-managed
            beans, letting you declare a dependency on a specific bean through metadata (such as an
            autowiring    annotation).


            2.1.3.   Bean     Overview

            A Spring   IoC  container    manages    one   or more    beans.  These   beans   are  created   with   the configuration
            metadata    that  you  supply   to the  container    (for example,    in the  form   of XML   <bean/>   definitions).


            Within   the  container    itself,  these bean   definitions   are  represented     as BeanDefinition     objects,   which
            contain   (among    other  information)     the  following   metadata:

              • A package-qualified class name: typically, the actual implementation class of the bean being

                defined.

              • Bean behavioral configuration elements, which state how the bean should behave in the
                container    (scope,  lifecycle  callbacks,   and  so  forth).

              • References     to other  beans   that  are  needed    for the  bean   to do  its work.  These   references    are  also
                called  collaborators    or  dependencies.

              • Other   configuration     settings   to set  in the  newly    created   object — for    example,    the  size  limit  of
                the  pool  or the  number     of connections     to use  in a bean   that  manages    a  connection    pool.


            This metadata translates to a set of properties that make up each bean definition. The following
            table describes    these  properties:


            Table 1. The  bean  definition

            Property                                                       Explained     in…

            Class                                                          Instantiating   Beans

            Name                                                           Naming    Beans

            Scope                                                          Bean   Scopes

            Constructor     arguments                                      Dependency      Injection

            Properties                                                     Dependency      Injection

            Autowiring     mode                                            Autowiring     Collaborators

            Lazy   initialization   mode                                   Lazy-initialized    Beans

            Initialization   method                                        Initialization   Callbacks

            Destruction     method                                         Destruction    Callbacks


            In addition to bean definitions that contain information on how to create a specific bean, the
            ApplicationContext      implementations       also  permit   the  registration   of existing   objects  that  are  created
            outside the container (by users). This is done by accessing the ApplicationContext’s BeanFactory
            through      the     getBeanFactory()        method,       which      returns      the    DefaultListableBeanFactory
            implementation.          DefaultListableBeanFactory            supports       this     registration       through       the
            registerSingleton(..)        and    registerBeanDefinition(..)          methods.     However,      typical   applications
            work   solely  with  beans   defined   through    regular   bean   definition   metadata.


                              Bean   metadata    and   manually    supplied    singleton   instances   need   to be  registered    as
                              early  as possible,   in order   for  the container    to properly    reason    about   them   during
                              autowiring    and   other  introspection     steps.  While   overriding    existing   metadata    and
                             existing  singleton    instances    is supported    to  some    degree,   the  registration   of  new
                              beans at runtime (concurrently with live access to the factory) is not officially
                              supported    and   may   lead  to  concurrent    access   exceptions,    inconsistent    state  in the
                              bean  container,    or both.



            Naming     Beans

            Every   bean   has  one  or  more   identifiers.  These   identifiers   must   be  unique    within   the container    that
            hosts  the  bean.   A bean   usually   has   only  one   identifier.  However,     if it  requires  more   than   one,  the

            extra  ones  can  be  considered     aliases.


            In XML-based      configuration    metadata,    you   use  the  id attribute,  the  name  attribute,  or  both  to specify
            the  bean   identifiers.  The   id  attribute   lets you   specify  exactly   one   id. Conventionally,     these   names
            are  alphanumeric      ('myBean',    'someService',    etc.), but  they  can  contain    special  characters    as  well. If
            you  want    to introduce    other   aliases  for  the  bean,   you  can   also  specify  them    in the  name   attribute,
            separated    by  a comma     (,), semicolon     (;), or white   space.   As  a historical   note,  in  versions   prior   to
            Spring   3.1,  the  id  attribute  was defined   as  an xsd:ID   type,  which   constrained     possible   characters.   As
            of 3.1, it is defined as an xsd:string type. Note that bean id uniqueness is still enforced by the
            container,   though   no  longer   by  XML   parsers.


            You  are  not  required   to supply    a name  or an  id for  a bean.   If  you do not  supply   a  name  or id explicitly,
            the container    generates    a unique    name    for that  bean.  However,     if you  want   to refer  to  that bean   by
            name, through the use of the ref element or a Service Locator style lookup, you must provide a
            name. Motivations for not supplying a name are related to using inner beans and autowiring
            collaborators.


                                                    Bean     Naming        Conventions

               The   convention     is  to  use  the  standard Java  convention     for  instance   field names    when    naming
               beans. That is, bean names start with a lowercase letter and are camel-cased from there.
               Examples     of such   names    include   accountManager,    accountService,     userDao,   loginController,     and
               so  forth.


               Naming     beans   consistently    makes    your   configuration     easier  to read   and   understand.     Also,  if
               you   use  Spring  AOP,   it  helps a lot when   applying    advice   to a set of beans    related  by  name.




                              With component scanning in the classpath, Spring generates bean names for
                              unnamed     components,      following    the rules  described    earlier:  essentially,   taking  the
                              simple   class  name    and  turning    its  initial  character  to lower-case.    However,     in the
                             (unusual)    special  case   when    there  is more    than   one   character    and  both   the  first
                              and  second   characters    are  upper   case,  the  original  casing   gets preserved.    These   are
                              the same    rules  as  defined   by  java.beans.Introspector.decapitalize            (which    Spring
                              uses  here).



            Aliasing a Bean   outside  the Bean  Definition

            In a bean definition itself, you can supply more than one name for the bean, by using a
            combination     of up  to  one  name    specified   by  the id  attribute  and   any  number     of other   names    in the
            name attribute. These names can be equivalent aliases to the same bean and are useful for some
            situations, such as letting each component in an application refer to a common dependency by
            using  a bean   name    that is specific  to that  component      itself.

            Specifying all aliases where the bean is actually defined is not always adequate, however. It is
            sometimes     desirable   to  introduce    an  alias  for a  bean   that  is defined   elsewhere.     This  is commonly
            the case in large systems where configuration is split amongst each subsystem, with each
            subsystem     having   its own   set  of object   definitions.   In XML-based      configuration     metadata,    you   can
            use the  <alias/>   element    to accomplish     this. The  following    example    shows    how   to do  so:

              <alias    name="fromName"       alias="toName"/>



            In this case, a bean (in the same container) named fromName may also, after the use of this alias
            definition,  be  referred   to as  toName.


            For example,     the configuration     metadata    for  subsystem     A may   refer  to a  DataSource     by the  name    of
            subsystemA-dataSource.       The  configuration     metadata     for  subsystem     B  may   refer  to a  DataSource     by
            the name of subsystemB-dataSource. When composing the main application that uses both these
            subsystems,    the  main   application    refers  to the  DataSource     by  the name    of myApp-dataSource.     To  have
            all three names refer to the same object, you can add the following alias definitions to the
            configuration    metadata:



              <alias    name="myApp-dataSource"          alias="subsystemA-dataSource"/>
              <alias    name="myApp-dataSource"          alias="subsystemB-dataSource"/>



            Now   each   component      and  the  main   application    can   refer  to the  dataSource    through    a  name   that  is
            unique   and   guaranteed      not  to clash   with  any   other   definition   (effectively   creating   a  namespace),
            yet they  refer  to the  same   bean.


                                                           Java-configuration

               If you   use  Javaconfiguration,      the  @Bean  annotation     can   be used   to  provide   aliases.  See   Using
               the  @Bean  Annotation     for details.




            Instantiating    Beans

            A bean   definition   is essentially   a recipe   for creating   one   or more   objects.   The  container    looks  at the
            recipe for a named bean when asked and uses the configuration metadata encapsulated by that
            bean  definition   to  create  (or acquire)   an  actual   object.


            If  you use  XML-based      configuration     metadata,    you  specify   the  type  (or  class) of  object  that  is to be
            instantiated   in  the class  attribute   of the  <bean/>   element.    This  class  attribute   (which,   internally,  is a
            Class   property      on   a   BeanDefinition      instance)     is  usually    mandatory.       (For   exceptions,     see
            Instantiation    by  Using   an  Instance   Factory    Method    and   Bean   Definition    Inheritance.)    You   can  use
            the Class  property    in one   of two  ways:


              • Typically, to specify the bean class to be constructed in the case where the container itself
                directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java
                code   with  the  new operator.

              • To specify the actual class containing the static factory method that is invoked to create the
                object,  in the  less common      case  where    the  container    invokes   a static   factory   method    on  a class
                to create   the  bean.   The  object   type  returned    from    the invocation     of the  static   factory   method
                may   be  the same    class or  another   class  entirely.

                                                          Nested      class    names

               If you   want   to configure    a  bean   definition   for  a nested   class,  you  may    use  either  the  binary
               name    or the  source   name    of the  nested   class.


               For example, if you have a class called SomeThing in the com.example package, and this
               SomeThing    class  has  a static   nested   class  called  OtherThing,    they  can   be  separated    by  a dollar
               sign ($) or a dot (.). So the value of the class attribute in a bean definition would be
               com.example.SomeThing$OtherThing           or com.example.SomeThing.OtherThing.





            Instantiation  with  a Constructor

            When you create a bean by the constructor approach, all normal classes are usable by and
            compatible    with   Spring.  That   is,  the  class  being developed    does   not  need   to implement     any   specific
            interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice.
            However,     depending     on  what    type  of  IoC  you  use   for that  specific   bean,   you  may    need   a default
            (empty)   constructor.


            The  Spring   IoC  container    can  manage     virtually   any  class  you  want   it to manage.     It  is  not  limited  to
            managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-
            argument) constructor and appropriate setters and getters modeled after the properties in the
            container.   You   can  also  have   more   exotic  non-bean-style      classes  in  your  container.    If,  for  example,
            you need to use a legacy connection pool that absolutely does not adhere to the JavaBean
            specification,   Spring   can  manage    it as well.


            With  XML-based      configuration     metadata    you  can   specify  your   bean   class as follows:



              <bean    id="exampleBean"       class="examples.ExampleBean"/>


              <bean    name="anotherExample"         class="examples.ExampleBeanTwo"/>



            For details about the mechanism for supplying arguments to the constructor (if required) and
            setting  object  instance   properties    after the  object  is constructed,    see  Injecting  Dependencies.



            Instantiation  with  a Static Factory  Method

            When    defining   a bean   that  you  create  with   a static factory   method,    use  the class   attribute  to specify
            the class  that  contains   the  static   factory   method    and   an  attribute   named    factory-method     to specify
            the name of the factory method itself. You should be able to call this method (with optional
            arguments,     as described    later)  and   return   a live  object,  which    subsequently     is treated   as  if it had
            been  created    through    a constructor.    One   use  for such   a bean   definition   is to call static   factories   in
            legacy  code.


            The  following    bean   definition   specifies   that  the  bean   will  be  created   by  calling   a factory   method.
            The definition does not specify the type (class) of the returned object, but rather the class
            containing the factory method. In this example, the createInstance() method must be a static
            method.   The   following   example     shows   how   to specify   a factory   method:

              <bean    id="clientService"
                    class="examples.ClientService"
                    factory-method="createInstance"/>



            The  following   example     shows   a class  that  would   work    with  the  preceding    bean   definition:


            Java


              public    class   ClientService      {
                    private    static   ClientService       clientService      =  new  ClientService();
                    private    ClientService()       {}


                    public   static    ClientService      createInstance()        {
                         return    clientService;
                    }
              }



            Kotlin


              class    ClientService      private    constructor()      {
                    companion     object   {
                         private    val   clientService      =  ClientService()
                         @JvmStatic
                         fun   createInstance()       =  clientService
                    }
              }



            For details about the mechanism for supplying (optional) arguments to the factory method and
            setting  object   instance   properties    after  the  object   is returned    from   the  factory,   see  Dependencies
            and  Configuration     in Detail.



            Instantiation  by Using  an  Instance  Factory  Method

            Similar to instantiation through a static factory method, instantiation with an instance factory
            method    invokes    a non-static   method     of an  existing   bean   from   the  container    to create   a new   bean.
            To  use  this mechanism,      leave   the  class   attribute  empty    and,   in the  factory-bean     attribute,  specify
            the name of a bean in the current (or parent or ancestor) container that contains the instance
            method    that  is  to  be  invoked to  create  the  object.  Set the  name    of the  factory   method    itself with  the
            factory-method     attribute.  The  following    example    shows    how   to configure    such  a bean:

              
              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              
              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>



            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                    }
                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }
              }



            One  factory   class can   also hold   more   than  one   factory  method,    as the  following    example    shows:



              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>


              <bean    id="accountService"
                    factory-bean="serviceLocator"
                    factory-method="createAccountServiceInstance"/>

            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    private    static   AccountService       accountService       = new   AccountServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }


                    public   AccountService       createAccountServiceInstance()             {
                         return    accountService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                         private    val   accountService      =  AccountServiceImpl()
                    }


                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }


                    fun  createAccountServiceInstance():             AccountService       {
                         return    accountService
                    }
              }



            This approach shows that the factory bean itself can be managed and configured through
            dependency     injection   (DI). See  Dependencies      and   Configuration     in Detail.


                              In Spring   documentation,       "factory   bean"   refers  to a  bean   that is configured     in the
                              Spring container and that creates objects through an instance or static factory
                             method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-
                              specific  FactoryBean    implementation       class.



            Determining    a Bean’s Runtime    Type

            The runtime type of a specific bean is non-trivial to determine. A specified class in the bean
            metadata    definition   is just  an  initial class  reference,    potentially   combined      with  a  declared   factory
            method    or being   a  FactoryBean    class which    may   lead  to  a different   runtime    type  of the  bean,   or not

            being set at all in case of an instance-level factory method (which is resolved via the specified
            factory-bean name instead). Additionally, AOP proxying may wrap a bean instance with an
            interface-based     proxy   with   limited  exposure     of the  target   bean’s  actual   type  (just  its implemented
            interfaces).

            The recommended way to find out about the actual runtime type of a particular bean is a
            BeanFactory.getType      call  for the  specified   bean   name.   This   takes  all of the  above   cases   into account
            and  returns   the  type   of object   that a  BeanFactory.getBean       call is going   to return   for  the  same   bean
            name.

            2.1.4.   Dependencies

            A typical  enterprise    application    does   not  consist  of a  single  object  (or  bean   in the  Spring   parlance).
            Even   the  simplest   application    has   a few   objects   that  work   together    to present    what   the  end-user
            sees  as a  coherent    application.    This  next  section   explains    how   you   go  from   defining   a  number     of
            bean  definitions    that stand   alone  to  a fully realized   application    where   objects   collaborate    to achieve
            a goal.


            Dependency       Injection

            Dependency      injection   (DI) is a process   whereby     objects  define   their  dependencies      (that is, the  other
            objects  with  which    they  work)   only  through    constructor    arguments,     arguments     to a factory   method,
            or properties    that  are  set  on  the  object  instance    after  it  is  constructed  or  returned    from   a factory
            method. The container then injects those dependencies when it creates the bean. This process is
            fundamentally      the  inverse   (hence   the  name,   Inversion    of  Control)   of the  bean   itself controlling   the
            instantiation   or  location  of  its  dependencies    on  its own   by  using  direct  construction    of  classes  or the
            Service  Locator    pattern.


            Code   is cleaner   with  the  DI  principle,   and   decoupling    is more    effective  when    objects   are  provided
            with their dependencies. The object does not look up its dependencies and does not know the
            location   or class  of  the  dependencies.      As  a result,  your   classes   become    easier   to test, particularly
            when the dependencies are on interfaces or abstract base classes, which allow for stub or mock
            implementations       to be used   in unit  tests.


            DI  exists   in   two    major    variants:    Constructor-based        dependency       injection    and    Setter-based
            dependency     injection.



            Constructor-based    Dependency     Injection

            Constructor-based DI is accomplished by the container invoking a constructor with a number of
            arguments,      each   representing      a  dependency.       Calling   a   static   factory    method     with    specific
            arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a
            constructor    and  to  a static   factory  method     similarly.  The  following    example    shows    a class  that  can
            only  be dependency-injected        with  constructor     injection:

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  a MovieFinder
                    private    final   MovieFinder      movieFinder;


                    //  a  constructor     so  that   the   Spring   container     can   inject   a  MovieFinder
                    public   SimpleMovieLister(MovieFinder             movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              //  a  constructor      so  that   the  Spring    container     can  inject    a MovieFinder
              class    SimpleMovieLister(private          val   movieFinder:      MovieFinder)      {
                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Notice that there is nothing special about this class. It is a POJO that has no dependencies on
            container   specific  interfaces,   base   classes, or  annotations.


            Constructor     Argument      Resolution

            Constructor argument resolution matching occurs by using the argument’s type. If no potential
            ambiguity exists in the constructor arguments of a bean definition, the order in which the
            constructor    arguments     are  defined    in a bean   definition    is the order   in  which   those   arguments     are
            supplied   to the  appropriate     constructor    when   the  bean   is being   instantiated.   Consider    the following
            class:


            Java


              package    x.y;


              public    class   ThingOne     {


                    public   ThingOne(ThingTwo        thingTwo,     ThingThree     thingThree)      {
                         //  ...
                    }
              }

            Kotlin


              package    x.y


              class    ThingOne(thingTwo:        ThingTwo,    thingThree:      ThingThree)



            Assuming that the ThingTwo and ThingThree classes are not related by inheritance, no potential
            ambiguity    exists.  Thus,  the  following    configuration     works    fine, and   you  do  not  need   to  specify  the
            constructor    argument     indexes   or types   explicitly  in the  <constructor-arg/>      element.



              <beans>
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        ref="beanTwo"/>
                         <constructor-arg        ref="beanThree"/>
                    </bean>


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>


                    <bean   id="beanThree"       class="x.y.ThingThree"/>
              </beans>



            When    another   bean   is referenced,    the  type  is known,    and  matching     can  occur   (as was   the case   with
            the preceding example). When a simple type is used, such as <value>true</value>, Spring cannot
            determine    the  type  of  the  value,  and  so  cannot   match    by  type  without    help.  Consider    the following
            class:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    final   int   years;


                    //  The  Answer    to  Life,   the   Universe,     and  Everything
                    private    final   String    ultimateAnswer;


                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }

            Kotlin


              package    examples


              class    ExampleBean(
                    private    val  years:    Int,   //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    val  ultimateAnswer:       String    //  The   Answer   to  Life,    the  Universe,     and
              Everything
              )



            Constructor   argument    type  matching
            In the  preceding    scenario,    the  container    can  use  type  matching     with   simple   types  if you   explicitly
            specify  the  type  of  the  constructor    argument     by  using   the  type  attribute,  as  the  following    example
            shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       type="int"     value="7500000"/>
                    <constructor-arg       type="java.lang.String"          value="42"/>
              </bean>



            Constructor   argument    index
            You can use the index attribute to specify explicitly the index of constructor arguments, as the
            following   example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       index="0"     value="7500000"/>
                    <constructor-arg       index="1"     value="42"/>
              </bean>



            In addition to resolving the ambiguity of multiple simple values, specifying an index resolves
            ambiguity    where    a constructor    has  two  arguments     of  the same    type.

                             The  index   is  0-based.


            Constructor   argument    name
            You can also use the constructor parameter name for value disambiguation, as the following
            example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       name="years"      value="7500000"/>
                    <constructor-arg       name="ultimateAnswer"         value="42"/>
              </bean>



            Keep   in mind    that, to  make   this  work   out  of  the  box,  your   code  must    be  compiled    with   the  debug
            flag enabled    so that  Spring   can  look   up  the parameter     name    from   the  constructor.    If you  cannot    or

            do not  want   to  compile   your   code   with  the  debug   flag, you   can  use  the  @ConstructorProperties         JDK
            annotation to explicitly name your constructor arguments. The sample class would then have to
            look  as follows:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Fields    omitted


                    @ConstructorProperties({"years",             "ultimateAnswer"})
                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }



            Kotlin


              package    examples


              class    ExampleBean
              @ConstructorProperties("years",             "ultimateAnswer")
              constructor(val       years:    Int,   val  ultimateAnswer:       String)




            Setter-based  Dependency     Injection

            Setter-based DI is accomplished by the container calling setter methods on your beans after
            invoking a no-argument constructor or a no-argument static factory method to instantiate your
            bean.

            The following example shows a class that can only be dependency-injected by using pure setter
            injection.  This  class  is  conventional   Java.  It is  a  POJO that has  no  dependencies      on  container    specific
            interfaces,  base   classes,  or annotations.

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  the  MovieFinder
                    private    MovieFinder     movieFinder;


                    //  a  setter   method    so  that   the  Spring    container     can  inject    a  MovieFinder
                    public   void   setMovieFinder(MovieFinder           movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              class    SimpleMovieLister       {


                    //  a  late-initialized       property    so   that  the   Spring    container    can   inject   a
              MovieFinder
                    lateinit    var   movieFinder:      MovieFinder


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            The  ApplicationContext      supports    constructor-based       and  setter-based    DI  for the  beans   it manages.    It
            also supports setter-based DI after some dependencies have already been injected through the
            constructor    approach.    You   configure    the  dependencies      in the  form   of  a BeanDefinition,     which    you
            use  in conjunction     with  PropertyEditor     instances    to convert   properties    from   one  format   to  another.
            However,    most   Spring   users   do  not  work   with   these  classes  directly   (that is, programmatically)       but
            rather  with   XML   bean  definitions,   annotated    components      (that  is,  classes annotated    with  @Component,
            @Controller,   and   so forth),  or @Bean   methods    in  Java-based    @Configuration     classes.  These   sources   are
            then converted internally into instances of BeanDefinition and used to load an entire Spring IoC
            container   instance.

                                           Constructor-based              or  setter-based          DI?

               Since   you   can  mix   constructor-based       and  setter-based     DI, it is a  good   rule  of thumb     to use
               constructors     for  mandatory      dependencies      and  setter   methods    or  configuration     methods     for
               optional    dependencies.     Note   that  use  of  the  @Autowired      annotation     on  a setter   method    can
               be  used   to make   the  property    be  a required    dependency;     however,     constructor    injection   with
               programmatic       validation   of arguments      is  preferable.

               The    Spring    team    generally     advocates     constructor     injection,    as  it  lets  you    implement
               application components as immutable objects and ensures that required dependencies are
               not null. Furthermore, constructor-injected components are always returned to the client
               (calling) code in a fully initialized state. As a side note, a large number of constructor
               arguments     is a bad   code  smell,  implying    that  the class  likely  has  too many    responsibilities    and
               should   be  refactored    to better  address    proper   separation    of concerns.


               Setter  injection   should   primarily    only  be  used   for optional   dependencies      that  can  be  assigned
               reasonable default values within the class. Otherwise, not-null checks must be performed
               everywhere the code uses the dependency. One benefit of setter injection is that setter
               methods make objects of that class amenable to reconfiguration or re-injection later.
               Management       through    JMX   MBeans     is  therefore  a compelling    use  case  for  setter  injection.


               Use   the  DI  style that  makes     the  most   sense   for a  particular   class.  Sometimes,     when    dealing
               with   third-party   classes   for which   you   do  not  have  the  source,   the  choice  is made    for you.  For
               example,    if a third-party    class  does  not  expose   any   setter  methods,    then  constructor     injection
               may   be  the  only  available   form   of DI.





            Dependency    Resolution   Process

            The  container    performs    bean   dependency      resolution   as  follows:


              • The   ApplicationContext      is created   and   initialized  with  configuration     metadata     that  describes   all
                the  beans.  Configuration     metadata     can  be  specified   by XML,   Java   code,  or annotations.

              • For  each  bean,   its dependencies      are expressed     in the  form  of  properties,   constructor    arguments,
                or arguments to the static-factory method (if you use that instead of a normal constructor).
                These   dependencies      are  provided    to the bean,   when    the bean   is actually   created.

              • Each   property    or constructor    argument     is an  actual   definition   of the  value  to  set,  or  a reference
                to another    bean   in the  container.

              • Each   property    or constructor     argument     that  is  a  value  is  converted  from   its  specified format    to
                the  actual  type  of  that property    or  constructor    argument.     By default,   Spring   can  convert   a value
                supplied   in  string  format   to all built-in  types,  such  as int,  long, String,   boolean,  and   so forth.

            The  Spring   container    validates   the configuration     of each   bean   as the  container    is  created. However,
            the bean properties themselves are not set until the bean is actually created. Beans that are
            singleton-scoped and set to be pre-instantiated (the default) are created when the container is
            created. Scopes are defined in Bean Scopes. Otherwise, the bean is created only when it is
            requested. Creation of a bean potentially causes a graph of beans to be created, as the bean’s
            dependencies      and  its dependencies'      dependencies      (and  so  on)  are  created   and   assigned.    Note  that

            resolution   mismatches      among     those  dependencies      may    show   up  late — that    is,  on  first  creation of
            the affected   bean.


                                                       Circular       dependencies

               If you use predominantly constructor injection, it is possible to create an unresolvable
               circular   dependency      scenario.


               For  example:    Class  A  requires   an  instance   of class  B through    constructor    injection,   and  class  B
               requires an instance of class A through constructor injection. If you configure beans for
               classes   A  and  B  to be  injected   into  each   other,  the  Spring   IoC  container    detects   this  circular
               reference    at runtime,    and  throws    a BeanCurrentlyInCreationException.


               One   possible    solution   is to edit  the  source   code   of  some   classes   to be   configured    by  setters
               rather than constructors. Alternatively, avoid constructor injection and use setter injection
               only.   In   other    words,    although     it  is  not    recommended,        you    can    configure     circular
               dependencies      with  setter  injection.


               Unlike   the  typical  case  (with   no  circular  dependencies),      a circular   dependency      between    bean
               A and bean B forces one of the beans to be injected into the other prior to being fully
               initialized   itself  (a  classic  chicken-and-egg   scenario).



            You can generally trust Spring to do the right thing. It detects configuration problems, such as
            references to non-existent beans and circular dependencies, at container load-time. Spring sets
            properties    and  resolves    dependencies      as late  as  possible,   when    the  bean   is actually   created.   This
            means    that a  Spring   container    that  has  loaded   correctly   can  later  generate    an  exception    when    you
            request an object if there is a problem creating that object or one of its dependencies — for
            example,    the bean   throws    an  exception    as a  result  of a missing   or  invalid   property.   This  potentially
            delayed visibility of some configuration issues is why ApplicationContext implementations by
            default pre-instantiate singleton beans. At the cost of some upfront time and memory to create
            these   beans    before    they    are   actually   needed,     you    discover    configuration      issues   when     the
            ApplicationContext      is created,  not  later. You   can  still  override  this default   behavior    so that  singleton
            beans   initialize lazily, rather   than  being   eagerly   pre-instantiated.


            If  no circular  dependencies      exist,  when    one  or  more   collaborating     beans   are  being   injected   into  a
            dependent bean, each collaborating bean is totally configured prior to being injected into the
            dependent     bean.  This   means    that, if bean   A  has  a dependency      on  bean   B, the  Spring   IoC  container
            completely    configures    bean    B prior   to invoking    the  setter  method     on  bean   A. In  other   words,   the
            bean is instantiated (if it is not a pre-instantiated singleton), its dependencies are set, and the
            relevant lifecycle methods (such as a configured init method or the InitializingBean callback
            method)    are  invoked.



            Examples   of Dependency     Injection

            The  following    example    uses  XML-based      configuration     metadata     for setter-based    DI. A  small   part  of
            a Spring   XML   configuration     file specifies  some   bean   definitions   as  follows:

              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <property     name="beanOne">
                         <ref   bean="anotherExampleBean"/>
                    </property>


                    
                    <property     name="beanTwo"      ref="yetAnotherBean"/>
                    <property     name="integerProperty"         value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   void   setBeanOne(AnotherBean          beanOne)    {
                         this.beanOne      =  beanOne;
                    }


                    public   void   setBeanTwo(YetAnotherBean           beanTwo)    {
                         this.beanTwo      =  beanTwo;
                    }


                    public   void   setIntegerProperty(int          i)  {
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean     {
                    lateinit    var   beanOne:    AnotherBean
                    lateinit    var   beanTwo:    YetAnotherBean
                    var  i:  Int   =  0
              }



            In the  preceding    example,    setters  are  declared    to match   against   the  properties    specified  in  the XML

            file.  The  following  example    uses  constructor-based       DI:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <constructor-arg>
                         <ref   bean="anotherExampleBean"/>
                    </constructor-arg>


                    
                    <constructor-arg       ref="yetAnotherBean"/>


                    <constructor-arg       type="int"     value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   ExampleBean(
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {
                         this.beanOne      =  anotherBean;
                         this.beanTwo      =  yetAnotherBean;
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean(
                         private    val   beanOne:    AnotherBean,
                         private    val   beanTwo:    YetAnotherBean,
                         private    val   i:  Int)



            The constructor arguments specified in the bean definition are used as arguments to the
            constructor    of the  ExampleBean.


            Now   consider    a variant   of this  example,    where,   instead   of using   a constructor,    Spring   is told  to call
            a static  factory   method    to return   an  instance   of the  object:

              <bean    id="exampleBean"       class="examples.ExampleBean"            factory-method="createInstance">
                    <constructor-arg       ref="anotherExampleBean"/>
                    <constructor-arg       ref="yetAnotherBean"/>
                    <constructor-arg       value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    //  a  private    constructor
                    private    ExampleBean(...)       {
                         ...
                    }


                    //  a  static   factory    method;    the   arguments     to  this   method   can   be
                    //  considered     the   dependencies     of   the  bean   that   is  returned,
                    //  regardless     of  how   those   arguments     are  actually     used.
                    public   static    ExampleBean      createInstance      (
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {


                         ExampleBean      eb  =  new  ExampleBean      (...);
                         //  some   other    operations...
                         return    eb;
                    }
              }



            Kotlin


              class    ExampleBean     private    constructor()      {
                    companion     object   {
                         //  a  static    factory    method;    the  arguments     to  this   method    can  be
                         //  considered      the  dependencies      of  the   bean  that   is  returned,
                         //  regardless      of  how  those   arguments     are   actually    used.
                         @JvmStatic
                         fun   createInstance(anotherBean:           AnotherBean,      yetAnotherBean:       YetAnotherBean,
              i:  Int):    ExampleBean     {
                               val  eb  =  ExampleBean      (...)
                               //  some   other   operations...
                               return   eb
                         }
                    }
              }

            Arguments     to  the  static   factory  method     are  supplied    by  <constructor-arg/>      elements,    exactly   the
            same   as if a constructor    had   actually   been  used.   The  type  of  the class  being   returned    by  the factory
            method    does   not  have   to be  of  the same    type  as  the  class  that  contains   the  static   factory   method
            (although, in this example, it is). An instance (non-static) factory method can be used in an
            essentially   identical   fashion   (aside  from    the  use  of the  factory-bean     attribute   instead   of  the  class
            attribute),  so we   do not  discuss   those  details  here.


            Dependencies       and  Configuration       in Detail

            As mentioned      in the previous    section,  you   can  define  bean   properties    and  constructor    arguments      as
            references    to other  managed      beans   (collaborators)    or  as values   defined    inline. Spring’s   XML-based
            configuration     metadata    supports    sub-element      types  within   its <property/>     and   <constructor-arg/>
            elements    for this purpose.



            Straight Values  (Primitives,  Strings,  and  so on)

            The  value   attribute   of the  <property/>     element    specifies   a property    or  constructor     argument     as  a
            human-readable       string  representation.      Spring’s   conversion    service   is used   to convert    these  values
            from   a String  to  the actual   type  of the  property    or argument.     The  following    example    shows    various
            values  being   set:



              <bean    id="myDataSource"       class="org.apache.commons.dbcp.BasicDataSource"                   destroy-
              method="close">
                    
                    <property     name="driverClassName"         value="com.mysql.jdbc.Driver"/>
                    <property     name="url"     value="jdbc:mysql://localhost:3306/mydb"/>
                    <property     name="username"       value="root"/>
                    <property     name="password"       value="misterkaoli"/>
              </bean>



            The  following   example     uses  the  p-namespace      for even   more   succinct   XML   configuration:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                    https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="myDataSource"        class="org.apache.commons.dbcp.BasicDataSource"
                         destroy-method="close"
                         p:driverClassName="com.mysql.jdbc.Driver"
                         p:url="jdbc:mysql://localhost:3306/mydb"
                         p:username="root"
                         p:password="misterkaoli"/>


              </beans>



            The  preceding    XML    is more   succinct.   However,     typos  are  discovered     at runtime    rather   than  design

            time, unless you use an IDE (such as IntelliJ IDEA or the Spring Tools for Eclipse) that supports
            automatic property completion when you create bean definitions. Such IDE assistance is highly
            recommended.


            You  can  also  configure   a  java.util.Properties      instance,   as  follows:



              <bean    id="mappings"
                    class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">


                    
                    <property     name="properties">
                         <value>
                               jdbc.driver.className=com.mysql.jdbc.Driver
                               jdbc.url=jdbc:mysql://localhost:3306/mydb
                         </value>
                    </property>
              </bean>



            The Spring container converts the text inside the <value/> element into a java.util.Properties
            instance   by  using  the  JavaBeans     PropertyEditor     mechanism.      This  is a  nice  shortcut,   and  is one  of  a
            few  places   where    the  Spring   team   do  favor   the  use  of the  nested    <value/>   element    over   the  value
            attribute  style.


            The  idref  element

            The  idref   element    is simply   an  error-proof    way   to  pass  the  id (a  string  value   -  not a reference)    of
            another bean in the container to a <constructor-arg/> or <property/> element. The following
            example    shows   how    to use  it:



              <bean    id="theTargetBean"        class="..."/>


              <bean    id="theClientBean"        class="...">
                    <property     name="targetName">
                         <idref    bean="theTargetBean"/>
                    </property>
              </bean>



            The  preceding    bean   definition   snippet   is exactly  equivalent    (at runtime)    to the  following   snippet:



              <bean    id="theTargetBean"        class="..."     />


              <bean    id="client"     class="...">
                    <property     name="targetName"       value="theTargetBean"/>
              </bean>



            The  first form   is preferable    to the  second,   because    using  the  idref   tag lets the  container    validate   at
            deployment time that the referenced, named bean actually exists. In the second variation, no

            validation   is performed      on  the  value   that is passed    to the  targetName    property    of  the  client  bean.
            Typos are only discovered (with most likely fatal results) when the client bean is actually
            instantiated.   If the  client  bean   is a  prototype    bean,  this  typo  and   the  resulting   exception    may   only
            be discovered     long  after the  container    is  deployed.


                              The  local   attribute   on  the  idref   element    is no  longer   supported     in the  4.0  beans
                              XSD, since it does not provide value over a regular bean reference any more.
                             Change    your  existing   idref   local   references    to idref   bean  when    upgrading     to the
                              4.0 schema.


            A common      place   (at least  in  versions   earlier   than   Spring   2.0)  where    the  <idref/>   element    brings
            value is in the configuration of AOP interceptors in a ProxyFactoryBean bean definition. Using
            <idref/> elements when you specify the interceptor names prevents you from misspelling an
            interceptor   ID.



            References   to Other  Beans  (Collaborators)

            The  ref  element    is the  final element    inside   a <constructor-arg/>      or  <property/>    definition   element.
            Here, you set the value of the specified property of a bean to be a reference to another bean (a
            collaborator)    managed     by  the  container.    The  referenced     bean   is a  dependency      of the  bean   whose
            property    is to be  set, and   it is initialized   on  demand     as  needed    before   the  property    is set. (If the
            collaborator    is a singleton    bean,  it may   already    be  initialized  by  the  container.)    All references    are
            ultimately   a reference    to another    object.  Scoping   and   validation   depend    on  whether    you   specify  the
            ID or  name   of the  other   object  through    the bean  or  parent  attribute.


            Specifying   the  target  bean   through    the  bean  attribute   of the  <ref/>  tag  is the most   general    form  and
            allows  creation    of a reference    to any   bean   in the  same   container    or parent    container,   regardless    of
            whether it is in the same XML file. The value of the bean attribute may be the same as the id
            attribute   of the  target  bean   or  be  the  same   as  one   of the  values   in the  name   attribute   of the  target
            bean.  The  following    example    shows    how   to use  a ref  element:



              <ref   bean="someBean"/>



            Specifying    the  target  bean   through    the  parent   attribute   creates   a  reference    to a  bean   that  is in  a
            parent container of the current container. The value of the parent attribute may be the same as
            either  the id  attribute  of  the target  bean   or  one  of the  values   in the  name  attribute  of  the target  bean.
            The target bean must be in a parent container of the current one. You should use this bean
            reference variant mainly when you have a hierarchy of containers and you want to wrap an
            existing  bean   in  a parent   container    with   a proxy    that  has  the  same   name    as  the  parent   bean.   The
            following   pair  of listings  shows   how   to use  the  parent   attribute:



              
              <bean    id="accountService"        class="com.something.SimpleAccountService">
                    
              </bean>

              
              <bean    id="accountService"        
                    class="org.springframework.aop.framework.ProxyFactoryBean">
                    <property     name="target">
                         <ref   parent="accountService"/>           
                    </property>
                    
              </bean>




                              The  local  attribute   on  the  ref element    is no  longer   supported    in the  4.0 beans    XSD,
                             since it does not provide value over a regular bean reference any more. Change
                              your  existing   ref  local  references    to ref  bean  when    upgrading     to the 4.0  schema.



            Inner Beans

            A <bean/>   element    inside   the  <property/>    or  <constructor-arg/>      elements    defines   an  inner   bean,   as
            the following    example    shows:



              <bean    id="outer"     class="...">
                    
                    <property     name="target">
                         <bean    class="com.example.Person">           
                               <property     name="name"     value="Fiona      Apple"/>
                               <property     name="age"     value="25"/>
                         </bean>
                    </property>
              </bean>



            An  inner  bean   definition   does   not  require   a defined   ID  or name.    If specified,  the  container    does  not
            use such a value as an identifier. The container also ignores the scope flag on creation, because
            inner  beans   are  always   anonymous       and  are  always    created   with  the  outer  bean.   It  is  not  possible  to
            access inner beans independently or to inject them into collaborating beans other than into the
            enclosing   bean.


            As a  corner   case,  it  is  possible  to  receive  destruction  callbacks    from   a custom    scope — for    example,
            for a request-scoped      inner   bean   contained    within   a singleton    bean.  The   creation   of  the inner   bean
            instance is tied to its containing bean, but destruction callbacks let it participate in the request
            scope’s  lifecycle.  This  is  not  a common    scenario.   Inner   beans   typically  simply   share   their  containing
            bean’s  scope.



            Collections

            The <list/>, <set/>, <map/>, and <props/> elements set the properties and arguments of the Java
            Collection    types  List,  Set,  Map, and   Properties,    respectively.   The   following    example     shows   how    to
            use them:

              <bean    id="moreComplexObject"         class="example.ComplexObject">
                    
                    <property     name="adminEmails">
                         <props>
                               <prop   key="administrator">administrator@example.org</prop>
                               <prop   key="support">support@example.org</prop>
                               <prop   key="development">development@example.org</prop>
                         </props>
                    </property>
                    
                    <property     name="someList">
                         <list>
                               <value>a    list   element    followed    by   a reference</value>
                               <ref   bean="myDataSource"        />
                         </list>
                    </property>
                    
                    <property     name="someMap">
                         <map>
                               <entry   key="an    entry"    value="just      some  string"/>
                               <entry   key="a    ref"   value-ref="myDataSource"/>
                         </map>
                    </property>
                    
                    <property     name="someSet">
                         <set>
                               <value>just     some   string</value>
                               <ref   bean="myDataSource"        />
                         </set>
                    </property>
              </bean>



            The  value  of  a map   key  or  value,  or a set  value,  can  also  be any  of  the following    elements:



              bean   |  ref  |  idref   |  list   |  set  |  map   | props    | value    | null



            Collection    Merging

            The Spring container also supports merging collections. An application developer can define a
            parent   <list/>,  <map/>,  <set/>   or  <props/>   element    and  have   child  <list/>,  <map/>,   <set/>  or  <props/>
            elements inherit and override values from the parent collection. That is, the child collection’s
            values   are  the  result  of merging     the  elements    of the  parent    and  child   collections,   with  the  child’s
            collection  elements    overriding    values   specified   in the  parent   collection.


            This section on merging discusses the parent-child bean mechanism. Readers unfamiliar with
            parent   and  child  bean   definitions   may   wish   to read  the  relevant   section   before  continuing.


            The  following   example     demonstrates     collection   merging:

              <beans>
                    <bean   id="parent"      abstract="true"       class="example.ComplexObject">
                         <property     name="adminEmails">
                               <props>
                                    <prop    key="administrator">administrator@example.com</prop>
                                    <prop    key="support">support@example.com</prop>
                               </props>
                         </property>
                    </bean>
                    <bean   id="child"     parent="parent">
                         <property     name="adminEmails">
                               
                               <props   merge="true">
                                    <prop    key="sales">sales@example.com</prop>
                                    <prop    key="support">support@example.co.uk</prop>
                               </props>
                         </property>
                    </bean>
              <beans>



            Notice  the  use  of the  merge=true    attribute  on  the  <props/>   element    of the  adminEmails    property    of the
            child bean definition. When the child bean is resolved and instantiated by the container, the
            resulting   instance   has  an  adminEmails     Properties    collection   that  contains   the  result  of  merging    the
            child’s  adminEmails    collection   with   the  parent’s   adminEmails    collection.   The   following    listing shows
            the result:



              administrator=administrator@example.com
              sales=sales@example.com
              support=support@example.co.uk



            The  child  Properties    collection’s   value   set inherits   all property    elements    from   the  parent   <props/>,
            and  the  child’s value   for the  support   value  overrides    the  value  in  the parent   collection.


            This  merging    behavior     applies   similarly   to the  <list/>,   <map/>,   and  <set/>   collection   types.   In the
            specific  case  of the  <list/>   element,    the  semantics    associated    with   the List   collection   type  (that  is,
            the notion    of an  ordered   collection   of  values)  is maintained.     The   parent’s   values   precede    all of the
            child list’s values. In the case of the Map, Set, and Properties collection types, no ordering exists.
            Hence,   no  ordering    semantics    are  in effect  for  the collection   types   that  underlie   the  associated    Map,
            Set, and  Properties    implementation       types  that  the container    uses  internally.


            Limitations     of Collection    Merging

            You  cannot   merge    different   collection  types   (such  as  a Map and   a List).  If  you do  attempt   to do  so, an
            appropriate    Exception    is  thrown.  The  merge   attribute  must   be  specified   on  the lower,   inherited,   child
            definition.  Specifying    the  merge  attribute   on a  parent   collection  definition    is  redundant   and   does  not
            result in  the desired   merging.

            Strongly-typed      collection

            Thanks to Java’s support for generic types, you can use strongly typed collections. That is, it is
            possible   to declare   a Collection    type  such   that  it  can  only contain   (for example)     String   elements.   If
            you use Spring to dependency-inject a strongly-typed Collection into a bean, you can take
            advantage of Spring’s type-conversion support such that the elements of your strongly-typed
            Collection    instances   are  converted     to the  appropriate     type  prior  to  being   added   to  the Collection.
            The  following   Java   class and   bean  definition   show    how   to do  so:


            Java


              public    class   SomeClass     {


                    private    Map<String,     Float>    accounts;


                    public   void   setAccounts(Map<String,          Float>    accounts)     {
                         this.accounts       = accounts;
                    }
              }



            Kotlin


              class    SomeClass    {
                    lateinit    var   accounts:    Map<String,      Float>
              }




              <beans>
                    <bean   id="something"       class="x.y.SomeClass">
                         <property     name="accounts">
                               <map>
                                    <entry    key="one"     value="9.99"/>
                                    <entry    key="two"     value="2.75"/>
                                    <entry    key="six"     value="3.99"/>
                               </map>
                         </property>
                    </bean>
              </beans>



            When     the   accounts    property     of  the   something     bean    is  prepared     for   injection,   the   generics
            information about the element type of the strongly-typed Map<String, Float> is available by
            reflection.  Thus,   Spring’s   type  conversion     infrastructure     recognizes    the  various    value  elements     as
            being  of  type  Float,  and   the  string  values   (9.99,  2.75,  and  3.99)   are  converted    into  an  actual   Float
            type.



            Null and  Empty   String Values

            Spring   treats  empty    arguments     for  properties    and   the  like  as empty    Strings.   The   following    XML-
            based   configuration    metadata     snippet   sets the  email  property    to the empty    String   value  ("").

              <bean    class="ExampleBean">
                    <property     name="email"     value=""/>
              </bean>



            The  preceding    example    is equivalent    to the  following    Java  code:


            Java


              exampleBean.setEmail("");



            Kotlin


              exampleBean.email        =  ""



            The  <null/>   element    handles   null  values.  The   following   listing  shows   an  example:



              <bean    class="ExampleBean">
                    <property     name="email">
                         <null/>
                    </property>
              </bean>



            The  preceding    configuration     is  equivalent   to the following    Java  code:


            Java


              exampleBean.setEmail(null);



            Kotlin


              exampleBean.email        =  null




            XML  Shortcut   with  the p-namespace

            The  p-namespace      lets you   use  the bean  element’s    attributes   (instead   of nested   <property/>    elements)
            to describe   your   property   values   collaborating    beans,   or both.


            Spring supports extensible configuration formats with namespaces, which are based on an XML
            Schema    definition.   The   beans  configuration     format    discussed    in this  chapter   is defined    in an  XML
            Schema    document.     However,     the  p-namespace       is not  defined   in  an  XSD   file and  exists  only   in the
            core  of Spring.


            The following example shows two XML snippets (the first uses standard XML format and the
            second   uses  the  p-namespace)      that resolve   to the  same   result:

              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="classic"       class="com.example.ExampleBean">
                         <property     name="email"      value="someone@somewhere.com"/>
                    </bean>


                    <bean   name="p-namespace"        class="com.example.ExampleBean"
                         p:email="someone@somewhere.com"/>
              </beans>



            The  example     shows    an  attribute   in the  p-namespace       called  email  in  the  bean   definition.   This  tells
            Spring   to include   a property    declaration.    As  previously    mentioned,     the p-namespace       does  not  have
            a schema    definition,   so you  can  set  the name    of the  attribute   to the property    name.


            This  next  example    includes   two   more   bean   definitions   that  both  have   a reference    to another   bean:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="john-classic"         class="com.example.Person">
                         <property     name="name"      value="John     Doe"/>
                         <property     name="spouse"      ref="jane"/>
                    </bean>


                    <bean   name="john-modern"
                         class="com.example.Person"
                         p:name="John      Doe"
                         p:spouse-ref="jane"/>


                    <bean   name="jane"      class="com.example.Person">
                         <property     name="name"      value="Jane     Doe"/>
                    </bean>
              </beans>



            This example includes not only a property value using the p-namespace but also uses a special
            format    to   declare    property     references.     Whereas       the   first  bean    definition     uses   <property
            name="spouse" ref="jane"/> to create a reference from bean john to bean jane, the second bean
            definition   uses  p:spouse-ref="jane"       as an  attribute   to do  the exact   same   thing.  In this  case,  spouse  is
            the property name, whereas the -ref part indicates that this is not a straight value but rather a
            reference   to another    bean.

                              The  p-namespace       is  not  as  flexible  as  the  standard  XML    format.   For  example,    the
                              format   for  declaring    property    references    clashes   with   properties   that  end   in  Ref,
                             whereas    the  standard    XML   format    does  not.  We   recommend       that  you  choose   your
                              approach     carefully    and    communicate        this  to   your   team    members       to  avoid
                              producing    XML    documents     that  use  all  three approaches     at the  same   time.



            XML  Shortcut   with  the c-namespace

            Similar to the XML Shortcut with the p-namespace, the c-namespace, introduced in Spring 3.1,
            allows  inlined   attributes   for configuring     the constructor    arguments      rather  then   nested   constructor-
            arg elements.


            The  following    example    uses   the  c: namespace      to do  the  same    thing  as the  from   Constructor-based
            Dependency      Injection:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:c="http://www.springframework.org/schema/c"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>
                    <bean   id="beanThree"       class="x.y.ThingThree"/>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        name="thingTwo"       ref="beanTwo"/>
                         <constructor-arg        name="thingThree"       ref="beanThree"/>
                         <constructor-arg        name="email"      value="something@somewhere.com"/>
                    </bean>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne"         c:thingTwo-ref="beanTwo"
                         c:thingThree-ref="beanThree"            c:email="something@somewhere.com"/>


              </beans>



            The  c: namespace      uses   the same    conventions     as the  p: one   (a trailing  -ref  for  bean   references)    for
            setting  the  constructor    arguments     by  their  names.   Similarly,   it needs   to be  declared   in  the  XML   file
            even  though    it  is  not  defined  in  an  XSD  schema  (it  exists  inside  the  Spring core).

            For the  rare  cases   where   the  constructor    argument     names    are  not  available   (usually   if  the  bytecode
            was   compiled    without    debugging     information),     you   can  use  fallback   to  the  argument     indexes,    as
            follows:

              
              <bean    id="beanOne"     class="x.y.ThingOne"         c:_0-ref="beanTwo"        c:_1-ref="beanThree"
                    c:_2="something@somewhere.com"/>




                              Due  to  the XML    grammar,     the  index   notation    requires   the  presence    of the  leading
                              _, as XML attribute names cannot start with a number (even though some IDEs
                             allow it). A corresponding index notation is also available for <constructor-arg>
                              elements but not commonly used since the plain order of declaration is usually
                              sufficient  there.


            In practice, the constructor resolution mechanism is quite efficient in matching arguments, so
            unless  you   really need   to, we  recommend       using   the name    notation   throughout     your   configuration.



            Compound     Property  Names

            You can use compound or nested property names when you set bean properties, as long as all
            components      of the  path   except   the  final property    name    are  not   null. Consider    the  following    bean
            definition:



              <bean    id="something"      class="things.ThingOne">
                    <property     name="fred.bob.sammy"         value="123"     />
              </bean>



            The  something    bean   has  a fred  property,    which   has  a  bob property,    which   has  a  sammy  property,   and
            that final  sammy  property    is being  set  to a value   of 123. In  order  for  this to work,   the  fred  property    of
            something   and   the  bob property    of  fred  must   not  be  null  after  the bean   is constructed.    Otherwise,     a
            NullPointerException      is thrown.


            Using   depends-on

            If  a  bean is  a  dependency    of another    bean,  that  usually   means    that  one  bean   is set as  a property    of
            another. Typically you accomplish this with the <ref/> element in XML-based configuration
            metadata.    However,     sometimes     dependencies      between    beans   are  less  direct. An   example    is when    a
            static initializer in a class needs to be triggered, such as for database driver registration. The
            depends-on    attribute   can  explicitly  force   one  or  more   beans    to be  initialized  before   the  bean   using
            this element is initialized. The following example uses the depends-on attribute to express a
            dependency     on  a single   bean:



              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager"/>
              <bean    id="manager"     class="ManagerBean"         />



            To express    a dependency      on  multiple   beans,   supply   a list  of  bean  names  as  the value   of the  depends-
            on attribute   (commas,    whitespace,     and  semicolons     are valid  delimiters):

              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager,accountDao">
                    <property     name="manager"      ref="manager"      />
              </bean>


              <bean    id="manager"     class="ManagerBean"         />
              <bean    id="accountDao"       class="x.y.jdbc.JdbcAccountDao"             />




                              The  depends-on    attribute  can   specify  both   an initialization-time     dependency      and,  in
                              the case of singleton beans only, a corresponding destruction-time dependency.
                             Dependent beans that define a depends-on relationship with a given bean are
                              destroyed    first,  prior  to  the  given  bean itself being   destroyed.   Thus,   depends-on    can
                              also control   shutdown     order.



            Lazy-initialized     Beans

            By  default,  ApplicationContext      implementations       eagerly   create   and  configure    all singleton   beans    as
            part  of the  initialization  process.   Generally,    this pre-instantiation     is desirable,   because   errors   in the
            configuration or surrounding environment are discovered immediately, as opposed to hours or
            even days later. When this behavior is not desirable, you can prevent pre-instantiation of a
            singleton   bean   by  marking    the  bean   definition   as being   lazy-initialized.   A  lazy-initialized   bean   tells
            the IoC  container    to create  a bean   instance   when    it is  first  requested, rather   than  at startup.


            In XML, this behavior is controlled by the lazy-init attribute on the <bean/> element, as the
            following   example    shows:



              <bean    id="lazy"    class="com.something.ExpensiveToCreateBean"                  lazy-init="true"/>
              <bean    name="not.lazy"       class="com.something.AnotherBean"/>



            When the preceding configuration is consumed by an ApplicationContext, the lazy bean is not
            eagerly   pre-instantiated     when    the  ApplicationContext      starts,  whereas    the  not.lazy    bean   is eagerly
            pre-instantiated.


            However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-
            initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must
            satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean
            elsewhere    that  is  not  lazy-initialized.

            You can also control lazy-initialization at the container level by using the default-lazy-init
            attribute  on  the  <beans/>   element,   as  the following    example    shows:



              <beans    default-lazy-init="true">
                    
              </beans>

            Autowiring     Collaborators

            The  Spring   container    can   autowire    relationships     between    collaborating     beans.   You  can   let Spring
            resolve   collaborators    (other   beans)   automatically     for  your   bean   by  inspecting    the  contents    of the
            ApplicationContext.      Autowiring    has  the  following    advantages:

              • Autowiring can significantly reduce the need to specify properties or constructor arguments.
                (Other mechanisms such as a bean template discussed elsewhere in this chapter are also
                valuable    in this regard.)

              • Autowiring     can  update    a configuration    as  your  objects   evolve.  For  example,    if you  need   to add   a
                dependency      to  a class,  that dependency       can  be  satisfied  automatically     without    you   needing    to
                modify the configuration. Thus autowiring can be especially useful during development,
                without    negating    the option   of  switching    to explicit  wiring    when    the code   base   becomes     more
                stable.


            When using XML-based configuration metadata (see Dependency Injection), you can specify the
            autowire mode for a bean definition with the autowire attribute of the <bean/> element. The
            autowiring functionality has four modes. You specify autowiring per bean and can thus choose
            which   ones  to  autowire.   The   following   table  describes   the  four  autowiring     modes:


            Table 2. Autowiring    modes

            Mode                     Explanation
            no                       (Default)   No  autowiring.    Bean   references    must   be  defined   by  ref elements.
                                     Changing     the default   setting  is not  recommended       for  larger  deployments,
                                     because    specifying   collaborators     explicitly  gives  greater   control  and   clarity. To
                                     some    extent,  it  documents    the structure   of  a system.
            byName                   Autowiring     by  property    name.   Spring   looks  for a  bean  with   the same    name   as
                                     the  property    that needs   to be  autowired.    For  example,    if a bean   definition   is
                                     set to  autowire    by name    and  it contains   a master   property    (that is, it  has  a
                                     setMaster(..)     method),    Spring   looks  for a  bean  definition   named     master  and
                                     uses  it to set the  property.
            byType                   Lets  a property    be  autowired    if exactly  one   bean  of  the property    type  exists  in
                                     the  container.   If more   than   one  exists, a  fatal exception    is  thrown,  which
                                     indicates   that  you  may   not  use  byType   autowiring    for that  bean.   If  there are no
                                     matching     beans,  nothing    happens    (the  property   is not  set).
            constructor              Analogous     to byType   but  applies  to constructor    arguments.     If there  is not
                                     exactly   one  bean   of the  constructor    argument     type  in the  container,   a fatal
                                     error   is  raised.


            With byType or constructor autowiring mode, you can wire arrays and typed collections. In such
            cases,  all autowire    candidates     within   the  container    that  match    the  expected    type  are  provided     to
            satisfy  the  dependency.     You   can  autowire     strongly-typed     Map  instances   if the  expected    key   type  is
            String. An autowired Map instance’s values consist of all bean instances that match the expected
            type, and   the Map  instance’s   keys  contain   the  corresponding      bean   names.

            Limitations  and  Disadvantages    of Autowiring

            Autowiring works best when it is used consistently across a project. If autowiring is not used in
            general,  it might   be confusing    to developers     to use  it  to  wire  only  one  or  two  bean definitions.


            Consider   the  limitations   and   disadvantages     of autowiring:

              • Explicit  dependencies      in  property   and  constructor-arg      settings  always    override   autowiring.     You
                cannot    autowire    simple   properties    such  as  primitives,   Strings,   and   Classes   (and  arrays   of such
                simple   properties).   This  limitation   is by-design.

              • Autowiring     is less  exact  than   explicit  wiring.   Although,    as  noted   in  the  earlier  table,  Spring   is
                careful to avoid guessing in case of ambiguity that might have unexpected results. The
                relationships    between    your   Spring-managed       objects   are  no longer   documented      explicitly.

              • Wiring information may not be available to tools that may generate documentation from a
                Spring   container.

              • Multiple bean definitions within the container may match the type specified by the setter
                method    or  constructor    argument     to be  autowired.    For  arrays,  collections,   or Map  instances,   this is
                not  necessarily    a problem.    However,     for dependencies      that  expect   a single  value,  this  ambiguity
                is not  arbitrarily  resolved.   If no  unique   bean   definition   is available,   an  exception   is thrown.


            In the  latter scenario,   you  have   several   options:

              • Abandon     autowiring     in favor  of explicit  wiring.

              • Avoid   autowiring     for  a bean   definition    by  setting  its autowire-candidate       attributes   to false,   as
                described    in the  next  section.

              • Designate    a single  bean   definition   as the  primary    candidate    by  setting  the  primary  attribute   of its
                <bean/>   element    to true.

              • Implement the more fine-grained control available with annotation-based configuration, as
                described    in Annotation-based       Container    Configuration.



            Excluding   a  Bean from  Autowiring

            On a per-bean basis, you can exclude a bean from autowiring. In Spring’s XML format, set the
            autowire-candidate      attribute   of the  <bean/>  element    to false.  The   container    makes   that  specific  bean
            definition   unavailable     to the  autowiring     infrastructure     (including   annotation     style  configurations
            such  as @Autowired).


                              The  autowire-candidate       attribute   is designed    to only  affect  type-based     autowiring.
                              It does not affect explicit references by name, which get resolved even if the
                             specified bean is not marked as an autowire candidate. As a consequence,
                              autowiring    by  name    nevertheless    injects  a bean   if  the  name  matches.


            You can also limit autowire candidates based on pattern-matching against bean names. The top-
            level <beans/> element accepts one or more patterns within its default-autowire-candidates
            attribute. For example, to limit autowire candidate status to any bean whose name ends with
            Repository,   provide    a value   of *Repository.    To  provide    multiple   patterns,   define   them   in  a comma-
            separated    list.  An  explicit  value of true  or  false  for  a bean   definition’s   autowire-candidate      attribute

            always   takes  precedence.     For  such  beans,   the pattern   matching     rules  do  not apply.


            These techniques are useful for beans that you never want to be injected into other beans by
            autowiring. It does not mean that an excluded bean cannot itself be configured by using
            autowiring.    Rather,   the bean   itself is not a  candidate    for autowiring    other   beans.


            Method    Injection

            In most   application    scenarios,    most   beans   in the  container    are   singletons.   When    a  singleton   bean
            needs   to collaborate    with  another    singleton   bean   or a  non-singleton     bean   needs   to collaborate    with
            another non-singleton bean, you typically handle the dependency by defining one bean as a
            property    of the  other.  A  problem     arises  when    the  bean   lifecycles   are  different.  Suppose     singleton
            bean   A  needs   to use   non-singleton     (prototype)    bean   B, perhaps     on  each   method    invocation     on  A.
            The  container    creates   the singleton    bean   A only  once,   and  thus   only  gets  one  opportunity     to set the
            properties.   The   container    cannot   provide    bean   A  with  a  new   instance   of  bean   B every   time   one  is
            needed.

            A solution   is to  forego   some   inversion    of control.   You  can   make   bean   A  aware    of the  container    by
            implementing the ApplicationContextAware interface, and by making a getBean("B") call to the
            container ask for (a typically new) bean B instance every time bean A needs it. The following
            example    shows   this  approach:

            Java


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple;


              //  Spring-API      imports
              import    org.springframework.beans.BeansException;
              import    org.springframework.context.ApplicationContext;
              import    org.springframework.context.ApplicationContextAware;


              public    class   CommandManager       implements     ApplicationContextAware          {


                    private    ApplicationContext        applicationContext;


                    public   Object    process(Map      commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    protected     Command    createCommand()       {
                         //  notice    the   Spring   API   dependency!
                         return    this.applicationContext.getBean("command",                 Command.class);
                    }


                    public   void   setApplicationContext(
                               ApplicationContext        applicationContext)        throws    BeansException       {
                         this.applicationContext          =  applicationContext;
                    }
              }

            Kotlin


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple


              //  Spring-API      imports
              import    org.springframework.context.ApplicationContext
              import    org.springframework.context.ApplicationContextAware


              class    CommandManager      :  ApplicationContextAware          {


                    private    lateinit    var   applicationContext:        ApplicationContext


                    fun  process(commandState:          Map<*,   *>):   Any   {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  notice    the  Spring    API  dependency!
                    protected     fun  createCommand()       =
                               applicationContext.getBean("command",               Command::class.java)


                    override    fun   setApplicationContext(applicationContext:                ApplicationContext)         {
                         this.applicationContext          =  applicationContext
                    }
              }



            The preceding is not desirable, because the business code is aware of and coupled to the Spring
            Framework.      Method    Injection,   a somewhat      advanced     feature   of  the  Spring   IoC  container,   lets  you
            handle   this use  case  cleanly.



               You   can  read  more   about   the  motivation    for  Method    Injection   in this blog  entry.





            Lookup   Method   Injection

            Lookup    method    injection   is the  ability of  the  container   to  override   methods     on  container-managed
            beans   and  return   the  lookup    result  for another    named     bean   in the  container.    The  lookup    typically
            involves a prototype bean, as in the scenario described in the preceding section. The Spring
            Framework      implements     this  method    injection   by  using  bytecode    generation    from   the  CGLIB    library
            to dynamically     generate   a  subclass   that overrides    the  method.

                                • For  this  dynamic    subclassing    to  work,   the  class that  the  Spring   bean   container
                                  subclasses    cannot   be  final,  and   the  method    to  be  overridden     cannot   be  final,
                                  either.

                                • Unit-testing    a class  that  has   an  abstract   method     requires    you  to  subclass   the
                                  class  yourself   and  to supply   a stub  implementation       of the  abstract   method.
                               • Concrete    methods     are  also necessary     for component      scanning,    which    requires
                                  concrete   classes   to pick  up.

                                • A further key limitation is that lookup methods do not work with factory
                                  methods and in particular not with @Bean methods in configuration classes,
                                  since,  in  that  case, the  container    is not  in  charge   of  creating   the  instance   and
                                  therefore   cannot    create  a runtime-generated        subclass   on  the fly.


            In the case of the CommandManager class in the previous code snippet, the Spring container
            dynamically     overrides    the implementation       of the  createCommand()      method.    The  CommandManager     class
            does  not  have   any  Spring   dependencies,     as the  reworked     example    shows:


            Java


              package    fiona.apple;


              //  no   more  Spring    imports!


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              package    fiona.apple


              //  no   more  Spring    imports!


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    fun  createCommand():        Command
              }



            In the client class that contains the method to be injected (the CommandManager in this case), the
            method    to be  injected  requires    a signature   of the  following    form:



              <public|protected>        [abstract]      <return-type>      theMethodName(no-arguments);



            If  the  method   is abstract,   the  dynamically-generated         subclass   implements      the  method.    Otherwise,
            the dynamically-generated subclass overrides the concrete method defined in the original class.
            Consider   the  following    example:



              
              <bean    id="myCommand"      class="fiona.apple.AsyncCommand"              scope="prototype">
                    
              </bean>


              
              <bean    id="commandManager"        class="fiona.apple.CommandManager">
                    <lookup-method      name="createCommand"         bean="myCommand"/>
              </bean>



            The bean identified as commandManager calls its own createCommand() method whenever it needs a
            new   instance   of the  myCommand   bean.   You  must   be  careful  to deploy   the  myCommand    bean   as a prototype
            if that is actually what is needed. If it is a singleton, the same instance of the myCommand bean is
            returned   each   time.


            Alternatively, within the annotation-based component model, you can declare a lookup method
            through   the  @Lookup   annotation,    as the  following   example     shows:

            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup("myCommand")
                    protected     abstract    Command    createCommand();
              }



            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup("myCommand")
                    protected     abstract    fun  createCommand():        Command
              }



            Or, more    idiomatically,   you   can  rely on  the  target  bean   getting   resolved   against   the  declared   return
            type  of the lookup    method:


            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup
                    protected     abstract    fun  createCommand():        Command
              }



            Note that you should typically declare such annotated lookup methods with a concrete stub
            implementation,      in order   for them    to be  compatible    with   Spring’s  component      scanning    rules  where
            abstract classes get ignored by default. This limitation does not apply to explicitly registered or
            explicitly  imported    bean   classes.


                              Another way of accessing differently scoped target beans is an ObjectFactory/
                              Provider   injection  point.  See  Scoped    Beans   as Dependencies.
                 
                              You       may        also      find       the       ServiceLocatorFactoryBean             (in      the
                              org.springframework.beans.factory.config             package)    to be useful.



            Arbitrary  Method   Replacement

            A less useful form of method injection than lookup method injection is the ability to replace
            arbitrary   methods     in a  managed     bean    with  another    method     implementation.       You  can   safely  skip
            the rest  of this section   until you   actually  need   this functionality.


            With XML-based configuration metadata, you can use the replaced-method element to replace an
            existing  method     implementation       with   another,   for  a  deployed    bean.   Consider    the  following    class,
            which   has  a method    called  computeValue     that  we  want   to override:


            Java


              public    class   MyValueCalculator        {


                    public   String    computeValue(String         input)   {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }

            Kotlin


              class    MyValueCalculator       {


                    fun  computeValue(input:         String):    String    {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }



            A class that implements the org.springframework.beans.factory.support.MethodReplacer interface
            provides   the  new   method    definition,   as the  following   example     shows:


            Java


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              public    class   ReplacementComputeValue          implements     MethodReplacer       {


                    public   Object    reimplement(Object        o,  Method    m,  Object[]    args)    throws   Throwable     {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         String    input   =  (String)    args[0];
                         ...
                         return    ...;
                    }
              }



            Kotlin


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              class    ReplacementComputeValue          : MethodReplacer       {


                    override    fun   reimplement(obj:       Any,   method:    Method,    args:   Array<out     Any>):    Any  {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         val   input   =  args[0]    as  String;
                         ...
                         return    ...;
                    }
              }



            The  bean   definition    to deploy   the  original   class  and   specify   the  method    override    would    resemble
            the following    example:

              <bean    id="myValueCalculator"         class="x.y.z.MyValueCalculator">
                    
                    <replaced-method       name="computeValue"         replacer="replacementComputeValue">
                         <arg-type>String</arg-type>
                    </replaced-method>
              </bean>


              <bean    id="replacementComputeValue"           class="a.b.c.ReplacementComputeValue"/>



            You  can   use  one   or more    <arg-type/>    elements     within   the  <replaced-method/>       element    to indicate
            the method signature of the method being overridden. The signature for the arguments is
            necessary only if the method is overloaded and multiple variants exist within the class. For
            convenience,     the  type  string  for  an  argument     may   be  a  substring   of  the  fully qualified   type   name.
            For example,    the  following    all  match  java.lang.String:



              java.lang.String
              String
              Str



            Because   the  number     of arguments     is often  enough     to distinguish   between     each  possible   choice,   this
            shortcut can save a lot of typing, by letting you type only the shortest string that matches an
            argument     type.

            2.1.5.   Bean     Scopes

            When    you   create   a bean   definition,   you   create   a recipe   for  creating   actual   instances    of the  class
            defined   by  that  bean   definition.   The  idea  that  a bean   definition    is a recipe   is  important,   because   it
            means   that,  as with   a class, you  can  create   many    object  instances   from   a single  recipe.


            You  can  control   not  only  the  various   dependencies      and   configuration     values   that are  to  be plugged
            into an object that is created from a particular bean definition but also control the scope of the
            objects  created   from    a particular   bean   definition.   This   approach    is powerful     and  flexible,  because
            you  can  choose    the scope   of  the objects   you  create   through    configuration    instead   of  having   to bake
            in the  scope   of  an  object  at  the  Java  class  level.  Beans   can   be  defined   to  be  deployed    in  one  of  a
            number     of scopes.   The  Spring    Framework      supports    six scopes,   four   of which    are  available   only  if
            you  use  a web-aware      ApplicationContext.      You  can  also  create  a custom    scope.

            The  following   table  describes    the supported     scopes:


            Table 3. Bean   scopes

            Scope                    Description

            singleton                (Default)   Scopes   a single  bean   definition   to a single  object   instance   for each
                                     Spring   IoC  container.

            prototype                Scopes   a  single  bean  definition   to  any  number     of object  instances.

            Scope                    Description

            request                  Scopes   a  single  bean  definition   to  the lifecycle  of a single   HTTP   request.   That
                                     is, each  HTTP    request   has  its  own  instance   of a bean   created   off the  back  of  a
                                     single  bean   definition.   Only  valid  in  the context   of a web-aware      Spring
                                     ApplicationContext.

            session                  Scopes   a  single  bean  definition   to  the lifecycle  of an  HTTP    Session.  Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            application              Scopes   a  single  bean  definition   to  the lifecycle  of a ServletContext.     Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            websocket                Scopes   a  single  bean  definition   to  the lifecycle  of a WebSocket.    Only  valid  in the
                                     context   of a  web-aware     Spring   ApplicationContext.



                              As  of Spring   3.0,  a thread    scope   is available   but  is  not  registered   by   default.  For
                             more   information,     see  the  documentation       for  SimpleThreadScope.      For  instructions
                              on how    to register  this or  any  other  custom    scope,  see  Using   a Custom    Scope.



            The  Singleton    Scope

            Only  one   shared   instance    of a singleton    bean   is  managed,   and   all requests   for  beans   with   an  ID  or
            IDs that  match    that  bean   definition   result  in  that one   specific  bean   instance    being  returned    by  the
            Spring  container.


            To put  it another    way,  when    you  define   a bean   definition   and   it  is  scoped as a singleton,   the  Spring
            IoC container    creates   exactly   one  instance    of the  object  defined   by  that  bean   definition.   This  single
            instance   is stored   in a  cache   of such   singleton    beans,   and  all subsequent      requests   and   references
            for that  named    bean   return   the  cached    object.  The  following    image   shows    how   the  singleton   scope
            works:








































            Spring’s   concept   of  a singleton    bean   differs  from    the  singleton   pattern   as  defined    in the  Gang    of
            Four  (GoF)   patterns    book.  The   GoF   singleton   hard-codes     the  scope   of  an  object  such   that  one  and

            only  one  instance   of  a particular   class  is created   per  ClassLoader.     The  scope   of the  Spring   singleton
            is  best  described  as being   per-container     and   per-bean.   This  means    that,  if  you  define one  bean   for  a
            particular   class in  a single  Spring   container,   the  Spring   container    creates  one   and  only  one   instance
            of the  class  defined   by  that  bean   definition.   The   singleton   scope   is the  default   scope   in Spring.   To
            define  a bean   as  a singleton   in XML,   you   can  define  a bean   as  shown    in the  following   example:



              <bean    id="accountService"        class="com.something.DefaultAccountService"/>


              
              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="singleton"/>




            The  Prototype     Scope

            The non-singleton prototype scope of bean deployment results in the creation of a new bean
            instance every time a request for that specific bean is made. That is, the bean is injected into
            another    bean   or  you  request    it through    a getBean()    method     call on  the  container.    As  a  rule,  you
            should   use  the prototype    scope   for all stateful  beans   and   the singleton   scope   for  stateless  beans.


            The  following   diagram     illustrates  the Spring   prototype    scope:








































            (A data   access  object   (DAO)   is not  typically   configured    as  a prototype,    because    a  typical  DAO    does
            not hold   any  conversational     state. It was   easier  for us  to reuse  the  core  of the  singleton   diagram.)

            The  following   example     defines   a bean   as a prototype    in XML:



              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="prototype"/>



            In contrast   to the  other   scopes,  Spring   does   not  manage     the complete     lifecycle  of a prototype    bean.

            The  container    instantiates,   configures,    and  otherwise     assembles    a  prototype    object  and   hands   it to
            the client,  with   no  further   record   of that  prototype    instance.   Thus,   although    initialization   lifecycle
            callback   methods    are  called  on  all objects   regardless    of scope,  in  the case  of  prototypes,    configured
            destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped
            objects  and   release  expensive     resources    that  the  prototype    beans   hold.  To  get the  Spring   container
            to release  resources    held  by  prototype-scoped      beans,   try  using  a custom    bean   post-processor,     which
            holds  a reference    to beans   that  need   to be cleaned    up.


            In some   respects,   the  Spring   container’s   role  in  regard   to a prototype-scoped       bean  is a  replacement
            for the  Java  new  operator.    All lifecycle  management        past  that  point  must    be  handled    by  the  client.
            (For details  on  the  lifecycle  of a bean   in the  Spring   container,   see  Lifecycle   Callbacks.)


            Singleton    Beans   with   Prototype-bean       Dependencies

            When you use singleton-scoped beans with dependencies on prototype beans, be aware that
            dependencies     are  resolved    at instantiation    time.  Thus,   if  you dependency-inject      a  prototype-scoped
            bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-
            injected  into  the  singleton   bean.   The  prototype    instance    is  the  sole  instance that  is ever  supplied    to
            the singleton-scoped      bean.


            However,    suppose    you   want   the  singleton-scoped      bean   to acquire   a  new   instance   of the  prototype-
            scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into
            your   singleton     bean,    because    that   injection    occurs    only    once,   when     the   Spring    container
            instantiates the singleton bean and resolves and injects its dependencies. If you need a new
            instance   of a prototype    bean   at runtime    more   than   once,  see Method     Injection.


            Request,    Session,   Application,     and   WebSocket      Scopes

            The  request,   session,   application,    and   websocket   scopes   are   available   only  if you   use  a web-aware
            Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you use these
            scopes    with   regular     Spring    IoC   containers,     such   as   the   ClassPathXmlApplicationContext,           an
            IllegalStateException       that complains     about   an  unknown     bean   scope   is thrown.



            Initial  Web Configuration

            To support the scoping of beans at the request, session, application, and websocket levels (web-
            scoped beans), some minor initial configuration is required before you define your beans. (This
            initial setup  is not  required   for  the standard    scopes:   singleton   and   prototype.)


            How   you  accomplish     this  initial setup  depends    on  your   particular   Servlet  environment.


            If  you access  scoped    beans   within   Spring   Web    MVC,   in effect,  within   a request   that  is processed    by
            the  Spring   DispatcherServlet,      no  special   setup   is necessary.   DispatcherServlet       already   exposes    all
            relevant   state.


            If  you use  a  Servlet   web   container,    with  requests    processed    outside   of  Spring’s   DispatcherServlet
            (for     example,        when        using      JSF      or      Struts),     you       need       to     register      the
            org.springframework.web.context.request.RequestContextListener ServletRequestListener. This can
            be done    programmatically       by  using   the WebApplicationInitializer         interface.   Alternatively,    add  the
            following   declaration    to your   web   application’s   web.xml   file:

              <web-app>
                    ...
                    <listener>
                         <listener-class>
                               org.springframework.web.context.request.RequestContextListener
                         </listener-class>
                    </listener>
                    ...
              </web-app>



            Alternatively,     if   there    are    issues     with    your     listener     setup,    consider      using    Spring’s
            RequestContextFilter.        The    filter   mapping       depends      on   the    surrounding       web     application
            configuration,    so you   have   to change    it  as  appropriate.  The  following    listing shows    the  filter part  of
            a web   application:



              <web-app>
                    ...
                    <filter>
                         <filter-name>requestContextFilter</filter-name>
                         <filter-class>org.springframework.web.filter.RequestContextFilter</filter-
              class>
                    </filter>
                    <filter-mapping>
                         <filter-name>requestContextFilter</filter-name>
                         <url-pattern>/*</url-pattern>
                    </filter-mapping>
                    ...
              </web-app>



            DispatcherServlet,     RequestContextListener,        and   RequestContextFilter       all do  exactly   the  same   thing,
            namely    bind  the  HTTP    request   object  to  the  Thread  that  is servicing   that  request.   This  makes    beans
            that are  request-   and  session-scoped      available   further  down    the  call chain.



            Request  scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="loginAction"       class="com.something.LoginAction"              scope="request"/>



            The  Spring   container    creates   a new   instance   of  the LoginAction     bean   by using   the  loginAction    bean
            definition for each and every HTTP request. That is, the loginAction bean is scoped at the HTTP
            request   level. You  can   change   the  internal   state of  the instance    that is created   as  much   as  you  want,
            because other instances created from the same loginAction bean definition do not see these
            changes in state. They are particular to an individual request. When the request completes
            processing,   the  bean   that is scoped   to  the request   is discarded.


            When    using  annotation-driven       components      or Java  configuration,     the  @RequestScope    annotation     can

            be used   to assign  a  component     to the  request   scope.  The   following   example     shows   how   to do  so:


            Java


              @RequestScope
              @Component
              public    class   LoginAction      {
                    //  ...
              }



            Kotlin


              @RequestScope
              @Component
              class    LoginAction     {
                    //  ...
              }




            Session  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>



            The   Spring     container     creates    a  new     instance    of   the   UserPreferences       bean    by   using    the
            userPreferences bean definition for the lifetime of a single HTTP Session. In other words, the
            userPreferences     bean   is effectively   scoped   at the  HTTP    Session   level. As  with   request-scoped     beans,
            you  can  change    the  internal  state  of the  instance   that  is created   as much    as you   want,   knowing    that
            other  HTTP    Session   instances    that  are  also  using  instances    created   from   the  same    userPreferences
            bean  definition    do not  see  these  changes    in state,  because   they   are particular    to an  individual   HTTP
            Session.  When     the  HTTP   Session   is eventually    discarded,    the  bean   that  is scoped   to  that  particular
            HTTP   Session   is also discarded.


            When using annotation-driven components or Java configuration, you can use the @SessionScope
            annotation    to assign   a component      to the session   scope.


            Java


              @SessionScope
              @Component
              public    class   UserPreferences       {
                    //  ...
              }

            Kotlin


              @SessionScope
              @Component
              class    UserPreferences       {
                    //  ...
              }




            Application  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="appPreferences"        class="com.something.AppPreferences"               scope="application"/>



            The  Spring   container    creates  a  new   instance   of the  AppPreferences     bean   by  using  the  appPreferences
            bean  definition   once   for the  entire  web   application.    That  is, the appPreferences     bean   is scoped   at the
            ServletContext     level  and  stored   as a  regular   ServletContext     attribute.  This  is somewhat      similar   to a
            Spring  singleton    bean  but  differs  in two   important    ways:   It is  a singleton  per ServletContext,     not  per
            Spring   ApplicationContext      (for  which   there   may   be  several   in any   given  web   application),    and   it  is
            actually  exposed    and   therefore   visible  as a ServletContext     attribute.


            When      using     annotation-driven        components         or   Java     configuration,      you     can    use    the
            @ApplicationScope annotation to assign a component to the application scope. The following
            example    shows   how    to do so:


            Java


              @ApplicationScope
              @Component
              public    class   AppPreferences       {
                    //  ...
              }



            Kotlin


              @ApplicationScope
              @Component
              class    AppPreferences      {
                    //  ...
              }




            WebSocket    Scope

            WebSocket     scope   is associated   with   the  lifecycle  of a WebSocket      session  and   applies   to STOMP     over
            WebSocket     applications,   see  WebSocket     scope   for  more   details.

            Scoped  Beans   as Dependencies

            The  Spring   IoC  container     manages     not  only  the  instantiation    of  your   objects  (beans),   but  also  the
            wiring   up  of collaborators     (or dependencies).      If  you want   to inject  (for  example)    an  HTTP    request-
            scoped   bean   into  another    bean   of a  longer-lived    scope,  you   may   choose    to inject  an  AOP   proxy    in
            place  of  the  scoped   bean.   That   is,  you need   to  inject  a proxy    object  that  exposes    the  same   public
            interface as the scoped object but that can also retrieve the real target object from the relevant
            scope  (such   as an  HTTP   request)   and   delegate   method    calls  onto  the  real object.


                              You  may   also  use  <aop:scoped-proxy/>       between    beans   that  are  scoped   as  singleton,
                              with  the  reference    then   going   through    an  intermediate     proxy    that  is serializable
                              and  therefore   able  to  re-obtain   the target  singleton    bean  on  deserialization.


                              When declaring <aop:scoped-proxy/> against a bean of scope prototype, every
                              method    call on  the  shared    proxy   leads   to the  creation   of a  new   target  instance    to
                              which   the  call is  then being  forwarded.

                              Also, scoped    proxies   are  not  the only   way   to access  beans    from   shorter   scopes  in  a
                              lifecycle-safe fashion. You may also declare your injection point (that is, the
                             constructor    or setter  argument     or  autowired    field)  as ObjectFactory<MyTargetBean>,
                              allowing   for  a  getObject()    call to  retrieve   the  current   instance    on  demand     every
                              time  it  is  needed — without    holding    on to  the instance   or  storing  it separately.


                              As an extended variant, you may declare ObjectProvider<MyTargetBean> which
                              delivers    several     additional     access     variants,    including      getIfAvailable      and
                              getIfUnique.


                              The    JSR-330     variant     of   this    is   called    Provider     and     is   used    with     a
                              Provider<MyTargetBean> declaration and a corresponding get() call for every
                              retrieval  attempt.   See  here  for  more   details  on  JSR-330   overall.


            The  configuration     in  the following    example     is only  one   line, but  it is important    to  understand     the
            “why”   as well  as  the “how”    behind   it:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    
                    <bean   id="userPreferences"         class="com.something.UserPreferences"               scope="session">
                         
                         <aop:scoped-proxy/>         ①
                    </bean>


                    
                    <bean   id="userService"       class="com.something.SimpleUserService">
                         
                         <property     name="userPreferences"          ref="userPreferences"/>
                    </bean>
              </beans>


            ① The    line that  defines   the proxy.

            To create   such  a proxy,   you  insert  a child  <aop:scoped-proxy/>       element    into  a scoped   bean   definition
            (see Choosing the Type of Proxy to Create and XML Schema-based configuration). Why do
            definitions   of beans   scoped   at  the request,   session   and  custom-scope      levels  require   the  <aop:scoped-
            proxy/> element? Consider the following singleton bean definition and contrast it with what you
            need to define for the aforementioned scopes (note that the following userPreferences bean
            definition   as it  stands is incomplete):



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            In the  preceding    example,    the  singleton   bean   (userManager)    is injected   with  a  reference   to  the HTTP
            Session-scoped bean (userPreferences). The salient point here is that the userManager bean is a
            singleton:   it  is  instantiated exactly   once   per  container,   and   its dependencies      (in this case   only  one,
            the userPreferences bean) are also injected only once. This means that the userManager bean
            operates   only  on  the  exact  same   userPreferences      object  (that  is,  the  one  with which   it was  originally
            injected).

            This  is not  the  behavior    you   want   when    injecting   a  shorter-lived    scoped    bean   into  a longer-lived
            scoped   bean   (for  example,    injecting   an   HTTP   Session-scoped      collaborating     bean   as  a dependency
            into singleton    bean).  Rather,   you   need   a single  userManager     object,  and,  for  the lifetime   of an  HTTP
            Session,  you   need   a userPreferences      object  that  is specific  to the  HTTP    Session.   Thus,  the  container

            creates  an  object   that  exposes   the  exact   same   public   interface   as  the  UserPreferences     class  (ideally
            an  object  that  is a UserPreferences      instance),   which    can  fetch  the  real  UserPreferences      object  from
            the scoping mechanism (HTTP request, Session, and so forth). The container injects this proxy
            object  into the  userManager    bean,   which   is unaware     that  this UserPreferences     reference    is a proxy.   In
            this  example,     when     a   UserManager     instance     invokes    a   method     on   the   dependency-injected
            UserPreferences     object,  it is actually   invoking    a  method     on  the  proxy.   The  proxy    then  fetches   the
            real UserPreferences object from (in this case) the HTTP Session and delegates the method
            invocation    onto  the  retrieved   real UserPreferences      object.

            Thus, you need the following (correct and complete) configuration when injecting request- and
            session-scoped     beans   into collaborating     objects,  as the  following   example    shows:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session">
                    <aop:scoped-proxy/>
              </bean>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>




            Choosing    the  Type   of  Proxy   to  Create

            By default, when the Spring container creates a proxy for a bean that is marked up with the
            <aop:scoped-proxy/>      element,    a CGLIB-based     class  proxy   is created.


                              CGLIB   proxies   intercept    only  public   method    calls! Do   not  call non-public    methods
                             on such   a proxy.   They  are  not  delegated    to the  actual  scoped   target  object.


            Alternatively, you can configure the Spring container to create standard JDK interface-based
            proxies   for such   scoped   beans,   by  specifying   false   for the  value   of the  proxy-target-class      attribute
            of the  <aop:scoped-proxy/>      element.    Using   JDK  interface-based      proxies   means    that  you  do  not  need
            additional   libraries   in your   application    classpath    to affect  such   proxying.    However,     it also  means
            that the  class  of  the  scoped   bean   must    implement     at  least one   interface   and   that  all collaborators
            into which    the  scoped    bean   is injected   must   reference    the  bean   through    one  of  its interfaces.   The
            following   example    shows    a proxy   based   on  an  interface:



              
              <bean    id="userPreferences"        class="com.stuff.DefaultUserPreferences"                 scope="session">
                    <aop:scoped-proxy        proxy-target-class="false"/>
              </bean>


              <bean    id="userManager"       class="com.stuff.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            For   more    detailed    information      about    choosing     class-based     or  interface-based      proxying,     see
            Proxying    Mechanisms.

            Custom    Scopes

            The bean scoping mechanism is extensible. You can define your own scopes or even redefine
            existing  scopes,   although    the  latter is considered     bad  practice   and   you  cannot    override   the  built-in
            singleton   and   prototype   scopes.



            Creating  a Custom   Scope

            To   integrate    your    custom     scopes    into   the   Spring    container,     you    need    to   implement      the
            org.springframework.beans.factory.config.Scope               interface,  which    is  described  in  this section.  For  an
            idea  of how    to implement     your   own    scopes,  see  the  Scope   implementations       that  are  supplied    with
            the Spring Framework itself and the Scope javadoc, which explains the methods you need to
            implement     in more   detail.


            The  Scope   interface   has  four  methods     to  get objects   from   the  scope,   remove    them    from   the  scope,
            and  let them   be  destroyed.


            The session scope implementation, for example, returns the session-scoped bean (if it does not
            exist, the  method    returns   a new   instance   of  the bean,   after  having   bound    it  to  the  session  for  future
            reference).   The  following    method    returns   the  object  from   the underlying     scope:


            Java


              Object    get(String     name,   ObjectFactory<?>        objectFactory)



            Kotlin


              fun   get(name:     String,    objectFactory:      ObjectFactory<*>):        Any



            The session scope implementation, for example, removes the session-scoped bean from the
            underlying    session.   The   object  should    be  returned,    but  you  can   return   null  if the  object   with  the
            specified  name    is not  found.  The   following   method     removes    the  object  from   the underlying     scope:


            Java


              Object    remove(String      name)



            Kotlin


              fun   remove(name:      String):    Any



            The following method registers a callback that the scope should invoke when it is destroyed or
            when   the  specified   object  in the  scope   is  destroyed:


            Java


              void   registerDestructionCallback(String              name,    Runnable    destructionCallback)

            Kotlin


              fun   registerDestructionCallback(name:              String,    destructionCallback:        Runnable)



            See the  javadoc   or  a Spring   scope   implementation      for  more   information     on  destruction    callbacks.

            The  following   method     obtains   the conversation     identifier   for the  underlying    scope:


            Java


              String    getConversationId()



            Kotlin


              fun   getConversationId():         String



            This  identifier  is different   for  each   scope.  For  a  session   scoped   implementation,       this identifier   can
            be the  session   identifier.



            Using a Custom    Scope

            After  you  write   and   test one  or  more   custom    Scope   implementations,       you  need   to make    the  Spring
            container   aware    of your   new   scopes.   The  following    method    is the  central   method    to register   a new
            Scope  with  the  Spring   container:


            Java


              void   registerScope(String         scopeName,     Scope   scope);



            Kotlin


              fun   registerScope(scopeName:          String,    scope:    Scope)



            This  method     is declared   on   the  ConfigurableBeanFactory        interface,   which    is available   through    the
            BeanFactory property on most of the concrete ApplicationContext implementations that ship with
            Spring.


            The  first argument      to the  registerScope(..)       method    is the  unique    name    associated    with   a  scope.
            Examples of such names in the Spring container itself are singleton and prototype. The second
            argument      to   the   registerScope(..)        method      is   an   actual    instance     of   the   custom      Scope
            implementation      that  you  wish   to register  and   use.

            Suppose that you write your custom Scope implementation, and then register it as shown in the
            next  example.

                              The  next  example     uses  SimpleThreadScope,      which   is included    with  Spring   but  is not
                             registered by default. The instructions would be the same for your own custom
                              Scope  implementations.


            Java


              Scope    threadScope     =  new  SimpleThreadScope();
              beanFactory.registerScope("thread",               threadScope);



            Kotlin


              val   threadScope     =  SimpleThreadScope()
              beanFactory.registerScope("thread",               threadScope)



            You can then create bean definitions that adhere to the scoping rules of your custom Scope, as
            follows:



              <bean    id="..."    class="..."     scope="thread">



            With  a  custom   Scope   implementation,      you  are  not  limited   to programmatic      registration    of the  scope.
            You  can  also  do  the  Scope  registration   declaratively,    by  using  the  CustomScopeConfigurer       class,  as the
            following   example    shows:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    <bean   class="org.springframework.beans.factory.config.CustomScopeConfigurer">
                         <property     name="scopes">
                               <map>
                                    <entry    key="thread">
                                          <bean
              class="org.springframework.context.support.SimpleThreadScope"/>
                                    </entry>
                               </map>
                         </property>
                    </bean>


                    <bean   id="thing2"      class="x.y.Thing2"        scope="thread">
                         <property     name="name"      value="Rick"/>
                         <aop:scoped-proxy/>
                    </bean>


                    <bean   id="thing1"      class="x.y.Thing1">
                         <property     name="thing2"      ref="thing2"/>
                    </bean>


              </beans>




                              When    you  place   <aop:scoped-proxy/>       within   a <bean>   declaration    for a  FactoryBean
                             implementation,      it is the factory   bean   itself that  is scoped,   not  the  object  returned
                              from  getObject().


            2.1.6.   Customizing          the   Nature       of  a Bean

            The  Spring   Framework       provides    a number     of  interfaces   you   can  use  to  customize    the  nature   of  a
            bean.  This  section   groups   them   as follows:

              • Lifecycle   Callbacks

              • ApplicationContextAware        and  BeanNameAware

              • Other   Aware  Interfaces


            Lifecycle   Callbacks

            To  interact  with   the  container’s    management       of  the bean    lifecycle,  you  can   implement     the  Spring
            InitializingBean and DisposableBean interfaces. The container calls afterPropertiesSet() for the

            former   and   destroy()    for the  latter  to let the  bean   perform     certain  actions   upon    initialization  and
            destruction    of your  beans.


                              The  JSR-250   @PostConstruct      and  @PreDestroy     annotations     are  generally   considered
                              best practice   for receiving    lifecycle  callbacks   in a modern     Spring   application.   Using
                              these annotations means that your beans are not coupled to Spring-specific
                             interfaces.  For  details,  see Using   @PostConstruct     and   @PreDestroy.


                              If you do not want to use the JSR-250 annotations but you still want to remove
                              coupling,   consider   init-method    and   destroy-method     bean   definition   metadata.


            Internally,  the  Spring   Framework       uses  BeanPostProcessor       implementations       to process   any   callback
            interfaces it can find and call the appropriate methods. If you need custom features or other
            lifecycle  behavior    Spring  does   not  by default   offer, you   can  implement     a BeanPostProcessor      yourself.
            For more    information,    see  Container    Extension    Points.


            In addition to the initialization and destruction callbacks, Spring-managed objects may also
            implement     the  Lifecycle   interface   so  that those   objects  can  participate    in the  startup  and   shutdown
            process,  as  driven   by the  container’s    own   lifecycle.


            The  lifecycle  callback   interfaces   are  described    in this section.



            Initialization Callbacks

            The     org.springframework.beans.factory.InitializingBean                   interface     lets    a    bean      perform
            initialization    work    after   the   container     has   set   all  necessary     properties     on   the   bean.    The
            InitializingBean     interface   specifies   a single  method:



              void   afterPropertiesSet()         throws    Exception;



            We  recommend       that  you  do  not  use  the InitializingBean      interface,   because   it unnecessarily     couples
            the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a
            POJO   initialization  method.    In  the  case  of XML-based      configuration    metadata,    you   can  use  the  init-
            method attribute to specify the name of the method that has a void no-argument signature. With
            Java  configuration,    you   can  use  the  initMethod    attribute   of @Bean.  See  Receiving    Lifecycle   Callbacks.
            Consider   the  following    example:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            init-method="init"/>



            Java


              public    class   ExampleBean      {


                    public   void   init()    {
                         //  do   some  initialization       work
                    }
              }

            Kotlin


              class    ExampleBean     {


                    fun  init()    {
                         //  do   some  initialization       work
                    }
              }



            The  preceding    example     has  almost   exactly  the  same   effect  as the  following    example    (which   consists
            of two  listings):



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     InitializingBean        {


                    @Override
                    public   void   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            Kotlin


              class    AnotherExampleBean        : InitializingBean        {


                    override    fun   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            However,    the  first of the  two  preceding    examples     does  not  couple   the  code  to Spring.



            Destruction   Callbacks

            Implementing the org.springframework.beans.factory.DisposableBean interface lets a bean get a
            callback   when    the  container    that  contains   it is destroyed.    The   DisposableBean     interface   specifies   a
            single  method:



              void   destroy()     throws    Exception;



            We  recommend       that  you   do  not  use  the DisposableBean      callback   interface,  because    it unnecessarily
            couples   the  code  to Spring.   Alternatively,    we  suggest   using   the @PreDestroy     annotation    or  specifying
            a generic   method     that  is supported     by  bean   definitions.   With   XML-based      configuration     metadata,
            you  can   use  the  destroy-method     attribute   on  the  <bean/>.   With   Java  configuration,     you   can  use  the

            destroyMethod      attribute    of  @Bean.   See    Receiving     Lifecycle    Callbacks.    Consider     the   following
            definition:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            destroy-method="cleanup"/>



            Java


              public    class   ExampleBean      {


                    public   void   cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    ExampleBean     {


                    fun  cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            The  preceding    definition   has  almost   exactly   the same    effect as  the following    definition:



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     DisposableBean       {


                    @Override
                    public   void   destroy()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    AnotherExampleBean        : DisposableBean       {


                    override    fun   destroy()    {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }

            However,    the  first of the  two  preceding    definitions   does   not  couple   the code   to Spring.


                              You  can  assign   the destroy-method     attribute   of a <bean>   element    a special  (inferred)
                              value, which instructs Spring to automatically detect a public close or shutdown
                              method       on     the    specific     bean      class.     (Any     class     that    implements
                              java.lang.AutoCloseable or java.io.Closeable would therefore match.) You can
                             also  set this  special  (inferred)    value   on  the  default-destroy-method        attribute   of  a
                              <beans> element to apply this behavior to an entire set of beans (see Default
                              Initialization  and   Destroy   Methods).    Note   that this  is  the  default behavior   with   Java
                              configuration.



            Default  Initialization and  Destroy  Methods

            When you write initialization and destroy method callbacks that do not use the Spring-specific
            InitializingBean      and  DisposableBean      callback   interfaces,   you   typically   write  methods     with   names
            such as init(), initialize(), dispose(), and so on. Ideally, the names of such lifecycle callback
            methods    are  standardized      across  a  project  so  that  all developers    use   the same    method    names    and
            ensure   consistency.


            You can configure the Spring container to “look” for named initialization and destroy callback
            method names on every bean. This means that you, as an application developer, can write your
            application    classes  and   use  an  initialization   callback   called  init(),   without   having    to configure    an
            init-method="init"      attribute   with  each   bean   definition.   The  Spring    IoC container    calls  that  method
            when   the  bean   is created   (and  in accordance     with   the standard    lifecycle  callback   contract   described
            previously).   This  feature   also enforces    a consistent   naming     convention    for  initialization   and  destroy
            method    callbacks.

            Suppose that your initialization callback methods are named init() and your destroy callback
            methods    are  named    destroy().   Your   class then   resembles    the  class  in the following    example:


            Java


              public    class   DefaultBlogService        implements     BlogService      {


                    private    BlogDao    blogDao;


                    public   void   setBlogDao(BlogDao        blogDao)     {
                         this.blogDao      =  blogDao;
                    }


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    public   void   init()    {
                         if  (this.blogDao       ==  null)   {
                               throw   new   IllegalStateException("The           [blogDao]    property     must   be  set.");
                         }
                    }
              }

            Kotlin


              class    DefaultBlogService        : BlogService      {


                    private    var  blogDao:     BlogDao?    =  null


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    fun  init()    {
                         if  (blogDao     ==  null)   {
                               throw   IllegalStateException("The           [blogDao]     property    must   be  set.")
                         }
                    }
              }



            You  could  then   use  that class  in a bean   resembling     the  following:



              <beans    default-init-method="init">


                    <bean   id="blogService"       class="com.something.DefaultBlogService">
                         <property     name="blogDao"       ref="blogDao"      />
                    </bean>


              </beans>



            The  presence    of the  default-init-method      attribute   on  the  top-level  <beans/>    element   attribute   causes
            the  Spring   IoC  container    to recognize     a method     called  init  on  the  bean    class  as the  initialization
            method    callback.   When    a  bean   is  created  and  assembled,     if the bean    class has   such  a  method,    it  is
            invoked   at the  appropriate     time.


            You can configure destroy method callbacks similarly (in XML, that is) by using the default-
            destroy-method     attribute  on  the  top-level  <beans/>    element.


            Where    existing   bean   classes   already   have   callback    methods    that  are   named    at  variance    with  the
            convention,    you   can  override   the  default   by  specifying   (in  XML,   that  is) the method     name    by using
            the init-method    and   destroy-method     attributes   of the  <bean/>  itself.


            The  Spring   container    guarantees    that  a configured    initialization   callback   is called  immediately     after
            a bean   is supplied   with   all dependencies.     Thus,   the  initialization  callback    is  called on  the raw   bean
            reference,   which   means    that  AOP   interceptors    and   so forth  are  not  yet  applied   to the  bean.  A  target
            bean  is fully  created   first and  then  an  AOP   proxy   (for  example)    with  its interceptor    chain   is  applied.
            If  the  target bean   and  the  proxy    are  defined   separately,   your   code   can  even   interact   with  the  raw
            target  bean,   bypassing    the  proxy.   Hence,   it would    be  inconsistent    to  apply   the  interceptors    to the
            init method, because doing so would couple the lifecycle of the target bean to its proxy or
            interceptors and leave strange semantics when your code interacts directly with the raw target
            bean.

---

### Models/Spring Ai Openai/Src/Test/Resources/Data/Acme/Bikes.Json (models/spring-ai-openai/src/test/resources/data/acme/bikes.json)

[
  {
    "name": "E-Adrenaline 8.0 EX1",
    "shortDescription": "a versatile and comfortable e-MTB designed for adrenaline enthusiasts who want to explore all types of terrain. It features a powerful motor and advanced suspension to provide a smooth and responsive ride, with a variety of customizable settings to fit any rider's needs.",
    "description": "## Overview\r\nIt's right for you if...\r\nYou want to push your limits on challenging trails and terrain, with the added benefit of an electric assist to help you conquer steep climbs and rough terrain. You also want a bike with a comfortable and customizable fit, loaded with high-quality components and technology.\r\n\r\nThe tech you get\r\nA lightweight, full ADV Mountain Carbon frame with a customizable geometry, including an adjustable head tube and chainstay length. A powerful and efficient motor with a 375Wh battery that can assist up to 28 mph when it's on, and provides a smooth and seamless transition when it's off. A SRAM EX1 8-speed drivetrain, a RockShox Lyrik Ultimate fork, and a RockShox Super Deluxe Ultimate rear shock.\r\n\r\nThe final word\r\nOur E-Adrenaline 8.0 EX1 is the perfect bike for adrenaline enthusiasts who want to explore all types of terrain. It's versatile, comfortable, and loaded with advanced technology to provide a smooth and responsive ride, no matter where your adventures take you.\r\n\r\n\r\n## Features\r\nVersatile and customizable\r\nThe E-Adrenaline 8.0 EX1 features a customizable geometry, including an adjustable head tube and chainstay length, so you can fine-tune your ride to fit your needs and preferences. It also features a variety of customizable settings, including suspension tuning, motor assistance levels, and more.\r\n\r\nPowerful and efficient\r\nThe bike is equipped with a powerful and efficient motor that provides a smooth and seamless transition between human power and electric assist. It can assist up to 28 mph when it's on, and provides zero drag when it's off.\r\n\r\nAdvanced suspension\r\nThe E-Adrenaline 8.0 EX1 features a RockShox Lyrik Ultimate fork and a RockShox Super Deluxe Ultimate rear shock, providing advanced suspension technology to absorb shocks and bumps on any terrain. The suspension is also customizable to fit your riding style and preferences.\r\n\r\n\r\n## Specs\r\nFrameset\r\nFrame ADV Mountain Carbon main frame & stays, adjustable head tube and chainstay length, tapered head tube, Knock Block, Control Freak internal routing, Boost148, 150mm travel\r\nFork RockShox Lyrik Ultimate, DebonAir spring, Charger 2.1 RC2 damper, remote lockout, tapered steerer, 42mm offset, Boost110, 15mm Maxle Stealth, 160mm travel\r\nShock RockShox Super Deluxe Ultimate, DebonAir spring, Thru Shaft 3-position damper, 230x57.5mm\r\n\r\nWheels\r\nWheel front Bontrager Line Elite 30, ADV Mountain Carbon, Tubeless Ready, 6-bolt, Boost110, 15mm thru axle\r\nWheel rear Bontrager Line Elite 30, ADV Mountain Carbon, Tubeless Ready, 54T Rapid Drive, 6-bolt, Shimano MicroSpline freehub, Boost148, 12mm thru axle\r\nSkewer rear Bontrager Switch thru axle, removable lever\r\nTire Bontrager XR5 Team Issue, Tubeless Ready, Inner Strength sidewall, aramid bead, 120tpi, 29x2.50''\r\nTire part Bontrager TLR sealant, 6oz\r\n\r\nDrivetrain\r\nShifter SRAM EX1, 8 speed\r\nRear derailleur SRAM EX1, 8 speed\r\nCrank Bosch Performance CX, magnesium motor body, 250 watt, 75 Nm torque\r\nChainring SRAM EX1, 18T, steel\r\nCassette SRAM EX1, 11-48, 8 speed\r\nChain SRAM EX1, 8 speed\r\n\r\nComponents\r\nSaddle Bontrager Arvada, hollow chromoly rails, 138mm width\r\nSeatpost Bontrager Line Elite Dropper, internal routing, 31.6mm\r\nHandlebar Bontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\r\nGrips Bontrager XR Trail Elite, alloy lock-on\r\nStem Bontrager Line Pro, 35mm, Knock Block, Blendr compatible, 0 degree, 50mm length\r\nHeadset Knock Block Integrated, 62-degree radius, cartridge bearing, 1-1\/8'' top, 1.5'' bottom\r\nBrake SRAM G2 RSC hydraulic disc, carbon levers\r\nBrake rotor SRAM Centerline, centerlock, round edge, 200mm\r\n\r\nAccessories\r\nE-bike system Bosch Performance CX, magnesium motor body, 250 watt, 75 Nm torque\r\nBattery Bosch PowerTube 625, 625Wh\r\nCharger Bosch 4A standard charger\r\nController Bosch Kiox with Anti-theft solution, Bluetooth connectivity, 1.9'' display\r\nTool Bontrager Switch thru axle, removable lever\r\n\r\nWeight\r\nWeight M - 20.25 kg \/ 44.6 lbs (with TLR sealant, no tubes)\r\nWeight limit This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\r\n\r\n## Sizing & fit\r\n\r\n| Size |       Rider Height       |        Inseam        |\r\n|:----:|:------------------------:|:--------------------:|\r\n|   S  | 155 - 170 cm 5'1\" - 5'7\" | 73 - 80 cm 29\" - 31.5\" |\r\n|   M  | 163 - 178 cm 5'4\" - 5'10\" | 77 - 83 cm 30.5\" - 32.5\" |\r\n|   L  | 176 - 191 cm 5'9\" - 6'3\" | 83 - 89 cm 32.5\" - 35\" |\r\n|  XL  | 188 - 198 cm 6'2\" - 6'6\" | 88 - 93 cm 34.5\" - 36.5\" |\r\n\r\n\r\n## Geometry\r\n\r\nAll measurements provided in cm unless otherwise noted.\r\nSizing table\r\n| Frame size letter         | S     | M     | L     | XL    |\r\n|---------------------------|-------|-------|-------|-------|\r\n| Actual frame size         | 15.8  | 17.8  | 19.8  | 21.8  |\r\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\r\n| A \u2014 Seat tube             | 40.0  | 42.5  | 47.5  | 51.0  |\r\n| B \u2014 Seat tube angle       | 72.5\u00B0 | 72.8\u00B0 | 73.0\u00B0 | 73.0\u00B0 |\r\n| C \u2014 Head tube length      | 9.5   | 10.5  | 11.0  | 11.5  |\r\n| D \u2014 Head angle            | 67.8\u00B0 | 67.8\u00B0 | 67.8\u00B0 | 67.8\u00B0 |\r\n| E \u2014 Effective top tube    | 59.0  | 62.0  | 65.0  | 68.0  |\r\n| F \u2014 Bottom bracket height | 32.5  | 32.5  | 32.5  | 32.5  |\r\n| G \u2014 Bottom bracket drop   | 5.5   | 5.5   | 5.5   | 5.5   |\r\n| H \u2014 Chainstay length      | 45.0  | 45.0  | 45.0  | 45.0  |\r\n| I \u2014 Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\r\n| J \u2014 Trail                 | 11.0  | 11.0  | 11.0  | 11.0  |\r\n| K \u2014 Wheelbase             | 113.0 | 117.0 | 120.0 | 123.0 |\r\n| L \u2014 Standover             | 77.0  | 77.0  | 77.0  | 77.0  |\r\n| M \u2014 Frame reach           | 41.0  | 44.5  | 47.5  | 50.0  |\r\n| N \u2014 Frame stack           | 61.0  | 62.0  | 62.5  | 63.0  |",
    "price": 1499.99,
    "tags": [
      "bicycle"
    ]
  },
  {
    "name": "Enduro X Pro",
    "shortDescription": "The Enduro X Pro is the ultimate mountain bike for riders who demand the best. With its full carbon frame and top-of-the-line components, this bike is ready to tackle any trail, from technical downhill descents to grueling uphill climbs.",
    "text": "## Overview\nIt's right for you if...\nYou're an experienced mountain biker who wants a high-performance bike that can handle any terrain. You want a bike with the best components available, including a full carbon frame, suspension system, and hydraulic disc brakes.\n\nThe tech you get\nOur top-of-the-line full carbon frame with aggressive geometry and a slack head angle for maximum control. It's equipped with a Fox Factory suspension system with 170mm of travel in the front and 160mm in the rear, a Shimano XTR 12-speed drivetrain, and hydraulic disc brakes for maximum stopping power. The bike also features a dropper seatpost for easy adjustments on the fly.\n\nThe final word\nThe Enduro X Pro is the ultimate mountain bike for riders who demand the best. With its full carbon frame, top-of-the-line components, and aggressive geometry, this bike is ready to take on any trail. Whether you're a seasoned pro or just starting out, the Enduro X Pro will help you take your riding to the next level.\n\n## Features\nFull carbon frame\nAggressive geometry with a slack head angle\nFox Factory suspension system with 170mm of travel in the front and 160mm in the rear\nShimano XTR 12-speed drivetrain\nHydraulic disc brakes for maximum stopping power\nDropper seatpost for easy adjustments on the fly\n\n## Specifications\nFrameset\nFrame\tFull carbon frame\nFork\tFox Factory suspension system with 170mm of travel\nRear suspension\tFox Factory suspension system with 160mm of travel\n\nWheels\nWheel size\t27.5\" or 29\"\nTires\tTubeless-ready Maxxis tires\n\nDrivetrain\nShifters\tShimano XTR 12-speed\nFront derailleur\tN/A\nRear derailleur\tShimano XTR\nCrankset\tShimano XTR\nCassette\tShimano XTR 12-speed\nChain\tShimano XTR\n\nComponents\nBrakes\tHydraulic disc brakes\nHandlebar\tAlloy handlebar\nStem\tAlloy stem\nSeatpost\tDropper seatpost\n\nAccessories\nPedals\tNot included\n\nWeight\nWeight\tApproximately 27-29 lbs\n\n## Sizing\n| Size |        Rider Height       |\n|:----:|:-------------------------:|\n|  S  |  5'4\" - 5'8\" (162-172cm) |\n|  M  |  5'8\" - 5'11\" (172-180cm) |\n|  L  |  5'11\" - 6'3\" (180-191cm) |\n|  XL |  6'3\" - 6'6\" (191-198cm) |\n\n## Geometry\n| Size |        S        |        M       |        L         |        XL       |\n|:----:|:---------------:|:---------------:|:-----------------:|:---------------:|\n| A - Seat tube length |   390mm   |   425mm   |     460mm     |    495mm   |\n| B - Effective top tube length |  585mm  |  610mm  |    635mm     |  660mm |\n| C - Head tube angle |  65.5°  |  65.5°  |  65.5°  |  65.5°  |\n| D - Seat tube angle |  76°  |  76°  |  76°  |  76°  |\n| E - Chainstay length |  435mm  |  435mm  |  435mm  |  435mm  |\n| F - Head tube length |  100mm  |  110mm  |  120mm  |  130mm  |\n| G - BB drop |  20mm  |  20mm  |  20mm  |  20mm  |\n| H - Wheelbase |  1155mm  |  1180mm  |  1205mm  |  1230mm  |\n| I - Standover height |  780mm  |  800mm  |  820mm  |  840mm  |\n| J - Reach |  425mm  |  450mm  |  475mm  |  500mm  |\n| K - Stack |  610mm  |  620mm  |  630mm  |  640mm  |",
    "price": 599.99,
    "tags": [
      "bicycle"
    ]
  },
  {
    "name": "Blaze X1",
    "shortDescription": "Blaze X1 is a high-performance road bike that offers superior speed and agility, making it perfect for competitive racing or fast-paced group rides. The bike features a lightweight carbon frame, aerodynamic tube shapes, a 12-speed Shimano Ultegra drivetrain, and hydraulic disc brakes for precise stopping power. With its sleek design and cutting-edge technology, Blaze X1 is a bike that is built to perform and dominate on any road.",
    "description": "## Overview\nIt's right for you if...\nYou're a competitive road cyclist or an enthusiast who enjoys fast-paced group rides. You want a bike that is lightweight, agile, and delivers exceptional speed.\n\nThe tech you get\nBlaze X1 features a lightweight carbon frame with a tapered head tube and aerodynamic tube shapes for maximum speed and efficiency. The bike is equipped with a 12-speed Shimano Ultegra drivetrain for smooth and precise shifting, Shimano hydraulic disc brakes for powerful and reliable stopping power, and Bontrager Aeolus Elite 35 carbon wheels for increased speed and agility.\n\nThe final word\nBlaze X1 is a high-performance road bike that is designed to deliver exceptional speed and agility. With its cutting-edge technology and top-of-the-line components, it's a bike that is built to perform and dominate on any road.\n\n## Features\nSpeed and efficiency\nBlaze X1's lightweight carbon frame and aerodynamic tube shapes offer maximum speed and efficiency, allowing you to ride faster and farther with ease.\n\nPrecision stopping power\nShimano hydraulic disc brakes provide precise and reliable stopping power, even in wet or muddy conditions.\n\nAgility and control\nBontrager Aeolus Elite 35 carbon wheels make Blaze X1 incredibly agile and responsive, allowing you to navigate tight turns and corners with ease.\n\nSmooth and precise shifting\nThe 12-speed Shimano Ultegra drivetrain offers smooth and precise shifting, so you can easily find the right gear for any terrain.\n\n## Specifications\nFrameset\nFrame\tADV Carbon, tapered head tube, BB90, direct mount rim brakes, internal cable routing, DuoTrap S compatible, 130x9mm QR\nFork\tADV Carbon, tapered steerer, direct mount rim brakes, internal brake routing, 100x9mm QR\n\nWheels\nWheel front\tBontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, 100x9mm QR\nWheel rear\tBontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, Shimano 11-speed freehub, 130x9mm QR\nTire front\tBontrager R3 Hard-Case Lite, aramid bead, 120 tpi, 700x25c\nTire rear\tBontrager R3 Hard-Case Lite, aramid bead, 120 tpi, 700x25c\nMax tire size\t25c Bontrager tires (with at least 4mm of clearance to frame)\n\nDrivetrain\nShifter\tShimano Ultegra R8020, 12 speed\nFront derailleur\tShimano Ultegra R8000, braze-on\nRear derailleur\tShimano Ultegra R8000, short cage, 30T max cog\nCrank\tSize: 50, 52, 54\nShimano Ultegra R8000, 50/34 (compact), 170mm length\nSize: 56, 58, 60, 62\nShimano Ultegra R8000, 50/34 (compact), 172.5mm length\nBottom bracket\tBB90, Shimano press-fit\nCassette\tShimano Ultegra R8000, 11-30, 12 speed\nChain\tShimano Ultegra HG701, 12 speed\n\nComponents\nSaddle\tBontrager Montrose Elite, titanium rails, 138mm width\nSeatpost\tBontrager carbon seatmast cap, 20mm offset\nHandlebar\tBontrager Elite Aero VR-CF, alloy, 31.8mm, internal cable routing, 40cm width\nGrips\tBontrager Supertack Perf tape\nStem\tBontrager Elite, 31.8mm, Blendr-compatible, 7 degree, 80mm length\nBrake Shimano Ultegra hydraulic disc brake\n\nWeight\nWeight\t56 - 8.91 kg / 19.63 lbs (with tubes)\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size | Rider height |\n|------|-------------|\n| 50   | 162-166cm   |\n| 52   | 165-170cm   |\n| 54   | 168-174cm   |\n| 56   | 174-180cm   |\n| 58   | 179-184cm   |\n| 60   | 184-189cm   |\n| 62   | 189-196cm   |\n\n## Geometry\n| Frame size | 50cm | 52cm | 54cm | 56cm | 58cm | 60cm | 62cm |\n|------------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A - Seat tube | 443mm | 460mm | 478mm | 500mm | 520mm | 540mm | 560mm |\n| B - Seat tube angle | 74.1° | 73.9° | 73.7° | 73.4° | 73.2° | 73.0° | 72.8° |\n| C - Head tube length | 100mm | 110mm | 130mm | 150mm | 170mm | 190mm | 210mm |\n| D - Head angle | 71.4° | 72.0° | 72.5° | 73.0° | 73.3° | 73.6° | 73.8° |\n| E - Effective top tube | 522mm | 535mm | 547mm | 562mm | 577mm | 593mm | 610mm |\n| F - Bottom bracket height | 268mm | 268mm | 268mm | 268mm | 268mm | 268mm | 268mm |\n| G - Bottom bracket drop | 69mm | 69mm | 69mm | 69mm | 69mm | 69mm | 69mm |\n| H - Chainstay length | 410mm | 410mm | 410mm | 410mm | 410mm | 410mm | 410mm |\n| I - Offset | 50mm | 50mm | 50mm | 50mm | 50mm | 50mm | 50mm |\n| J - Trail | 65mm | 62mm | 59mm | 56mm | 55mm | 53mm | 52mm |\n| K - Wheelbase | 983mm | 983mm | 990mm | 1005mm | 1019mm | 1036mm | 1055mm |\n| L - Standover | 741mm | 765mm | 787mm | 806mm | 825mm | 847mm | 869mm |",
    "price": 799.99,
    "tags": [
      "bicycle",
      "mountain bike"
    ]
  },
  {
    "name": "Celerity X5",
    "shortDescription": "Celerity X5 is a versatile and reliable road bike that is designed for experienced and amateur riders alike. It's designed to provide smooth and comfortable rides over long distances. With an ultra-lightweight and responsive carbon fiber frame, Shimano 105 groupset, hydraulic disc brakes, and 28mm wide tires, this bike ensures efficient power transfer, precise handling, and superior stopping power.",
    "description": "## Overview\n\nIt's right for you if...    \nYou are looking for a high-performance road bike that offers a perfect balance of speed, comfort, and control. You enjoy long-distance rides and need a bike that is designed to handle various road conditions with ease. You also appreciate the latest technology and reliable components that make your riding experience more enjoyable.\n\nThe tech you get    \nCelerity X5 is equipped with a full carbon fiber frame that ensures maximum strength and durability while keeping the weight down. It features a Shimano 105 groupset with 11-speed gearing for precise and efficient shifting. Hydraulic disc brakes offer superior stopping power, and 28mm wide tires provide comfort and stability on various road surfaces. Internal cable routing enhances the bike's sleek appearance.\n\nThe final word    \nIf you are looking for a high-performance road bike that offers comfort, speed, and control, Celerity X5 is the perfect choice. With its lightweight carbon fiber frame, reliable components, and advanced technology, this bike is designed to help you enjoy long-distance rides with ease.\n\n## Features    \n\nLightweight and responsive    \nCelerity X5 comes with a full carbon fiber frame that is not only lightweight but also responsive, providing excellent handling and control.\n\nHydraulic disc brakes    \nThis bike is equipped with hydraulic disc brakes that provide superior stopping power in all weather conditions, ensuring your safety and confidence on the road.\n\nComfortable rides    \nThe 28mm wide tires and carbon seat post provide ample cushioning, ensuring a smooth and comfortable ride over long distances.\n\nSleek appearance    \nThe bike's internal cable routing enhances its sleek appearance while also protecting the cables from the elements, ensuring smooth shifting for longer periods.\n\n## Specifications    \n\nFrameset    \nFrame\tCelerity X5 Full Carbon Fiber Frame, Internal Cable Routing, Tapered Headtube, Press Fit Bottom Bracket, 12x142mm Thru-Axle    \nFork\tCelerity X5 Full Carbon Fiber Fork, Internal Brake Routing, 12x100mm Thru-Axle    \n\nWheels    \nWheelset\tAlexRims CXD7 Wheelset    \nTire\tSchwalbe Durano Plus 700x28mm    \nInner Tubes\tSchwalbe SV15 700x18-28mm    \nSkewers\tCelerity X5 Thru-Axle Skewers    \n\nDrivetrain    \nShifter\tShimano 105 R7025 Hydraulic Disc Shifters    \nFront Derailleur\tShimano 105 R7000    \nRear Derailleur\tShimano 105 R7000    \nCrankset\tShimano 105 R7000 50-34T    \nBottom Bracket\tShimano BB72-41B    \nCassette\tShimano 105 R7000 11-30T    \nChain\tShimano HG601 11-Speed Chain    \n\nComponents    \nSaddle\tSelle Royal Asphalt Saddle    \nSeatpost\tCelerity X5 Carbon Seatpost    \nHandlebar\tCelerity X5 Compact Handlebar    \nStem\tCelerity X5 Aluminum Stem    \nHeadset\tFSA Orbit IS-2    \n\nBrakes    \nBrakes\tShimano 105 R7025 Hydraulic Disc Brakes    \nRotors\tShimano SM-RT70 160mm Rotors    \n\nAccessories    \nPedals\tCelerity X5 Road Pedals    \n\nWeight    \nWeight\t8.2 kg / 18.1 lbs    \nWeight Limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 120 kg (265 lbs).\n\n## Sizing    \n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  49  |  155 - 162 cm 5'1\" - 5'4\" | 71 - 76 cm 28\" - 30\" |\n|  52  |  162 - 170 cm 5'4\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|  54  |  170 - 178 cm 5'7\" - 5'10\" | 77 - 83 cm 30\" - 32\" |\n|  56  |  178 - 185 cm 5'10\" - 6'1\" | 82 - 88 cm 32\" - 34\" |\n|  58  |  185 - 193 cm 6'1\" - 6'4\" | 86 - 92 cm 34\" - 36\" |\n|  61  |  193 - 200 cm 6'4\" - 6'7\" | 90 - 95 cm 35\" - 37\" |\n\n## Geometry    \n| Frame size number                     | 49 cm | 52 cm | 54 cm | 56 cm | 58 cm | 61 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 47.5  | 50.0  | 52.0  | 54.0  | 56.0  | 58.5  |\n| B — Seat tube angle                   | 75.0° | 74.5° | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length                  | 12.0  | 14.5  | 16.5  | 18.5  | 20.5  | 23.5  |\n| D — Head angle                        | 70.0° | 71.0° | 71.5° | 72.0° | 72.5° | 72.5° |\n| E — Effective top tube                | 52.5  | 53.5  | 54.5  | 56.0  | 57.5  | 59.5  |\n| G — Bottom bracket drop               | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length                  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  |\n| K — Wheelbase                         | 98.4  | 98.9  | 99.8  | 100.8 | 101.7 | 103.6 |\n| L — Standover                         | 72.0  | 74.0  | 76.0  | 78.0  | 80.0  | 82.0  |\n| M — Frame reach                       | 36.2  | 36.8  | 37.3  | 38.1  | 38.6  | 39.4  |\n| N — Frame stack                       | 52.0  | 54.3  | 56.2  | 58.1  | 59.8  | 62.4  |\n| Saddle rail height min                | 67.0  | 69.5  | 71.5  | 74.0  | 76.0  | 78.0  |\n| Saddle rail height max                | 75.0  | 77.5  | 79.5  | 82.0  | 84.0  | 86.0  |",
    "price": 399.99,
    "tags": [
      "bicycle",
      "city bike"
    ]
  },
  {
    "name": "Velocity V8",
    "shortDescription": "Velocity V8 is a high-performance road bike that is designed to deliver speed, agility, and control on the road. With its lightweight aluminum frame, carbon fiber fork, Shimano Tiagra groupset, and hydraulic disc brakes, this bike is perfect for experienced riders who are looking for a fast and responsive bike that can handle various road conditions.",
    "description": "## Overview\n\nIt's right for you if...    \nYou are an experienced rider who is looking for a high-performance road bike that is lightweight, agile, and responsive. You want a bike that can handle long-distance rides, steep climbs, and fast descents with ease. You also appreciate the latest technology and reliable components that make your riding experience more enjoyable.\n\nThe tech you get    \nVelocity V8 features a lightweight aluminum frame with a carbon fiber fork that ensures a comfortable ride without sacrificing stiffness and power transfer. It comes with a Shimano Tiagra groupset with 10-speed gearing for precise and efficient shifting. Hydraulic disc brakes offer superior stopping power in all weather conditions, while 28mm wide tires provide comfort and stability on various road surfaces. Internal cable routing enhances the bike's sleek appearance.\n\nThe final word    \nIf you are looking for a high-performance road bike that is lightweight, fast, and responsive, Velocity V8 is the perfect choice. With its lightweight aluminum frame, reliable components, and advanced technology, this bike is designed to help you enjoy fast and comfortable rides on the road.\n\n## Features    \n\nLightweight and responsive    \nVelocity V8 comes with a lightweight aluminum frame that is not only lightweight but also responsive, providing excellent handling and control.\n\nHydraulic disc brakes    \nThis bike is equipped with hydraulic disc brakes that provide superior stopping power in all weather conditions, ensuring your safety and confidence on the road.\n\nComfortable rides    \nThe 28mm wide tires and carbon fork provide ample cushioning, ensuring a smooth and comfortable ride over long distances.\n\nSleek appearance    \nThe bike's internal cable routing enhances its sleek appearance while also protecting the cables from the elements, ensuring smooth shifting for longer periods.\n\n## Specifications    \n\nFrameset    \nFrame\tVelocity V8 Aluminum Frame, Internal Cable Routing, Tapered Headtube, Press Fit Bottom Bracket, 12x142mm Thru-Axle    \nFork\tVelocity V8 Carbon Fiber Fork, Internal Brake Routing, 12x100mm Thru-Axle    \n\nWheels    \nWheelset\tAlexRims CXD7 Wheelset    \nTire\tSchwalbe Durano Plus 700x28mm    \nInner Tubes\tSchwalbe SV15 700x18-28mm    \nSkewers\tVelocity V8 Thru-Axle Skewers    \n\nDrivetrain    \nShifter\tShimano Tiagra Hydraulic Disc Shifters    \nFront Derailleur\tShimano Tiagra    \nRear Derailleur\tShimano Tiagra    \nCrankset\tShimano Tiagra 50-34T    \nBottom Bracket\tShimano BB-RS500-PB    \nCassette\tShimano Tiagra 11-32T    \nChain\tShimano HG54 10-Speed Chain    \n\nComponents    \nSaddle\tVelocity V8 Saddle    \nSeatpost\tVelocity V8 Aluminum Seatpost    \nHandlebar\tVelocity V8 Compact Handlebar    \nStem\tVelocity V8 Aluminum Stem    \nHeadset\tFSA Orbit IS-2    \n\nBrakes    \nBrakes\tShimano Tiagra Hydraulic Disc Brakes    \nRotors\tShimano SM-RT64 160mm Rotors    \n\nAccessories    \nPedals\tVelocity V8 Road Pedals    \n\nWeight    \nWeight\t9.4 kg / 20.7 lbs    \nWeight Limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 120 kg (265 lbs).\n\n## Sizing    \n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  49  |  155 - 162 cm 5'1\" - 5'4\" | 71 - 76 cm 28\" - 30\" |\n|  52  |  162 - 170 cm 5'4\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|  54  |  170 - 178 cm 5'7\" - 5'10\" | 77 - 83 cm 30\" - 32\" |\n|  56  |  178 - 185 cm 5'10\" - 6'1\" | 82 - 88 cm 32\" - 34\" |\n|  58  |  185 - 193 cm 6'1\" - 6'4\" | 86 - 92 cm 34\" - 36\" |\n|  61  |  193 - 200 cm 6'4\" - 6'7\" | 90 - 95 cm 35\" - 37\" |\n\n## Geometry    \n| Frame size number                     | 49 cm | 52 cm | 54 cm | 56 cm | 58 cm | 61 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 47.5  | 50.0  | 52.0  | 54.0  | 56.0  | 58.5  |\n| B — Seat tube angle                   | 75.0° | 74.5° | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length                  | 12.0  | 14.5  | 16.5  | 18.5  | 20.5  | 23.5  |\n| D — Head angle                        | 70.0° | 71.0° | 71.5° | 72.0° | 72.5° | 72.5° |\n| E — Effective top tube                | 52.5  | 53.5  | 54.5  | 56.0  | 57.5  | 59.5  |\n| G — Bottom bracket drop               | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length                  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  |\n| K — Wheelbase                         | 98.4  | 98.9  | 99.8  | 100.8 | 101.7 | 103.6 |\n| L — Standover                         | 72.0  | 74.0  | 76.0  | 78.0  | 80.0  | 82.0  |\n| M — Frame reach                       | 36.2  | 36.8  | 37.3  | 38.1  | 38.6  | 39.4  |\n| N — Frame stack                       | 52.0  | 54.3  | 56.2  | 58.1  | 59.8  | 62.4  |\n| Saddle rail height min                | 67.0  | 69.5  | 71.5  | 74.0  | 76.0  | 78.0  |\n| Saddle rail height max                | 75.0  | 77.5  | 79.5  | 82.0  | 84.0  | 86.0  |",
    "price": 1899.99,
    "tags": [
      "bicycle",
      "electric bike"
    ]
  },
  {
    "name": "VeloCore X9 eMTB",
    "shortDescription": "The VeloCore X9 eMTB is a light, agile and versatile electric mountain bike designed for adventure and performance. Its purpose-built frame and premium components offer an exhilarating ride experience on both technical terrain and smooth singletrack.",
    "description": "## Overview\nIt's right for you if...\nYou love exploring new trails and testing your limits on challenging terrain. You want an electric mountain bike that offers power when you need it, without sacrificing performance or agility. You're looking for a high-quality bike with top-notch components and a sleek design.\n\nThe tech you get\nA lightweight, full carbon frame with custom geometry, a 140mm RockShox Pike Ultimate fork with Charger 2.1 damper, and a Fox Float DPS Performance shock. A Shimano STEPS E8000 motor and 504Wh battery that provide up to 62 miles of range and 20 mph assistance. A Shimano XT 12-speed drivetrain, Shimano SLX brakes, and DT Swiss wheels.\n\nThe final word\nThe VeloCore X9 eMTB delivers power and agility in equal measure. It's a versatile and capable electric mountain bike that can handle any trail with ease. With premium components, a custom carbon frame, and a sleek design, this bike is built for adventure.\n\n## Features\nAgile and responsive\n\nThe VeloCore X9 eMTB is designed to be nimble and responsive on the trail. Its custom carbon frame offers a perfect balance of stiffness and compliance, while the suspension system provides smooth and stable performance on technical terrain.\n\nPowerful and efficient\n\nThe Shimano STEPS E8000 motor and 504Wh battery provide up to 62 miles of range and 20 mph assistance. The motor delivers smooth and powerful performance, while the battery offers reliable and consistent power for long rides.\n\nCustomizable ride experience\n\nThe VeloCore X9 eMTB comes with an intuitive and customizable Shimano STEPS display that allows you to adjust the level of assistance, monitor your speed and battery life, and customize your ride experience to suit your needs.\n\nPremium components\n\nThe VeloCore X9 eMTB is equipped with high-end components, including a Shimano XT 12-speed drivetrain, Shimano SLX brakes, and DT Swiss wheels. These components offer reliable and precise performance, allowing you to push your limits with confidence.\n\n## Specs\nFrameset\nFrame\tVeloCore carbon fiber frame, Boost, tapered head tube, internal cable routing, 140mm travel\nFork\tRockShox Pike Ultimate, Charger 2.1 damper, DebonAir spring, 15x110mm Boost Maxle Ultimate, 46mm offset, 140mm travel\nShock\tFox Float DPS Performance, EVOL, 3-position adjust, Kashima Coat, 210x50mm\n\nWheels\nWheel front\tDT Swiss XM1700 Spline, 30mm internal width, 15x110mm Boost axle\nWheel rear\tDT Swiss XM1700 Spline, 30mm internal width, Shimano Microspline driver, 12x148mm Boost axle\nTire front\tMaxxis Minion DHF, 29x2.5\", EXO+ casing, tubeless ready\nTire rear\tMaxxis Minion DHR II, 29x2.4\", EXO+ casing, tubeless ready\n\nDrivetrain\nShifter\tShimano XT M8100, 12-speed\nRear derailleur\tShimano XT M8100, Shadow Plus, long cage, 51T max cog\nCrankset\tShimano STEPS E8000, 165mm length, 34T chainring\nCassette\tShimano XT M8100, 10-51T, 12-speed\nChain\tShimano CN-M8100, 12-speed\nPedals\tNot included\n\nComponents\nSaddle\tBontrager Arvada, hollow chromoly rails\nSeatpost\tDrop Line, internal routing, 31.6mm (15.5: 100mm, 17.5 & 18.5: 125mm, 19.5 & 21.5: 150mm)\nHandlebar\tBontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\nStem\tBontrager Line Pro, 35mm, Knock Block, 0 degree, 50mm length\nGrips\tBontrager XR Trail Elite, alloy lock-on\nHeadset\tIntegrated, sealed cartridge bearing, 1-1/8\" top, 1.5\" bottom\nBrakeset\tShimano SLX M7120, 4-piston hydraulic disc\n\nAccessories\nBattery\tShimano STEPS BT-E8010, 504Wh\nCharger\tShimano STEPS EC-E8004, 4A\nController\tShimano STEPS E8000 display\nBike weight\tM - 22.5 kg / 49.6 lbs (with tubes)\n\n## Sizing & fit\n\n| Size |       Rider Height       |\n|:----:|:------------------------:|\n|   S  | 162 - 170 cm 5'4\" - 5'7\" |\n|   M  | 170 - 178 cm 5'7\" - 5'10\"|\n|   L  | 178 - 186 cm 5'10\" - 6'1\"|\n|  XL  | 186 - 196 cm 6'1\" - 6'5\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\n| Frame size         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| A — Seat tube             | 40.6  | 43.2  | 47.0  | 51.0  |\n| B — Seat tube angle       | 75.0° | 75.0° | 75.0° | 75.0° |\n| C — Head tube length      | 9.6   | 10.6  | 11.6  | 12.6  |\n| D — Head angle            | 66.5° | 66.5° | 66.5° | 66.5° |\n| E — Effective top tube    | 60.4  | 62.6  | 64.8  | 66.9  |\n| F — Bottom bracket height | 33.2  | 33.2  | 33.2  | 33.2  |\n| G — Bottom bracket drop   | 3.0   | 3.0   | 3.0   | 3.0   |\n| H — Chainstay length      | 45.5  | 45.5  | 45.5  | 45.5  |\n| I — Offset                | 4.6   | 4.6   | 4.6   | 4.6   |\n| J — Trail                 | 11.9  | 11.9  | 11.9  | 11.9  |\n| K — Wheelbase             | 117.0 | 119.3 | 121.6 | 123.9 |\n| L — Standover             | 75.9  | 75.9  | 78.6  | 78.6  |\n| M — Frame reach           | 43.6  | 45.6  | 47.6  | 49.6  |\n| N — Frame stack           | 60.5  | 61.5  | 62.4  | 63.4  |",
    "price": 1299.99,
    "tags": [
      "bicycle",
      "touring bike"
    ]
  },
  {
    "name": "Zephyr 8.8 GX Eagle AXS Gen 3",
    "shortDescription": "Zephyr 8.8 GX Eagle AXS is a light and nimble full-suspension mountain bike. It's designed to handle technical terrain with ease and has a smooth and efficient ride feel. The sleek and powerful Bosch Performance Line CX motor and removable Powertube battery provide a boost to your pedaling and give you long-lasting riding time. The bike also features high-end components and advanced technology for an ultimate mountain biking experience.",
    "description": "## Overview\nIt's right for you if...\nYou're an avid mountain biker looking for a high-performance e-MTB that can tackle challenging trails. You want a bike with a powerful motor, efficient suspension, and advanced technology to enhance your riding experience. You also need a bike that's reliable and durable for long-lasting use.\n\nThe tech you get\nA lightweight, full carbon frame with 150mm of rear travel and a 160mm RockShox Pike Ultimate fork with Charger 2.1 RCT3 damper, remote lockout, and DebonAir spring. A Bosch Performance Line CX motor and removable Powertube 625Wh battery that can assist up to 20mph when it's on and gives zero drag when it's off, plus an easy-to-use handlebar-mounted Bosch Purion controller. A SRAM GX Eagle AXS wireless electronic drivetrain, a RockShox Reverb Stealth dropper, and DT Swiss HX1501 Spline One wheels.\n\nThe final word\nZephyr 8.8 GX Eagle AXS is a high-performance e-MTB that's designed to handle technical terrain with ease. With a powerful Bosch motor and long-lasting battery, you can conquer challenging climbs and enjoy long rides. The bike also features high-end components and advanced technology for an ultimate mountain biking experience.\n\n## Features\nPowerful motor\n\nThe Bosch Performance Line CX motor provides a boost to your pedaling and can assist up to 20mph. It has four power modes and a walk-assist function for easy navigation on steep climbs. The motor is also reliable and durable for long-lasting use.\n\nEfficient suspension\n\nZephyr 8.8 has a 150mm of rear travel and a 160mm RockShox Pike Ultimate fork with Charger 2.1 RCT3 damper, remote lockout, and DebonAir spring. The suspension is efficient and responsive, allowing you to handle technical terrain with ease.\n\nRemovable battery\n\nThe Powertube 625Wh battery is removable for easy charging and storage. It provides long-lasting riding time and can be replaced with a spare battery for even longer rides. The battery is also durable and weather-resistant for all-season riding.\n\nAdvanced technology\n\nZephyr 8.8 is equipped with advanced technology, including a Bosch Purion controller for easy motor control, a SRAM GX Eagle AXS wireless electronic drivetrain for precise shifting, and a RockShox Reverb Stealth dropper for adjustable saddle height. The bike also has DT Swiss HX1501 Spline One wheels for reliable performance on any terrain.\n\nCarbon frame\n\nThe full carbon frame is lightweight and durable, providing a smooth and efficient ride. It's also designed with a tapered head tube, internal cable routing, and Boost148 spacing for enhanced stiffness and responsiveness.\n\n## Specs\nFrameset\nFrame\tCarbon main frame & stays, tapered head tube, internal routing, Boost148, 150mm travel\nFork\tRockShox Pike Ultimate, Charger 2.1 RCT3 damper, DebonAir spring, remote lockout, tapered steerer, Boost110, 15mm Maxle Stealth, 160mm travel\nShock\tRockShox Deluxe RT3, DebonAir spring, 205mm x 57.5mm\nMax compatible fork travel\t170mm\n\nWheels\nWheel front\tDT Swiss HX1501 Spline One, Centerlock, 30mm inner width, 110x15mm Boost\nWheel rear\tDT Swiss HX1501 Spline One, Centerlock, 30mm inner width, SRAM XD driver, 148x12mm Boost\nTire\tBontrager XR4 Team Issue, Tubeless Ready, Inner Strength sidewall, aramid bead, 120tpi, 29x2.40''\nMax tire size\t29x2.60\"\n\nDrivetrain\nShifter\tSRAM GX Eagle AXS, wireless, 12 speed\nRear derailleur\tSRAM GX Eagle AXS\nCrank\tBosch Gen 4, 32T\nChainring\tSRAM X-Sync 2, 32T, direct-mount\nCassette\tSRAM PG-1275 Eagle, 10-52, 12 speed\nChain\tSRAM GX Eagle, 12 speed\n\nComponents\nSaddle\tBontrager Arvada, hollow titanium rails, 138mm width\nSeatpost\tRockShox Reverb Stealth, 31.6mm, internal routing, 150mm (S), 170mm (M/L), 200mm (XL)\nHandlebar\tBontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\nGrips\tBontrager XR Trail Elite, alloy lock-on\nStem\tBontrager Line Pro, Knock Block, 35mm, 0 degree, 50mm length\nHeadset\tIntegrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\nBrake\tSRAM Code RSC hydraulic disc, 200mm (front), 180mm (rear)\nBrake rotor\tSRAM CenterLine, centerlock, round edge, 200mm (front), 180mm (rear)\n\nAccessories\nE-bike system\tBosch Performance Line CX\nBattery\tBosch Powertube 625Wh\nCharger\tBosch 4A compact charger\nController\tBosch Purion\nTool\tBontrager multi-tool, integrated storage bag\n\nWeight\nWeight\tM - 24.08 kg / 53.07 lbs (with TLR sealant, no tubes)\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n\n## Sizing & fit\n\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 153 - 162 cm 5'0\" - 5'4\" | 67 - 74 cm 26\" - 29\" |\n|   M  | 161 - 172 cm 5'3\" - 5'8\" | 74 - 79 cm 29\" - 31\" |\n|   L  | 171 - 180 cm 5'7\" - 5'11\" | 79 - 84 cm 31\" - 33\" |\n|  XL  | 179 - 188 cm 5'10\" - 6'2\" | 84 - 89 cm 33\" - 35\" |\n\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 15.5  | 17.5  | 19.5  | 21.5  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.4  | 41.9  | 44.5  | 47.6  |\n| B — Seat tube angle       | 76.1° | 76.1° | 76.1° | 76.1° |\n| C — Head tube length      | 9.6   | 10.5  | 11.5  | 12.5  |\n| D — Head angle            | 65.5° | 65.5° | 65.5° | 65.5° |\n| E — Effective top tube    | 58.6  | 61.3  | 64.0  | 66.7  |\n| F — Bottom bracket height | 34.0  | 34.0  | 34.0  | 34.0  |\n| G — Bottom bracket drop   | 1.0   | 1.0   | 1.0   | 1.0   |\n| H — Chainstay length      | 45.0  | 45.0  | 45.0  | 45.0  |\n| I — Offset                | 4.6   | 4.6   | 4.6   | 4.6   |\n| J — Trail                 | 10.5  | 10.5  | 10.5  | 10.5  |\n| K — Wheelbase             | 119.5 | 122.3 | 125.0 | 127.8 |\n| L — Standover             | 72.7  | 74.7  | 77.6  | 81.0  |\n|",
    "price": 1499.99,
    "tags": [
      "bicycle",
      "electric bike",
      "city bike"
    ]
  },
  {
    "name": "Velo 99 XR1 AXS",
    "shortDescription": "Velo 99 XR1 AXS is a next-generation bike designed for fast-paced adventure seekers and speed enthusiasts. Built for high-performance racing, the bike boasts state-of-the-art technology and premium components. It is the ultimate bike for riders who want to push their limits and get their adrenaline pumping.",
    "description": "## Overview\nIt's right for you if...\nYou are a passionate cyclist looking for a bike that can keep up with your speed, agility, and endurance. You are an adventurer who loves to explore new terrains and challenge yourself on the toughest courses. You want a bike that is lightweight, durable, and packed with the latest technology.\n\nThe tech you get\nA lightweight, full carbon frame with advanced aerodynamics and integrated cable routing for a clean look. A high-performance SRAM XX1 Eagle AXS wireless electronic drivetrain, featuring a 12-speed cassette and a 32T chainring. A RockShox SID Ultimate fork with a remote lockout, 120mm travel, and Charger Race Day damper. A high-end SRAM G2 Ultimate hydraulic disc brake with carbon levers. A FOX Transfer SL dropper post for quick and easy height adjustments. DT Swiss XRC 1501 carbon wheels for superior speed and handling.\n\nThe final word\nVelo 99 XR1 AXS is a premium racing bike that can help you achieve your goals and reach new heights. It is designed for speed, agility, and performance, and it is packed with the latest technology and premium components. If you are a serious cyclist who wants the best, this is the bike for you.\n\n## Features\nAerodynamic design\n\nThe Velo 99 XR1 AXS features a state-of-the-art frame design that reduces drag and improves speed. It has an aerodynamic seatpost, integrated cable routing, and a sleek, streamlined look that sets it apart from other bikes.\n\nWireless electronic drivetrain\n\nThe SRAM XX1 Eagle AXS drivetrain features a wireless electronic system that provides precise, instant shifting and unmatched efficiency. It eliminates the need for cables and makes the bike lighter and faster.\n\nHigh-performance suspension\n\nThe RockShox SID Ultimate fork and Charger Race Day damper provide 120mm of smooth, responsive suspension that can handle any terrain. The fork also has a remote lockout for quick adjustments on the fly.\n\nSuperior braking power\n\nThe SRAM G2 Ultimate hydraulic disc brake system delivers unmatched stopping power and control. It has carbon levers for a lightweight, ergonomic design and precision control.\n\nCarbon wheels\n\nThe DT Swiss XRC 1501 carbon wheels are ultra-lightweight, yet incredibly strong and durable. They provide superior speed and handling, making the bike more agile and responsive.\n\n## Specs\nFrameset\nFrame\tFull carbon frame, integrated cable routing, aerodynamic design, Boost148\nFork\tRockShox SID Ultimate, Charger Race Day damper, remote lockout, tapered steerer, Boost110, 15mm Maxle Stealth, 120mm travel\n\nWheels\nWheel front\tDT Swiss XRC 1501 carbon wheel, Boost110, 15mm thru axle\nWheel rear\tDT Swiss XRC 1501 carbon wheel, SRAM XD driver, Boost148, 12mm thru axle\nTire\tSchwalbe Racing Ray, Performance Line, Addix, 29x2.25\"\nTire part\tSchwalbe Doc Blue Professional, 500ml\nMax tire size\t29x2.3\"\n\nDrivetrain\nShifter\tSRAM Eagle AXS, wireless, 12-speed\nRear derailleur\tSRAM XX1 Eagle AXS\nCrank\tSRAM XX1 Eagle, 32T, carbon\nChainring\tSRAM X-SYNC, 32T, alloy\nCassette\tSRAM Eagle XG-1299, 10-52, 12-speed\nChain\tSRAM XX1 Eagle, 12-speed\nMax chainring size\t1x: 32T\n\nComponents\nSaddle\tBontrager Montrose Elite, carbon rails, 138mm width\nSeatpost\tFOX Transfer SL, 125mm travel, internal routing, 31.6mm\nHandlebar\tBontrager Kovee Pro, ADV Carbon, 35mm, 5mm rise, 720mm width\nGrips\tBontrager XR Endurance Elite\nStem\tBontrager Kovee Pro, 35mm, Blendr compatible, 7 degree, 60mm length\nHeadset\tIntegrated, cartridge bearing, 1-1/8\" top, 1.5\" bottom\nBrake\tSRAM G2 Ultimate hydraulic disc, carbon levers, 180mm rotors\n\nAccessories\nBike computer\tBontrager Trip 300\nTool\tBontrager Flatline Pro pedal wrench, T25 Torx\n\n\n## Sizing & fit\n\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 158 - 168 cm 5'2\" - 5'6\" | 74 - 78 cm 29\" - 31\" |\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 78 - 82 cm 31\" - 32\" |\n|   L  | 173 - 183 cm 5'8\" - 6'0\" | 82 - 86 cm 32\" - 34\" |\n|  XL  | 180 - 193 cm 5'11\" - 6'4\" | 86 - 90 cm 34\" - 35\" |\n\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 15.5  | 17.5  | 19.5  | 21.5  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.9  | 43.0  | 47.0  | 51.0  |\n| B — Seat tube angle       | 74.5° | 74.5° | 74.5° | 74.5° |\n| C — Head tube length      | 9.0   | 10.0  | 11.0  | 12.0  |\n| D — Head angle            | 68.0° | 68.0° | 68.0° | 68.0° |\n| E — Effective top tube    | 57.8  | 59.7  | 61.6  | 63.6  |\n| F — Bottom bracket height | 33.0  | 33.0  | 33.0  | 33.0  |\n| G — Bottom bracket drop   | 5.0   | 5.0   | 5.0   | 5.0   |\n| H — Chainstay length      | 43.0  | 43.0  | 43.0  | 43.0  |\n| I — Offset                | 4.2   | 4.2   | 4.2   | 4.2   |\n| J — Trail                 | 9.7   | 9.7   | 9.7   | 9.7   |\n| K — Wheelbase             | 112.5 | 114.5 | 116.5 | 118.6 |\n| L — Standover             | 75.9  | 77.8  | 81.5  | 84.2  |\n| M — Frame reach           | 41.6  | 43.4  | 45.2  | 47.1  |\n| N — Frame stack           | 58.2  | 58.9  | 59.3  | 59.9  |",
    "price": 1099.99,
    "tags": [
      "bicycle",
      "mountain bike"
    ]
  },
  {
    "name": "AURORA 11S E-MTB",
    "shortDescription": "The AURORA 11S is a powerful and stylish electric mountain bike designed to take you on thrilling off-road adventures. With its sturdy frame and premium components, this bike is built to handle any terrain. It features a high-performance motor, long-lasting battery, and advanced suspension system that guarantee a smooth and comfortable ride.",
    "description": "## Overview\nIt's right for you if...\nYou want a top-of-the-line e-MTB that is both powerful and stylish. You also want a bike that can handle any terrain, from steep climbs to rocky descents. With its advanced features and premium components, the AURORA 11S is designed for serious off-road riders who demand the best.\n\nThe tech you get\nA sturdy aluminum frame with advanced suspension system that provides 120mm of travel. A 750W brushless motor that delivers up to 28mph, and a 48V/14Ah lithium-ion battery that provides up to 60 miles of range on a single charge. An advanced 11-speed Shimano drivetrain with hydraulic disc brakes for precise shifting and reliable stopping power. \n\nThe final word\nThe AURORA 11S is a top-of-the-line e-MTB that delivers exceptional performance and style. Whether you're tackling steep climbs or hitting rocky descents, this bike is built to handle any terrain with ease. With its advanced features and premium components, the AURORA 11S is the perfect choice for serious off-road riders who demand the best.\n\n## Features\nPowerful and efficient\n\nThe AURORA 11S is equipped with a high-performance 750W brushless motor that delivers up to 28mph. The motor is powered by a long-lasting 48V/14Ah lithium-ion battery that provides up to 60 miles of range on a single charge.\n\nAdvanced suspension system\n\nThe bike's advanced suspension system provides 120mm of travel, ensuring a smooth and comfortable ride on any terrain. The front suspension is a Suntour XCR32 Air fork, while the rear suspension is a KS-281 hydraulic shock absorber.\n\nPremium components\n\nThe AURORA 11S features an advanced 11-speed Shimano drivetrain with hydraulic disc brakes. The bike is also equipped with a Tektro HD-E725 hydraulic disc brake system that provides reliable stopping power.\n\nSleek and stylish design\n\nWith its sleek and stylish design, the AURORA 11S is sure to turn heads on the trail. The bike's sturdy aluminum frame is available in a range of colors, including black, blue, and red.\n\n## Specs\nFrameset\nFrame Material: Aluminum\nFrame Size: S, M, L\nFork: Suntour XCR32 Air, 120mm Travel\nShock Absorber: KS-281 Hydraulic Shock Absorber\n\nWheels\nWheel Size: 27.5 inches\nTires: Kenda K1151 Nevegal, 27.5x2.35\nRims: Alloy Double Wall\nSpokes: 32H, Stainless Steel\n\nDrivetrain\nShifters: Shimano SL-M7000\nRear Derailleur: Shimano RD-M8000\nCrankset: Prowheel 42T, Alloy Crank Arm\nCassette: Shimano CS-M7000, 11-42T\nChain: KMC X11EPT\n\nBrakes\nBrake System: Tektro HD-E725 Hydraulic Disc Brake\nBrake Rotors: 180mm Front, 160mm Rear\n\nE-bike system\nMotor: 750W Brushless\nBattery: 48V/14Ah Lithium-Ion\nCharger: 48V/3A Smart Charger\nController: Intelligent Sinusoidal Wave\n\nWeight\nWeight: 59.5 lbs\n\n## Sizing & fit\n| Size | Rider Height | Standover Height |\n|------|-------------|-----------------|\n| S    | 5'2\"-5'6\"   | 28.5\"           |\n| M    | 5'7\"-6'0\"   | 29.5\"           |\n| L    | 6'0\"-6'4\"   | 30.5\"           |\n\n## Geometry\nAll measurements provided in cm.\nSizing table\n| Frame size letter | S   | M   | L   |\n|-------------------|-----|-----|-----|\n| Wheel Size        | 27.5\"| 27.5\"| 27.5\"|\n| Seat tube length  | 44.5| 48.5| 52.5|\n| Head tube angle   | 68° | 68° | 68° |\n| Seat tube angle   | 74.5°| 74.5°| 74.5°|\n| Effective top tube | 57.5| 59.5| 61.5|\n| Head tube length  | 12.0| 12.0| 13.0|\n| Chainstay length  | 45.5| 45.5| 45.5|\n| Bottom bracket height | 30.0| 30.0| 30.0|\n| Wheelbase         | 115.0|116.5|118.5|",
    "price": 1999.99,
    "tags": [
      "bicycle",
      "road bike"
    ]
  },
  {
    "name": "VeloTech V9.5 AXS Gen 3",
    "shortDescription": "VeloTech V9.5 AXS is a sleek and fast carbon bike that combines high-end tech with a comfortable ride. It's designed to provide the ultimate experience for the most serious riders. The bike comes with a lightweight and powerful motor that can be activated when needed, and you get a spec filled with premium parts.",
    "description": "## Overview\nIt's right for you if...\nYou want a bike that is fast, efficient, and delivers an adrenaline-filled experience. You are looking for a bike that is built with cutting-edge technology, and you want a ride that is both comfortable and exciting.\n\nThe tech you get\nA lightweight and durable full carbon frame with a fork that has 100mm of travel. The bike comes with a powerful motor that can deliver up to 20 mph of assistance. The drivetrain is a wireless electronic system that is precise and reliable. The bike is also equipped with hydraulic disc brakes, tubeless-ready wheels, and comfortable grips.\n\nThe final word\nThe VeloTech V9.5 AXS is a high-end bike that delivers an incredible experience for serious riders. It combines the latest technology with a comfortable ride, making it perfect for long rides, tough climbs, and fast descents.\n\n## Features\nFast and efficient\nThe VeloTech V9.5 AXS comes with a powerful motor that can provide up to 20 mph of assistance. The motor is lightweight and efficient, providing a boost when you need it without adding bulk. The bike's battery is removable, allowing you to ride without assistance when you don't need it.\n\nSmart software for the trail\nThe VeloTech V9.5 AXS is equipped with intelligent software that delivers a smooth and responsive ride. The software allows the motor to respond immediately as you start to pedal, delivering more power over a wider cadence range. You can also customize your user settings to suit your preferences.\n\nComfortable ride\nThe VeloTech V9.5 AXS is designed to provide a comfortable ride, even on long rides. The bike's fork has 100mm of travel, providing ample cushioning for rough terrain. The bike's grips are also designed to provide a comfortable and secure grip, even on the most challenging rides.\n\n## Specs\nFrameset\nFrame\tCarbon fiber frame with internal cable routing and Boost148\nFork\t100mm of travel with remote lockout\nShock\tN/A\n\nWheels\nWheel front\tCarbon fiber tubeless-ready wheel\nWheel rear\tCarbon fiber tubeless-ready wheel\nSkewer rear\t12mm thru-axle\nTire\tTubeless-ready tire\nTire part\tTubeless sealant\n\nDrivetrain\nShifter\tWireless electronic shifter\nRear derailleur\tWireless electronic derailleur\nCrank\tCarbon fiber crankset with chainring\nCrank arm\tCarbon fiber crank arm\nChainring\tAlloy chainring\nCassette\t12-speed cassette\nChain\t12-speed chain\n\nComponents\nSaddle\tCarbon fiber saddle\nSeatpost\tCarbon fiber seatpost\nHandlebar\tCarbon fiber handlebar\nGrips\tComfortable and secure grips\nStem\tCarbon fiber stem\nHeadset\tCarbon fiber headset\nBrake\tHydraulic disc brakes\nBrake rotor\tDisc brake rotor\n\nAccessories\nE-bike system\tPowerful motor with removable battery\nBattery\tLithium-ion battery\nCharger\tFast charging adapter\nController\tHandlebar-mounted controller\nTool\tBasic toolkit\n\nWeight\nWeight\tM - 17.5 kg / 38.5 lbs (with tubeless sealant)\n\nWeight limit\nThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing & fit\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 160 - 170 cm 5'3\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|   M  | 170 - 180 cm 5'7\" - 5'11\" | 79 - 84 cm 31\" - 33\" |\n|   L  | 180 - 190 cm 5'11\" - 6'3\" | 84 - 89 cm 33\" - 35\" |\n|  XL  | 190 - 200 cm 6'3\" - 6'7\" | 89 - 94 cm 35\" - 37\" |\n\n## Geometry\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 50.0  | 53.3  | 55.6  | 58.8  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.4  | 43.2  | 48.3  | 53.3  |\n| B — Seat tube angle       | 72.3° | 72.6° | 72.8° | 72.8° |\n| C — Head tube length      | 9.0   | 10.0  | 10.5  | 11.0  |\n| D — Head angle            | 67.5° | 67.5° | 67.5° | 67.5° |\n| E — Effective top tube    | 58.0  | 61.7  | 64.8  | 67.0  |\n| F — Bottom bracket height | 32.3  | 32.3  | 32.3  | 32.3  |\n| G — Bottom bracket drop   | 5.0   | 5.0   | 5.0   | 5.0   |\n| H — Chainstay length      | 44.7  | 44.7  | 44.7  | 44.7  |\n| I — Offset                | 4.2   | 4.2   | 4.2   | 4.2   |\n| J — Trail                 | 10.9  | 10.9  | 10.9  | 10.9  |\n| K — Wheelbase             | 112.6 | 116.5 | 119.7 | 121.9 |\n| L — Standover             | 76.8  | 76.8  | 76.8  | 76.8  |\n| M — Frame reach           | 40.5  | 44.0  | 47.0  | 49.0  |\n| N — Frame stack           | 60.9  | 61.8  | 62.2  | 62.7  |",
    "price": 1699.99,
    "tags": [
      "bicycle",
      "electric bike",
      "city bike"
    ]
  },
  {
    "name": "Axiom D8 E-Mountain Bike",
    "shortDescription": "The Axiom D8 is an electrifying mountain bike that is built for adventure. It boasts a light aluminum frame, a powerful motor and the latest tech to tackle the toughest of terrains. The D8 provides assistance without adding bulk to the bike, giving you the flexibility to ride like a traditional mountain bike or have an extra push when you need it.",
    "description": "## Overview  \nIt's right for you if...  \nYou're looking for an electric mountain bike that can handle a wide variety of terrain, from flowing singletrack to technical descents. You also want a bike that offers a powerful motor that provides assistance without adding bulk to the bike. The D8 is designed to take you anywhere, quickly and comfortably.\n\nThe tech you get  \nA lightweight aluminum frame with 140mm of travel, a Suntour fork with hydraulic lockout, and a reliable and powerful Bafang M400 mid-motor that provides a boost up to 20 mph. The bike features a Shimano Deore drivetrain, hydraulic disc brakes, and a dropper seat post. With the latest tech on-board, the D8 is designed to take you to new heights.\n\nThe final word  \nThe Axiom D8 is an outstanding electric mountain bike that is designed for adventure. It's built with the latest tech and provides the flexibility to ride like a traditional mountain bike or have an extra push when you need it. Whether you're a beginner or an experienced rider, the D8 is the perfect companion for your next adventure.\n\n## Features  \nBuilt for Adventure  \n\nThe D8 features a lightweight aluminum frame that is built to withstand rugged terrain. It comes equipped with 140mm of travel and a Suntour fork that can handle even the toughest of trails. With this bike, you're ready to take on anything the mountain can throw at you.\n\nPowerful Motor  \n\nThe Bafang M400 mid-motor provides reliable and powerful assistance without adding bulk to the bike. You can quickly and easily switch between the different assistance levels to find the perfect balance between range and power.\n\nShimano Deore Drivetrain  \n\nThe Shimano Deore drivetrain is reliable and offers smooth shifting on any terrain. You can easily adjust the gears to match your riding style and maximize your performance on the mountain.\n\nDropper Seat Post  \n\nThe dropper seat post allows you to easily adjust your seat height on the fly, so you can maintain the perfect position for any terrain. With the flick of a switch, you can quickly and easily lower or raise your seat to match the terrain.\n\nHydraulic Disc Brakes  \n\nThe D8 features powerful hydraulic disc brakes that offer reliable stopping power in any weather condition. You can ride with confidence knowing that you have the brakes to stop on a dime.\n\n## Specs  \nFrameset  \nFrame\tAluminum frame with 140mm of travel  \nFork\tSuntour fork with hydraulic lockout, 140mm of travel  \nShock\tN/A  \nMax compatible fork travel\t140mm  \n  \nWheels  \nWheel front\tAlloy wheel  \nWheel rear\tAlloy wheel  \nSkewer rear\tThru axle  \nTire\t29\" x 2.35\"  \nTire part\tN/A  \nMax tire size\t29\" x 2.6\"  \n  \nDrivetrain  \nShifter\tShimano Deore  \nRear derailleur\tShimano Deore  \nCrank\tBafang M400  \nCrank arm\tN/A  \nChainring\tN/A  \nCassette\tShimano Deore  \nChain\tShimano Deore  \nMax chainring size\tN/A  \n  \nComponents  \nSaddle\tAxiom D8 saddle  \nSeatpost\tDropper seat post  \nHandlebar\tAxiom D8 handlebar  \nGrips\tAxiom D8 grips  \nStem\tAxiom D8 stem  \nHeadset\tAxiom D8 headset  \nBrake\tHydraulic disc brakes  \nBrake rotor\t180mm  \n\nAccessories  \nE-bike system\tBafang M400 mid-motor  \nBattery\tLithium-ion battery, 500Wh  \nCharger\tLithium-ion charger  \nController\tBafang M400 controller  \nTool\tN/A  \n  \nWeight  \nWeight\tM - 22 kg / 48.5 lbs  \nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 136 kg (300 lbs).  \n  \n  \n## Sizing & fit  \n  \n| Size |       Rider Height       |        Inseam        |  \n|:----:|:------------------------:|:--------------------:|  \n|   S  | 152 - 165 cm 5'0\" - 5'5\" | 70 - 76 cm 27\" - 30\" |  \n|   M  | 165 - 178 cm 5'5\" - 5'10\" | 76 - 81 cm 30\" - 32\" |  \n|   L  | 178 - 185 cm 5'10\" - 6'1\" | 81 - 86 cm 32\" - 34\" |  \n|  XL  | 185 - 193 cm 6'1\" - 6'4\" | 86 - 91 cm 34\" - 36\" |  \n  \n  \n## Geometry  \n  \nAll measurements provided in cm unless otherwise noted.  \nSizing table  \n| Frame size letter         | S     | M     | L     | XL    |  \n|---------------------------|-------|-------|-------|-------|  \n| Actual frame size         | 41.9  | 46.5  | 50.8  | 55.9  |  \n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |  \n| A — Seat tube             | 42.0  | 46.5  | 51.0  | 56.0  |  \n| B — Seat tube angle       | 74.0° | 74.0° | 74.0° | 74.0° |  \n| C — Head tube length      | 11.0  | 12.0  | 13.0  | 15.0  |  \n| D — Head angle            | 68.0° | 68.0° | 68.0° | 68.0° |  \n| E — Effective top tube    | 57.0  | 60.0  | 62.0  | 65.0  |  \n| F — Bottom bracket height | 33.0  | 33.0  | 33.0  | 33.0  |  \n| G — Bottom bracket drop   | 3.0   | 3.0   | 3.0   | 3.0   |  \n| H — Chainstay length      | 46.0  | 46.0  | 46.0  | 46.0  |  \n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |  \n| J — Trail                 | 10.9  | 10.9  | 10.9  | 10.9  |  \n| K — Wheelbase             | 113.0 | 116.0 | 117.5 | 120.5 |  \n| L — Standover             | 73.5  | 75.5  | 76.5  | 79.5  |  \n| M — Frame reach           | 41.0  | 43.5  | 45.0  | 47.5  |  \n| N — Frame stack           | 60.5  | 61.5  | 62.5  | 64.5  |",
    "price": 1399.99,
    "tags": [
      "bicycle",
      "electric bike",
      "mountain bike"
    ]
  },
  {
    "name": "Velocity X1",
    "shortDescription": "Velocity X1 is a high-performance road bike designed for speed enthusiasts. It features a lightweight yet durable frame, aerodynamic design, and top-quality components, making it the perfect choice for those who want to take their cycling experience to the next level.",
    "description": "## Overview\nIt's right for you if...\nYou're an experienced cyclist looking for a bike that can keep up with your need for speed. You want a bike that's lightweight, aerodynamic, and built to perform, whether you're training for a race or just pushing yourself to go faster.\n\nThe tech you get\nA lightweight aluminum frame with a carbon fork, Shimano Ultegra groupset with a wide range of gearing, hydraulic disc brakes, aerodynamic carbon wheels, and a vibration-absorbing handlebar with ergonomic grips.\n\nThe final word\nVelocity X1 is the ultimate road bike for speed enthusiasts. Its lightweight frame, aerodynamic design, and top-quality components make it the perfect choice for those who want to take their cycling experience to the next level.\n\n\n## Features\n\nAerodynamic design\nVelocity X1 is built with an aerodynamic design to help you go faster with less effort. It features a sleek profile, hidden cables, and a carbon fork that cuts through the wind, reducing drag and increasing speed.\n\nHydraulic disc brakes\nVelocity X1 comes equipped with hydraulic disc brakes, providing excellent stopping power in all weather conditions. They're also low maintenance, with minimal adjustments needed over time.\n\nCarbon wheels\nThe Velocity X1's aerodynamic carbon wheels provide excellent speed and responsiveness, helping you achieve your fastest times yet. They're also lightweight, reducing overall bike weight and making acceleration and handling even easier.\n\nShimano Ultegra groupset\nThe Shimano Ultegra groupset provides smooth shifting and reliable performance, ensuring you get the most out of every ride. With a wide range of gearing options, it's ideal for tackling any terrain, from steep climbs to fast descents.\n\n\n## Specifications\nFrameset\nFrame with Fork\tAluminium frame, internal cable routing, 135x9mm QR\nFork\tCarbon, hidden cable routing, 100x9mm QR\n\nWheels\nWheel front\tCarbon, 30mm deep rim, 23mm width, 100x9mm QR\nWheel rear\tCarbon, 30mm deep rim, 23mm width, 135x9mm QR\nSkewer front\t100x9mm QR\nSkewer rear\t135x9mm QR\nTire\tContinental Grand Prix 5000, 700x25mm, folding bead\nMax tire size\t700x28mm without fenders\n\nDrivetrain\nShifter\tShimano Ultegra R8020, 11 speed\nRear derailleur\tShimano Ultegra R8000, 11 speed\n*Crank\tSize: S, M\nShimano Ultegra R8000, 50/34T, 170mm length\nSize: L, XL\nShimano Ultegra R8000, 50/34T, 175mm length\nBottom bracket\tShimano BB-RS500-PB, PressFit\nCassette\tShimano Ultegra R8000, 11-30T, 11 speed\nChain\tShimano Ultegra HG701, 11 speed\nPedal\tNot included\nMax chainring size\t50/34T\n\nComponents\nSaddle\tBontrager Montrose Comp, steel rails, 138mm width\nSeatpost\tBontrager Comp, 6061 alloy, 27.2mm, 8mm offset, 330mm length\n*Handlebar\tSize: S, M, L\nBontrager Elite Aero VR-CF, alloy, 31.8mm, 93mm reach, 123mm drop, 400mm width\nSize: XL\nBontrager Elite Aero VR-CF, alloy, 31.8mm, 93mm reach, 123mm drop, 420mm width\nGrips\tBontrager Supertack Perf tape\n*Stem\tSize: S, M, L\nBontrager Elite Blendr, 31.8mm clamp, 7 degree, 90mm length\nSize: XL\nBontrager Elite Blendr, 31.8mm clamp, 7 degree, 100mm length\nBrake\tShimano Ultegra R8070 hydraulic disc, flat mount\nBrake rotor\tShimano RT800, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 8.15 kg / 17.97 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|   S  |   162 - 170 cm 5'4\" - 5'7\" | 74 - 78 cm 29\" - 31\" |\n|   M  |   170 - 178 cm 5'7\" - 5'10\" | 77 - 82 cm 30\" - 32\" |\n|   L  |  178 - 186 cm 5'10\" - 6'1\" | 82 - 86 cm 32\" - 34\" |\n|  XL  |  186 - 196 cm 6'1\" - 6'5\" | 87 - 92 cm 34\" - 36\" |\n\n\n## Geometry\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 50.0  | 52.0  | 54.0  | 56.0  |\n| B — Seat tube angle       | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length      | 13.0  | 15.0  | 17.0  | 19.0  |\n| D — Head angle            | 71.0° | 72.0° | 72.0° | 72.5° |\n| E — Effective top tube    | 53.7  | 55.0  | 56.5  | 58.0  |\n| F — Bottom bracket height | 27.5  | 27.5  | 27.5  | 27.5  |\n| G — Bottom bracket drop   | 7.3   | 7.3   | 7.3   | 7.3   |\n| H — Chainstay length      | 41.0  | 41.0  | 41.0  | 41.0  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 6.0   | 6.0   | 6.0   | 5.8   |\n| K — Wheelbase             | 98.2  | 99.1  | 100.1 | 101.0 |\n| L — Standover             | 75.2  | 78.2  | 81.1  | 84.1  |\n| M — Frame reach           | 37.5  | 38.3  | 39.1  | 39.9  |\n| N — Frame stack           | 53.3  | 55.4  | 57.4  | 59.5  |",
    "price": 1799.99,
    "tags": [
      "bicycle",
      "touring bike"
    ]
  },
  {
    "name": "Velocity V9",
    "shortDescription": "Velocity V9 is a high-performance hybrid bike that combines speed and comfort for riders who demand the best of both worlds. The lightweight aluminum frame, along with the carbon fork and seat post, provide optimal stiffness and absorption to tackle any terrain. A 2x Shimano Deore drivetrain, hydraulic disc brakes, and 700c wheels with high-quality tires make it a versatile ride for commuters, fitness riders, and weekend adventurers alike.",
    "description": "## Overview\nIt's right for you if...\nYou want a fast, versatile bike that can handle anything from commuting to weekend adventures. You value comfort as much as speed and performance. You want a reliable and durable bike that will last for years to come.\n\nThe tech you get\nA lightweight aluminum frame with a carbon fork and seat post, a 2x Shimano Deore drivetrain with a wide range of gearing, hydraulic disc brakes, and 700c wheels with high-quality tires. The Velocity V9 is designed for riders who demand both performance and comfort in one package.\n\nThe final word\nThe Velocity V9 is the perfect bike for riders who want speed and performance without sacrificing comfort. The lightweight aluminum frame and carbon components provide optimal stiffness and absorption, while the 2x Shimano Deore drivetrain and hydraulic disc brakes ensure precise shifting and stopping power. Whether you're commuting, hitting the trails, or training for your next race, the Velocity V9 has everything you need to achieve your goals.\n\n## Features\n\n2x drivetrain\nA 2x drivetrain means more versatility and a wider range of gearing options. Whether you're climbing hills or sprinting on the flats, the Velocity V9 has the perfect gear for any situation.\n\nCarbon components\nThe Velocity V9 features a carbon fork and seat post to provide optimal stiffness and absorption. This means you can ride faster and more comfortably over any terrain.\n\nHydraulic disc brakes\nHydraulic disc brakes provide unparalleled stopping power and modulation in any weather condition. You'll feel confident and in control no matter where you ride.\n\n## Specifications\nFrameset\nFrame with Fork\tAluminum frame with carbon fork and seat post, internal cable routing, fender mounts, 135x5mm ThruSkew\nFork\tCarbon fork, hidden fender mounts, flat mount disc, 5x100mm thru-skew\n\nWheels\nWheel front\tDouble wall aluminum rims, 700c, quick release hub\nWheel rear\tDouble wall aluminum rims, 700c, quick release hub\nTire\tKenda Kwick Tendril, puncture resistant, reflective sidewall, 700x32c\nMax tire size\t700x35c without fenders, 700x32c with fenders\n\nDrivetrain\nShifter\tShimano Deore, 10 speed\nFront derailleur\tShimano Deore\nRear derailleur\tShimano Deore\nCrank\tShimano Deore, 46-30T, 170mm (S/M), 175mm (L/XL)\nBottom bracket\tShimano BB52, 68mm, threaded\nCassette\tShimano Deore, 11-36T, 10 speed\nChain\tShimano HG54, 10 speed\nPedal\tWellgo alloy platform\n\nComponents\nSaddle\tVelo VL-2158, steel rails\nSeatpost\tCarbon seat post, 27.2mm\nHandlebar\tAluminum, 31.8mm clamp, 15mm rise, 680mm width\nGrips\tVelo ergonomic grips\nStem\tAluminum, 31.8mm clamp, 7 degree, 90mm length\nBrake\tShimano hydraulic disc, MT200 lever, MT200 caliper\nBrake rotor\tShimano RT56, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 11.5 kg / 25.35 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  |  186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size         | S     | M     | L     | XL    |\n|--------------------|-------|-------|-------|-------|\n| Wheel size         | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube      | 44.0  | 48.0  | 52.0  | 56.0  |\n| B — Seat tube angle | 74.5° | 74.0° | 73.5° | 73.0° |\n| C — Head tube length | 14.5  | 16.0  | 18.0  | 20.0  |\n| D — Head angle       | 71.0° | 71.0° | 71.5° | 71.5° |\n| E — Effective top tube | 56.5  | 57.5  | 58.5  | 59.5  |\n| F — Bottom bracket height | 27.0  | 27.0  | 27.0  | 27.0  |\n| G — Bottom bracket drop | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length | 43.0  | 43.0  | 43.0  | 43.0  |\n| I — Offset | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail | 7.0   | 7.0   | 6.6   | 6.6   |\n| K — Wheelbase | 105.4 | 106.3 | 107.2 | 108.2 |\n| L — Standover | 73.2  | 77.1  | 81.2  | 85.1  |\n| M — Frame reach | 39.0  | 39.8  | 40.4  | 41.3  |\n| N — Frame stack | 57.0  | 58.5  | 60.0  | 61.5  |",
    "price": 2199.99,
    "tags": [
      "bicycle",
      "electric bike",
      "mountain bike"
    ]
  },
  {
    "name": "Aero Pro X",
    "shortDescription": "Aero Pro X is a high-end racing bike designed for serious cyclists who demand speed, agility, and superior performance. The lightweight carbon frame and fork, combined with the aerodynamic design, provide optimal stiffness and efficiency to maximize your speed. The bike features a 2x Shimano Ultegra drivetrain, hydraulic disc brakes, and 700c wheels with high-quality tires. Whether you're competing in a triathlon or climbing steep hills, Aero Pro X delivers exceptional performance and precision handling.",
    "description": "## Overview\nIt's right for you if...\nYou are a competitive cyclist looking for a bike that is designed for racing. You want a bike that delivers exceptional speed, agility, and precision handling. You demand superior performance and reliability from your equipment.\n\nThe tech you get\nA lightweight carbon frame with an aerodynamic design, a carbon fork with hidden fender mounts, a 2x Shimano Ultegra drivetrain with a wide range of gearing, hydraulic disc brakes, and 700c wheels with high-quality tires. Aero Pro X is designed for serious cyclists who demand nothing but the best.\n\nThe final word\nAero Pro X is the ultimate racing bike for serious cyclists. The lightweight carbon frame and aerodynamic design deliver maximum speed and efficiency, while the 2x Shimano Ultegra drivetrain and hydraulic disc brakes ensure precise shifting and stopping power. Whether you're competing in a triathlon or a criterium race, Aero Pro X delivers the performance you need to win.\n\n## Features\n\nAerodynamic design\nThe Aero Pro X features an aerodynamic design that reduces drag and maximizes efficiency. The bike is optimized for speed and agility, so you can ride faster and farther with less effort.\n\nHydraulic disc brakes\nHydraulic disc brakes provide unrivaled stopping power and modulation in any weather condition. You'll feel confident and in control no matter where you ride.\n\nCarbon components\nThe Aero Pro X features a carbon fork with hidden fender mounts to provide optimal stiffness and absorption. This means you can ride faster and more comfortably over any terrain.\n\n## Specifications\nFrameset\nFrame with Fork\tCarbon frame with an aerodynamic design, internal cable routing, 3s chain keeper, 142x12mm thru-axle\nFork\tCarbon fork with hidden fender mounts, flat mount disc, 100x12mm thru-axle\n\nWheels\nWheel front\tDouble wall carbon rims, 700c, thru-axle hub\nWheel rear\tDouble wall carbon rims, 700c, thru-axle hub\nTire\tContinental Grand Prix 5000, folding bead, 700x25c\nMax tire size\t700x28c without fenders, 700x25c with fenders\n\nDrivetrain\nShifter\tShimano Ultegra, 11 speed\nFront derailleur\tShimano Ultegra\nRear derailleur\tShimano Ultegra\nCrank\tShimano Ultegra, 52-36T, 170mm (S), 172.5mm (M), 175mm (L/XL)\nBottom bracket\tShimano BB72, 68mm, PressFit\nCassette\tShimano Ultegra, 11-30T, 11 speed\nChain\tShimano HG701, 11 speed\nPedal\tNot included\n\nComponents\nSaddle\tBontrager Montrose Elite, carbon rails, 138mm width\nSeatpost\tCarbon seat post, 27.2mm, 20mm offset\nHandlebar\tBontrager XXX Aero, carbon, 31.8mm clamp, 75mm reach, 125mm drop\nGrips\tBontrager Supertack Perf tape\nStem\tBontrager Pro, 31.8mm clamp, 7 degree, 90mm length\nBrake\tShimano hydraulic disc, Ultegra lever, Ultegra caliper\nBrake rotor\tShimano RT800, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 8.36 kg / 18.42 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size |        Rider Height       |\n|:----:|:-------------------------:|\n|   S  |  155 - 165 cm 5'1\" - 5'5\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" |\n|  XL  |  186 - 197 cm 6'1\" - 6'6\" |\n\n## Geometry\n| Frame size         | S     | M     | L     | XL    |\n|--------------------|-------|-------|-------|-------|\n| Wheel size         | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube      | 50.6  | 52.4  | 54.3  | 56.2  |\n| B — Seat tube angle | 75.5° | 74.5° | 73.5° | 72.5° |\n| C — Head tube length | 12.0  | 14.0  | 16.0  | 18.0  |\n| D — Head angle       | 72.5° | 73.0° | 73.5° | 74.0° |\n| E — Effective top tube | 53.8  | 55.4  | 57.0  | 58.6  |\n| F — Bottom bracket height | 26.5  | 26.5  | 26.5  | 26.5  |\n| G — Bottom bracket drop | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length | 41.0  | 41.0  | 41.0  | 41.0  |\n| I — Offset | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail | 6.0   | 6.0   | 6.0   | 6.0   |\n| K — Wheelbase | 97.1  | 98.7  | 100.2 | 101.8 |\n| L — Standover | 73.8  | 76.2  | 78.5  | 80.8  |\n| M — Frame reach | 38.8  | 39.5  | 40.2  | 40.9  |\n| N — Frame stack | 52.8  | 54.7  | 56.6  | 58.5  |",
    "price": 1599.99,
    "tags": [
      "bicycle",
      "road bike"
    ]
  },
  {
    "name": "Voltex+ Ultra Lowstep",
    "shortDescription": "Voltex+ Ultra Lowstep is a high-performance electric hybrid bike designed for riders who seek speed, comfort, and reliability during their everyday rides. Equipped with a powerful and efficient Voltex Drive Pro motor and a fully-integrated 600Wh battery, this e-bike allows you to cover longer distances on a single charge. The Voltex+ Ultra Lowstep comes with premium components that prioritize comfort and safety, such as a suspension seatpost, wide and stable tires, and integrated lights.",
    "description": "## Overview\n\nIt's right for you if...\nYou want an e-bike that provides a boost for faster rides and effortless usage. Durability is crucial, and you need a bike with one of the most powerful and efficient motors.\n\nThe tech you get\nA lightweight Delta Carbon Fiber frame with an ultra-lowstep design, a Voltex Drive Pro (350W, 75Nm) motor capable of maintaining speeds up to 30 mph, an extended range 600Wh battery integrated into the frame, and a Voltex Control Panel. Additionally, it features a 12-speed Shimano drivetrain, hydraulic disc brakes for optimal all-weather stopping power, a suspension seatpost, wide puncture-resistant tires for added stability, ergonomic grips, a kickstand, lights, and a cargo rack.\n\nThe final word\nThis bike offers enhanced enjoyment and ease of use on long commutes, leisure rides, and adventures. With its extended-range battery, powerful Voltex motor, user-friendly controller, and a seatpost that smooths out road vibrations, it guarantees an exceptional riding experience.\n\n## Features\n\nUltra-fast assistance\n\nExperience speeds up to 30 mph with the cutting-edge Voltex Drive Pro motor, allowing you to breeze through errands, commutes, and joyrides.\n\n## Specs\n\nFrameset\n- Frame: Delta Carbon Fiber, Removable Integrated Battery (RIB), sleek welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: Voltex Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: Voltex Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: Voltex E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore XT M8100, 12-speed\n- Rear derailleur: Shimano Deore XT M8100, long cage\n- Crank: Voltex alloy, 170mm length\n- Chainring: FSA, 44T, aluminum with guard\n- Cassette: Shimano Deore XT M8100, 10-51, 12-speed\n- Chain: KMC E12 Turbo\n- Pedal: Voltex Urban pedals\n\nComponents\n- Saddle: Voltex Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar: Voltex alloy, 31.8mm, comfort sweep, 620mm width (XS, S, M), 660mm width (L)\n- Grips: Voltex Satellite Elite, alloy lock-on\n- Stem: Voltex alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length (XS, S), 105mm length (M, L)\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT520 hydraulic disc\n- Brake rotor: Shimano RT56, 6-bolt, 180mm (XS, S, M, L), 160mm (XS, S, M, L)\n\nAccessories\n- Battery: Voltex PowerTube 600Wh\n- Charger: Voltex compact 2A, 100-240V\n- Computer: Voltex Control Panel\n- Motor: Voltex Drive Pro, 75Nm, 30mph\n- Light: Voltex Solo for e-bike, taillight (XS, S, M, L), Voltex MR8, 180 lumen, 60 lux, LED, headlight (XS, S, M, L)\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: Voltex-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender: Voltex wide (XS, S, M, L), Voltex plastic (XS, S, M, L)\n\nWeight\n- Weight: M - 20.50 kg / 45.19 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 330 pounds (150 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 38.0  | 43.0  | 48.0  | 53.0  |\n| B — Seat tube angle       | 70.5° | 70.5° | 70.5° | 70.5° |\n| C — Head tube length      | 15.0  | 15.0  | 17.0  | 19.0  |\n| D — Head angle            | 69.2° | 69.2° | 69.2° | 69.2° |\n| E — Effective top tube    | 57.2  | 57.7  | 58.8  | 60.0  |\n| F — Bottom bracket height | 30.3  | 30.3  | 30.3  | 30.3  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.5  | 48.5  | 48.5  | 48.5  |\n| I — Offset                | 5.0   | 5.0   | 5.0   | 5.0   |\n| J — Trail                 | 9.0   | 9.0   | 9.0   | 9.0   |\n| K — Wheelbase             | 111.8 | 112.3 | 113.6 | 114.8 |\n| L — Standover             | 42.3  | 42.3  | 42.3  | 42.3  |\n| M — Frame reach           | 36.0  | 38.0  | 38.0  | 38.0  |\n| N — Frame stack           | 62.0  | 62.0  | 63.9  | 65.8  |\n| Stem length               | 8.0   | 8.5   | 8.5   | 10.5  |\n\nPlease note that the specifications and features listed above are subject to change and may vary based on different models and versions of the Voltex+ Ultra Lowstep bike.",
    "price": 2999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "SwiftRide Hybrid",
    "shortDescription": "SwiftRide Hybrid is a versatile and efficient bike designed for riders who want a smooth and enjoyable ride on various terrains. It incorporates advanced technology and high-quality components to provide a comfortable and reliable cycling experience.",
    "description": "## Overview\n\nIt's right for you if...\nYou are looking for a bike that combines the benefits of an electric bike with the versatility of a hybrid. You value durability, speed, and ease of use.\n\nThe tech you get\nThe SwiftRide Hybrid features a lightweight and durable aluminum frame, making it easy to handle and maneuver. It is equipped with a powerful electric motor that offers a speedy assist, helping you reach speeds of up to 25 mph. The bike comes with a removable and fully-integrated 500Wh battery, providing a long-range capacity for extended rides. It also includes a 10-speed Shimano drivetrain, hydraulic disc brakes for precise stopping power, wide puncture-resistant tires for stability, and integrated lights for enhanced visibility.\n\nThe final word\nThe SwiftRide Hybrid is designed for riders who want a bike that can handle daily commutes, recreational rides, and adventures. With its efficient motor, intuitive controls, and comfortable features, it offers an enjoyable and hassle-free riding experience.\n\n## Features\n\nEfficient electric assist\nExperience the thrill of effortless riding with the powerful electric motor that provides a speedy assist, making your everyday rides faster and more enjoyable.\n\n## Specs\n\nFrameset\n- Frame: Lightweight Aluminum, Removable Integrated Battery (RIB), rack & fender mounts, internal routing, 135x5mm QR\n- Fork: SwiftRide Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: SwiftRide Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: SwiftRide E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: SwiftRide City pedals\n\nComponents\n- Saddle: SwiftRide Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - SwiftRide alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - SwiftRide alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: SwiftRide Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - SwiftRide alloy quill, 31.8mm clamp, adjustable rise, 85mm length\n  - Size: M, L - SwiftRide alloy quill, 31.8mm clamp, adjustable rise, 105mm length\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: SwiftRide PowerTube 500Wh\n- Charger: SwiftRide compact 2A, 100-240V\n- Computer: SwiftRide Purion\n- Motor: SwiftRide Performance Line Sport, 65Nm, 25mph\n- Light:\n  - Size: XS, S, M, L - SwiftRide SOLO for e-bike, taillight\n  - Size: XS, S, M, L - SwiftRide MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: SwiftRide-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - SwiftRide wide\n  - Size: XS, S, M, L - SwiftRide plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm (4'10\" - 5'1\") | 69 - 73 cm (27\" - 29\") |\n|   S  |  155 - 165 cm (5'1\" - 5'5\") | 72 - 78 cm (28\" - 31\") |\n|   M  |  165 - 175 cm (5'5\" - 5'9\") | 77 - 83 cm (30\" - 33\") |\n|   L  |  175 - 186 cm (5'9\" - 6'1\") | 82 - 88 cm (32\" - 35\") |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 3999.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "RoadRunner E-Speed Lowstep",
    "shortDescription": "RoadRunner E-Speed Lowstep is a high-performance electric hybrid designed for riders seeking speed and excitement on their daily rides. It is equipped with a powerful and reliable ThunderBolt drive unit that offers exceptional acceleration. The bike features a fully-integrated 500Wh battery, allowing riders to cover longer distances on a single charge. With its comfortable and safe components, including a suspension seatpost, wide and stable tires, and integrated lights, the RoadRunner E-Speed Lowstep ensures a smooth and enjoyable ride.",
    "description": "## Overview\n\nIt's right for you if...\nYou're looking for an e-bike that provides an extra boost to reach your destination quickly and effortlessly. You prioritize durability and want a bike with one of the fastest motors available.\n\nThe tech you get\nA lightweight and sturdy ThunderBolt aluminum frame with a lowstep geometry. The bike is equipped with a ThunderBolt Performance Sport (250W, 65Nm) drive unit capable of reaching speeds up to 28 mph. It features a long-range 500Wh battery fully integrated into the frame and a ThunderBolt controller. Additionally, the bike has a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThe RoadRunner E-Speed Lowstep is designed to provide enjoyment and ease of use on longer commutes, recreational rides, and adventurous journeys. Its long-range battery, fast ThunderBolt motor, intuitive controller, and road-smoothing suspension seatpost make it the perfect choice for riders seeking both comfort and speed.\n\n## Features\n\nSuper speedy assist\n\nThe ThunderBolt Performance Sport drive unit allows you to accelerate up to 28mph, making errands, commutes, and joyrides a breeze.\n\n## Specs\n\nFrameset\n- Frame: ThunderBolt Smooth Aluminum, Removable Integrated Battery (RIB), sleek welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: RoadRunner Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: ThunderBolt DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: ThunderBolt DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: ThunderBolt Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: ThunderBolt E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: RoadRunner City pedals\n\nComponents\n- Saddle: RoadRunner Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - RoadRunner alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - RoadRunner alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: RoadRunner Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - RoadRunner alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\n  - Size: M, L - RoadRunner alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: ThunderBolt PowerTube 500Wh\n- Charger: ThunderBolt compact 2A, 100-240V\n- Computer: ThunderBolt Purion\n- Motor: ThunderBolt Performance Line Sport, 65Nm, 28mph\n- Light:\n  - Size: XS, S, M, L - ThunderBolt SOLO for e-bike, taillight\n  - Size: XS, S, M, L - ThunderBolt MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: MIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - RoadRunner wide\n  - Size: XS, S, M, L - RoadRunner plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 4999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "Hyperdrive Turbo X1",
    "shortDescription": "Hyperdrive Turbo X1 is a high-performance electric bike designed for riders seeking an exhilarating experience on their daily rides. It features a powerful and efficient Hyperdrive Sport drive unit and a sleek, integrated 500Wh battery for extended range. This e-bike is equipped with top-of-the-line components prioritizing comfort and safety, including a suspension seatpost, wide and stable tires, and integrated lights.",
    "description": "## Overview\n\nIt's right for you if...\nYou crave the thrill of an e-bike that can accelerate rapidly, reaching high speeds effortlessly. You value durability and are looking for a bike that is equipped with one of the fastest motors available.\n\nThe tech you get\nA lightweight Hyper Alloy frame with a lowstep geometry, a Hyperdrive Sport (300W, 70Nm) drive unit capable of maintaining speeds up to 30 mph, a long-range 500Wh battery seamlessly integrated into the frame, and an intuitive Hyper Control controller. Additionally, it features a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for enhanced stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThis bike is designed for riders seeking enjoyment and convenience on longer commutes, recreational rides, and thrilling adventures. With its long-range battery, high-speed motor, user-friendly controller, and smooth-riding suspension seatpost, the Hyperdrive Turbo X1 guarantees an exceptional e-biking experience.\n\n## Features\n\nHyperboost Acceleration\nExperience adrenaline-inducing rides with the powerful Hyperdrive Sport drive unit that enables quick acceleration and effortless cruising through errands, commutes, and joyrides.\n\n## Specs\n\nFrameset\nFrame\tHyper Alloy, Removable Integrated Battery (RIB), seamless welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\nFork\tHyper Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\nMax compatible fork travel\t50mm\n\nWheels\nHub front\tFormula DC-20, alloy, 6-bolt, 5x100mm QR\nSkewer front\t132x5mm QR, ThruSkew\nHub rear\tFormula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\nSkewer rear\t153x5mm bolt-on\nRim\tHyper Connection, double-wall, 32-hole, 20 mm width, Schrader valve\nTire\tHyper E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\nMax tire size\t700x50mm with or without fenders\n\nDrivetrain\nShifter\tShimano Deore M4100, 10 speed\nRear derailleur\tShimano Deore M5120, long cage\nCrank\tProWheel alloy, 170mm length\nChainring\tFSA, 42T, steel w/guard\nCassette\tShimano Deore M4100, 11-42, 10 speed\nChain\tKMC E10\nPedal\tHyper City pedals\n\nComponents\nSaddle\tHyper Boulevard\nSeatpost\tAlloy, suspension, 31.6mm, 300mm length\n*Handlebar\tSize: XS, S, M\nHyper alloy, 31.8mm, comfort sweep, 620mm width\nSize: L\nHyper alloy, 31.8mm, comfort sweep, 660mm width\nGrips\tHyper Satellite Elite, alloy lock-on\n*Stem\tSize: XS, S\nHyper alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\nSize: M, L\nHyper alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\nHeadset\tVP sealed cartridge, 1-1/8'', threaded\nBrake\tShimano MT200 hydraulic disc\n*Brake rotor\tSize: XS, S, M, L\nShimano RT26, 6-bolt,180mm\nSize: XS, S, M, L\nShimano RT26, 6-bolt,160mm\n\nAccessories\nBattery\tHyper PowerTube 500Wh\nCharger\tHyper compact 2A, 100-240V\nComputer\tHyper Control\nMotor\tHyperdrive Sport, 70Nm, 30mph\n*Light\tSize: XS, S, M, L\nSpanninga SOLO for e-bike, taillight\nSize: XS, S, M, L\nHerrmans MR8, 180 lumen, 60 lux, LED, headlight\nKickstand\tAdjustable length rear mount alloy kickstand\nCargo rack\tMIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n*Fender\tSize: XS, S, M, L\nSKS wide\nSize: XS, S, M, L\nSKS plastic\n\nWeight\nWeight\tM - 22.30 kg / 49.17 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 1999.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  },
  {
    "name": "Horizon+ Evo Lowstep",
    "shortDescription": "The Horizon+ Evo Lowstep is a versatile electric hybrid bike designed for riders seeking a thrilling and efficient riding experience on a variety of terrains. With its powerful Bosch Performance Line Sport drive unit and integrated 500Wh battery, this e-bike enables riders to cover long distances with ease. Equipped with features prioritizing comfort and safety, such as a suspension seatpost, stable tires, and integrated lights, the Horizon+ Evo Lowstep is a reliable companion for everyday rides.",
    "description": "## Overview\n\nIt's right for you if...\nYou desire the convenience and speed of an e-bike to enhance your riding, and you want an intuitive and durable bicycle. You prioritize having one of the fastest motors developed by Bosch.\n\nThe tech you get\nA lightweight Alpha Smooth Aluminum frame with a lowstep geometry, a Bosch Performance Line Sport (250W, 65Nm) drive unit capable of sustaining speeds up to 28 mph, a fully encased 500Wh battery integrated into the frame, and a Bosch Purion controller. Additionally, it features a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for improved stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThe Horizon+ Evo Lowstep offers an enjoyable and user-friendly riding experience for longer commutes, recreational rides, and adventures. It boasts an extended range battery, a high-performance Bosch motor, an intuitive controller, and a suspension seatpost for a smooth ride on various road surfaces.\n\n## Features\n\nSuper speedy assist\nExperience effortless cruising through errands, commutes, and joyrides with the new Bosch Performance Sport drive unit, allowing acceleration of up to 28 mph.\n\n## Specs\n\nFrameset\n- Frame: Alpha Platinum Aluminum, Removable Integrated Battery (RIB), smooth welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: Horizon Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Front Hub: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Front Skewer: 132x5mm QR, ThruSkew\n- Rear Hub: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Rear Skewer: 153x5mm bolt-on\n- Rim: Bontrager Connection, double-wall, 32-hole, 20mm width, Schrader valve\n- Tire: Bontrager E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10-speed\n- Rear Derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10-speed\n- Chain: KMC E10\n- Pedal: Bontrager City pedals\n\nComponents\n- Saddle: Bontrager Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - Bontrager alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - Bontrager alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: Bontrager Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - Bontrager alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\n  - Size: M, L - Bontrager alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\n- Headset: VP sealed cartridge, 1-1/8\", threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: Bosch PowerTube 500Wh\n- Charger: Bosch compact 2A, 100-240V\n- Computer: Bosch Purion\n- Motor: Bosch Performance Line Sport, 65Nm, 28mph\n- Light:\n  - Size: XS, S, M, L - Spanninga SOLO for e-bike, taillight\n  - Size: XS, S, M, L - Herrmans MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: MIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - SKS wide\n  - Size: XS, S, M, L - SKS plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 4499.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "FastRider X1",
    "shortDescription": "FastRider X1 is a high-performance e-bike designed for riders seeking speed and long-distance capabilities. Equipped with a powerful motor and a high-capacity battery, the FastRider X1 is perfect for daily commuters and e-bike enthusiasts. It boasts a sleek and functional design, making it a great alternative to car transportation. The bike also features a smartphone controller for easy navigation and entertainment options.",
    "description": "## Overview\nIt's right for you if...\nYou're looking for an e-bike that offers both speed and endurance. The FastRider X1 comes with a high-performance motor and a long-lasting battery, making it ideal for long-distance rides.\n\nThe tech you get\nThe FastRider X1 features a state-of-the-art motor and a spacious battery, ensuring a fast and efficient ride.\n\nThe final word\nWith the powerful motor and long-range battery, the FastRider X1 allows you to cover more distance at higher speeds.\n\n## Features\nConnect Your Ride with the FastRider App\nDownload the FastRider app and transform your smartphone into an on-board computer. Easily dock and charge your phone with the smartphone controller, and use the thumb pad on your handlebar to make calls, listen to music, get turn-by-turn directions, and more. The app also allows you to connect with fitness and health apps, syncing your routes and ride data.\n\nGoodbye, Car. Hello, Extended Range!\nWith the option to add the Range Boost feature, you can attach a second long-range battery to your FastRider X1, doubling the distance and time between charges. This enhancement allows you to ride longer, commute farther, and take on more adventurous routes.\n\nWhat is the range?\nTo estimate the distance you can travel on a single charge, use our range calculator tool. It automatically fills in the variables for this specific bike model and assumes an average rider, but you can adjust the settings to get the most accurate estimate for your needs.\n\n## Specifications\nFrameset\n- Frame: High-performance hydroformed alloy, Removable Integrated Battery, Range Boost-compatible, internal cable routing, Motor Armour, post-mount disc, 135x5 mm QR\n- Fork: FastRider rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru axle, post mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: FastRider sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: FastRider Switch thru axle, removable lever\n- Rear Hub: FastRider alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: FastRider MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: Size: M, L, XL - 14g stainless steel, black\n- Tire: FastRider E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Size: M, L, XL - Shimano Deore M5120, long cage\n- Crank: Size: M - FastRider alloy, 170mm length / Size: L, XL - FastRider alloy, 175mm length\n- Chainring: FastRider 46T narrow/wide alloy, w/alloy guard\n- Cassette: Size: M, L, XL - Shimano Deore M4100, 11-42, 10 speed\n- Chain: Size: M, L, XL - KMC E10 / Size: M, L, XL - KMC X10e\n- Pedal: Size: M, L, XL - FastRider City pedals / Size: M, L, XL - Wellgo C157, boron axle, plastic body / Size: M, L, XL - slip-proof aluminum pedals with reflectors\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: FastRider Commuter Comp\n- Seatpost: FastRider Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Size: M - FastRider alloy, 31.8mm, 15mm rise, 600mm width / Size: L, XL - FastRider alloy, 31.8mm, 15mm rise, 660mm width\n- Grips: FastRider Satellite Elite, alloy lock-on\n- Stem: Size: M - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length / Size: L - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length / Size: XL - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\n- Headset: Size: M, L, XL - FSA IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom / Size: M, L, XL - FSA Integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\n- Battery: FastRider PowerTube 625Wh\n- Charger: FastRider standard 4A, 100-240V\n- Motor: FastRider Performance Speed, 85 Nm, 28 mph / 45 kph\n- Light: Size: M, L, XL - FastRider taillight, 50 lumens / Size: M, L, XL - FastRider headlight, 500 lumens\n- Kickstand: Size: M, L, XL - Rear mount, alloy / Size: M, L, XL - Adjustable length alloy kickstand\n- Cargo rack: FastRider integrated rear rack, aluminum\n- Fender: FastRider custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n\nWeight limit\n- This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         | M     | L     | XL    |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 5499.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "SonicRide 8S",
    "shortDescription": "SonicRide 8S is a high-performance e-bike designed for riders who crave speed and long-distance capabilities. The advanced SonicDrive motor provides powerful assistance up to 28 mph, combined with a durable and long-lasting battery for extended rides. With its sleek design and thoughtful features, the SonicRide 8S is perfect for those who prefer the freedom of riding a bike over driving a car. Plus, it comes equipped with a smartphone controller for easy navigation, music, and more.",
    "description": "## Overview\nIt's right for you if...\nYou want a fast and efficient e-bike that can take you long distances. The SonicRide 8S features a hydroformed aluminum frame with a concealed 625Wh battery, a high-powered SonicDrive motor, and a Smartphone Controller. It also includes essential accessories such as lights, fenders, and a rear rack.\n\nThe tech you get\nThe SonicRide 8S is equipped with the fastest SonicDrive motor, ensuring exhilarating rides at high speeds. The long-range battery is perfect for commuters and riders looking to explore new horizons.\n\nThe final word\nWith the SonicDrive motor and long-lasting battery, you can enjoy extended rides at higher speeds.\n\n## Features\n\nConnect Your Ride with SonicRide App\nDownload the SonicRide app and transform your phone into an onboard computer. Simply attach it to the Smartphone Controller for docking and charging. Use the thumb pad on your handlebar to control calls, music, directions, and more. The Bluetooth® wireless technology allows you to connect with fitness and health apps, syncing your routes and ride data.\n\nSay Goodbye to Limited Range with Range Boost!\nExperience the convenience of Range Boost, an additional long-range 500Wh battery that seamlessly attaches to your bike's down tube. This upgrade allows you to double your distance and time between charges, enabling longer commutes and more adventurous rides. Range Boost is compatible with select SonicRide electric bike models.\n\nWhat is the range?\nFor an accurate estimate of how far you can ride on a single charge, use SonicRide's range calculator. We have pre-filled the variables for this specific bike model and the average rider, but you can adjust them to obtain the most accurate estimate.\n\n## Specifications\nFrameset\n- Frame: High-performance hydroformed alloy, Removable Integrated Battery, Range Boost-compatible, internal cable routing, Motor Armour, post-mount disc, 135x5 mm QR\n- Fork: SonicRide rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru axle, post mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: SonicRide sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: SonicRide Switch thru axle, removable lever\n- Rear Hub: SonicRide alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: SonicRide MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: Size: M, L, XL - 14g stainless steel, black\n- Tire: SonicRide E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear Derailleur: Size: M, L, XL - Shimano Deore M5120, long cage\n- Crank: Size: M - SonicRide alloy, 170mm length; Size: L, XL - SonicRide alloy, 175mm length\n- Chainring: SonicRide 46T narrow/wide alloy, with alloy guard\n- Cassette: Size: M, L, XL - Shimano Deore M4100, 11-42, 10 speed\n- Chain: Size: M, L, XL - KMC E10; Size: M, L, XL - KMC X10e\n- Pedal: Size: M, L, XL - SonicRide City pedals; Size: M, L, XL - Wellgo C157, boron axle, plastic body; Size: M, L, XL - slip-proof aluminum pedals with reflectors\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: SonicRide Commuter Comp\n- Seatpost: SonicRide Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Size: M - SonicRide alloy, 31.8mm, 15mm rise, 600mm width; Size: L, XL - SonicRide alloy, 31.8mm, 15mm rise, 660mm width\n- Grips: SonicRide Satellite Elite, alloy lock-on\n- Stem: Size: M - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length; Size: L - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length; Size: XL - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\n- Headset: Size: M, L, XL - SonicRide IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom; Size: M, L, XL - SonicRide Integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\n- Battery: SonicRide PowerTube 625Wh\n- Charger: SonicRide standard 4A, 100-240V\n- Motor: SonicRide Performance Speed, 85 Nm, 28 mph / 45 kph\n- Light: Size: M, L, XL - SonicRide Lync taillight, 50 lumens; Size: M, L, XL - SonicRide Lync headlight, 500 lumens\n- Kickstand: Size: M, L, XL - Rear mount, alloy; Size: M, L, XL - Adjustable length alloy kickstand\n- Cargo rack: SonicRide integrated rear rack, aluminum\n- Fender: SonicRide custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm / 5'5\" - 5'9\" | 77 - 83 cm / 30\" - 33\" |\n|   L  | 175 - 186 cm / 5'9\" - 6'1\" | 82 - 88 cm / 32\" - 35\" |\n|  XL  | 186 - 197 cm / 6'1\" - 6'6\" | 87 - 93 cm / 34\" - 37\" |\n\n## Geometry\n| Frame size letter         |   M   |   L   |   XL  |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |",
    "price": 5999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "SwiftVolt Pro",
    "shortDescription": "SwiftVolt Pro is a high-performance e-bike designed for riders seeking a thrilling and fast riding experience. Equipped with a powerful SwiftDrive motor that provides assistance up to 30 mph and a long-lasting battery, this bike is perfect for long-distance commuting and passionate e-bike enthusiasts. The sleek and innovative design features cater specifically to individuals who prioritize cycling over driving. Additionally, the bike is seamlessly integrated with your smartphone, allowing you to use it for navigation, music, and more.",
    "description": "## Overview\nThis bike is ideal for you if:\n- You desire a sleek and modern hydroformed aluminum frame that houses a 700Wh battery.\n- You want to maintain high speeds of up to 30 mph with the assistance of the SwiftDrive motor.\n- You appreciate the convenience of using your smartphone as a controller, which can be docked and charged on the handlebar.\n\n## Features\n\nConnect with SwiftSync App\nBy downloading the SwiftSync app, your smartphone becomes an interactive on-board computer. Attach it to the handlebar-mounted controller for easy access and charging. With the thumb pad, you can make calls, listen to music, receive turn-by-turn directions, and connect with fitness and health apps to track your routes and ride data via Bluetooth® wireless technology.\n\nEnhanced Range with BoostMax\nBoostMax offers the capability to attach a second 700Wh Swift battery to the downtube of your bike, effectively doubling the distance and time between charges. This allows for extended rides, longer commutes, and more significant adventures. BoostMax is compatible with select Swift electric bike models.\n\nRange Estimation\nFor an estimate of how far you can ride on a single charge, consult the Swift range calculator. The variables are automatically populated based on this bike model and the average rider, but you can modify them to obtain the most accurate estimate.\n\n## Specifications\nFrameset\n- Frame: Lightweight hydroformed alloy, Removable Integrated Battery, BoostMax-compatible, internal cable routing, post-mount disc, 135x5 mm QR\n- Fork: SwiftVolt rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru-axle, post-mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: Swift sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: Swift Switch thru-axle, removable lever\n- Rear Hub: Swift alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: SwiftRim, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: 14g stainless steel, black\n- Tire: Swift E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear Derailleur: Shimano Deore M5120, long cage\n- Crank: Swift alloy, 170mm length\n- Chainring: Swift 46T narrow/wide alloy, w/alloy guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: Swift City pedals\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: Swift Commuter Comp\n- Seatpost: Swift Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Swift alloy, 31.8mm, 15mm rise, 600mm width (M), 660mm width (L, XL)\n- Grips: Swift Satellite Elite, alloy lock-on\n- Stem: Swift alloy, 31.8mm, Blendr compatible, 7 degree, 70mm length (M), 90mm length (L), 100mm length (XL)\n- Headset: FSA IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brakes: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake Rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max 180mm front & rear\n\nAccessories\n- Battery: Swift PowerTube 700Wh\n- Charger: Swift standard 4A, 100-240V\n- Motor: SwiftDrive, 90 Nm, 30 mph / 48 kph\n- Light: Swift Lync taillight, 50 lumens (M, L, XL), Swift Lync headlight, 500 lumens (M, L, XL)\n- Kickstand: Rear mount, alloy (M, L, XL), Adjustable length alloy kickstand (M, L, XL)\n- Cargo rack: SwiftVolt integrated rear rack, aluminum\n- Fender: Swift custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |     Rider Height      |     Inseam    |\n|:----:|:---------------------:|:-------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         | M     | L     | XL    |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 2499.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  },
  {
    "name": "AgileEon 9X",
    "shortDescription": "AgileEon 9X is a high-performance e-bike designed for riders seeking speed and endurance. Equipped with a robust motor and an extended battery life, this bike is perfect for long-distance commuters and avid e-bike enthusiasts. It boasts innovative features tailored for individuals who prioritize cycling over driving. Additionally, the bike integrates seamlessly with your smartphone, allowing you to access navigation, music, and more.",
    "description": "## Overview\nIt's right for you if...\nYou crave speed and want to cover long distances efficiently. The AgileEon 9X features a sleek hydroformed aluminum frame that houses a powerful motor, along with a large-capacity battery for extended rides. It comes equipped with a 10-speed drivetrain, front and rear lighting, fenders, and a rear rack.\n\nThe tech you get\nDesigned for those constantly on the move, this bike includes a state-of-the-art motor and a high-capacity battery, making it an excellent choice for lengthy commutes.\n\nThe final word\nWith the AgileEon 9X, you can push your boundaries and explore new horizons thanks to its powerful motor and long-lasting battery.\n\n## Features\n\nConnect Your Ride with RideMate App\nMake use of the RideMate app to transform your smartphone into an onboard computer. Simply attach it to the RideMate controller to dock and charge, then utilize the thumb pad on your handlebar to make calls, listen to music, receive turn-by-turn directions, and more. The bike also supports Bluetooth® wireless technology, enabling seamless connectivity with fitness and health apps for route syncing and ride data.\n\nGoodbye, car. Hello, Extended Range!\nEnhance your riding experience with the Extended Range option, which allows for the attachment of an additional high-capacity 500Wh battery to your bike's downtube. This doubles the distance and time between charges, enabling longer rides, extended commutes, and more significant adventures. The Extended Range feature is compatible with select AgileEon electric bike models.\n\nWhat is the range?\nTo determine how far you can ride on a single charge, you can utilize the range calculator provided by AgileEon. We have pre-filled the variables for this specific model and an average rider, but adjustments can be made for a more accurate estimation.\n\n## Specifications\nFrameset\nFrame: High-performance hydroformed alloy, Removable Integrated Battery, Extended Range-compatible, internal cable routing, Motor Armor, post-mount disc, 135x5 mm QR\nFork: AgileEon rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru-axle, post-mount disc brake\nMax compatible fork travel: 63mm\n\nWheels\nFront Hub: AgileEon sealed bearing, 32-hole 15mm alloy thru-axle\nFront Skewer: AgileEon Switch thru-axle, removable lever\nRear Hub: AgileEon alloy, sealed bearing, 6-bolt, 135x5mm QR\nRear Skewer: 148x5mm bolt-on\nRim: AgileEon MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\nSpokes:\n- Size: M, L, XL: 14g stainless steel, black\nTire: AgileEon E6 Hard-Case Lite, reflective strip, 27.5x2.40''\nMax tire size: 27.5x2.40\"\n\nDrivetrain\nShifter: Shimano Deore M4100, 10-speed\nRear derailleur:\n- Size: M, L, XL: Shimano Deore M5120, long cage\nCrank:\n- Size: M: AgileEon alloy, 170mm length\n- Size: L, XL: AgileEon alloy, 175mm length\nChainring: AgileEon 46T narrow/wide alloy, with alloy guard\nCassette:\n- Size: M, L, XL: Shimano Deore M4100, 11-42, 10-speed\nChain:\n- Size: M, L, XL: KMC E10\nPedal:\n- Size: M, L, XL: AgileEon City pedals\nMax chainring size: 1x: 48T\n\nComponents\nSaddle: AgileEon Commuter Comp\nSeatpost: AgileEon Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\nHandlebar:\n- Size: M: AgileEon alloy, 31.8mm, 15mm rise, 600mm width\n- Size: L, XL: AgileEon alloy, 31.8mm, 15mm rise, 660mm width\nGrips: AgileEon Satellite Elite, alloy lock-on\nStem:\n- Size: M: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length\n- Size: L: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length\n- Size: XL: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\nHeadset:\n- Size: M, L, XL: AgileEon IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\nBrake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\nBrake rotor: Shimano RT56, 6-bolt, 180mm\nRotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\nBattery: AgileEon PowerTube 625Wh\nCharger: AgileEon standard 4A, 100-240V\nMotor: AgileEon Performance Speed, 85 Nm, 28 mph / 45 kph\nLight:\n- Size: M, L, XL: AgileEon taillight, 50 lumens\n- Size: M, L, XL: AgileEon headlight, 500 lumens\nKickstand:\n- Size: M, L, XL: Rear mount, alloy\n- Size: M, L, XL: Adjustable length alloy kickstand\nCargo rack: AgileEon integrated rear rack, aluminum\nFender: AgileEon custom aluminum\n\nWeight\nWeight: M - 25.54 kg / 56.3 lbs\nWeight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         |   M   |   L   |   XL  |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 3499.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "Stealth R1X Pro",
    "shortDescription": "Stealth R1X Pro is a high-performance carbon road bike designed for riders who crave speed and exceptional handling. With its aerodynamic tube shaping, disc brakes, and lightweight carbon wheels, the Stealth R1X Pro offers unparalleled performance for competitive road cycling.",
    "description": "## Overview\nIt's right for you if...\nYou're a competitive cyclist looking for a road bike that offers superior performance in terms of speed, handling, and aerodynamics. You want a complete package that includes lightweight carbon wheels, without the need for future upgrades.\n\nThe tech you get\nThe Stealth R1X Pro features a lightweight and aerodynamic carbon frame, an advanced carbon fork, high-performance Shimano Ultegra 11-speed drivetrain, and powerful Ultegra disc brakes. The bike also comes equipped with cutting-edge Bontrager Aeolus Elite 35 carbon wheels.\n\nThe final word\nThe Stealth R1X Pro stands out with its combination of a fast and aerodynamic frame, high-end drivetrain, and top-of-the-line carbon wheels. Whether you're racing on local roads, participating in pro stage races, or engaging in hill climbing competitions, this bike is a formidable choice that delivers an exceptional riding experience.\n\n## Features\nSleek and aerodynamic design\nThe Stealth R1X Pro's aero tube shapes maximize speed and performance, making it faster on climbs and flats alike. The bike also features a streamlined Aeolus RSL bar/stem for improved front-end aerodynamics.\n\nDesigned for all riders\nThe Stealth R1X Pro is designed to provide an outstanding fit for riders of all genders, body types, riding styles, and abilities. It comes equipped with size-specific components to ensure a comfortable and efficient riding position for competitive riders.\n\n## Specifications\nFrameset\n- Frame: Ultralight carbon frame constructed with high-performance 500 Series ADV Carbon. It features Ride Tuned performance tube optimization, a tapered head tube, internal routing, DuoTrap S compatibility, flat mount disc brake mounts, and a 142x12mm thru axle.\n- Fork: Full carbon fork (Émonda SL) with a tapered carbon steerer, internal brake routing, flat mount disc brake mounts, and a 12x100mm thru axle.\n- Frame fit: H1.5 Race geometry.\n\nWheels\n- Front wheel: Bontrager Aeolus Elite 35 carbon wheel with a 35mm rim depth, ADV Carbon construction, Tubeless Ready compatibility, and a 100x12mm thru axle.\n- Rear wheel: Bontrager Aeolus Elite 35 carbon wheel with a 35mm rim depth, ADV Carbon construction, Tubeless Ready compatibility, Shimano 11/12-speed freehub, and a 142x12mm thru axle.\n- Front skewer: Bontrager Switch thru axle with a removable lever.\n- Rear skewer: Bontrager Switch thru axle with a removable lever.\n- Tire: Bontrager R2 Hard-Case Lite with an aramid bead, 60 tpi, and a size of 700x25c.\n- Maximum tire size: 28mm.\n\nDrivetrain\n- Shifter:\n  - Size 47, 50, 52: Shimano Ultegra R8025 with short-reach levers, 11-speed.\n  - Size 54, 56, 58, 60, 62: Shimano Ultegra R8020, 11-speed.\n- Front derailleur: Shimano Ultegra R8000, braze-on.\n- Rear derailleur: Shimano Ultegra R8000, short cage, with a maximum cog size of 30T.\n- Crank:\n  - Size 47: Shimano Ultegra R8000 with 52/36 chainrings and a 165mm length.\n  - Size 50, 52: Shimano Ultegra R8000 with 52/36 chainrings and a 170mm length.\n  - Size 54, 56, 58: Shimano Ultegra R8000 with 52/36 chainrings and a 172.5mm length.\n  - Size 60, 62: Shimano Ultegra R8000 with 52/36 chainrings and a 175mm length.\n- Bottom bracket: Praxis T47 threaded bottom bracket with internal bearings.\n- Cassette: Shimano Ultegra R8000, 11-30, 11-speed.\n- Chain: Shimano Ultegra HG701, 11-speed.\n- Maximum chainring size: 1x - 50T, 2x - 53/39.\n\nComponents\n- Saddle: Bontrager Aeolus Comp with steel rails and a width of 145mm.\n- Seatpost:\n  - Size 47, 50, 52, 54: Bontrager carbon seatmast cap with a 20mm offset and a short length.\n  - Size 56, 58, 60, 62: Bontrager carbon seatmast cap with a 20mm offset and a tall length.\n- Handlebar:\n  - Size 47, 50: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 38cm.\n  - Size 52: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 40cm.\n  - Size 54, 56, 58: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 42cm.\n  - Size 60, 62: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 44cm.\n- Handlebar tape: Bontrager Supertack Perf tape.\n- Stem:\n  - Size 47: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 70mm.\n  - Size 50: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 80mm.\n  - Size 52, 54: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 90mm.\n  - Size 56: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 100mm.\n  - Size 58, 60, 62: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 110mm.\n- Brake: Shimano Ultegra hydraulic disc brakes with flat mount calipers.\n- Brake rotor: Shimano RT800 with centerlock mounting, 160mm diameter.\n\nWeight\n- Weight: 8.03 kg (17.71 lbs) for the 56cm frame.\n- Weight limit: The bike has a maximum total weight limit (combined weight of the bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\nPlease refer to the table below for the corresponding Stealth R1X Pro frame sizes, recommended rider height range, and inseam measurements:\n\n| Size |      Rider Height     |     Inseam     |\n|:----:|:---------------------:|:--------------:|\n|  47  |  152 - 158 cm (5'0\")  |  71 - 75 cm    |\n|  50  |  158 - 163 cm (5'2\")  |  74 - 77 cm    |\n|  52  |  163 - 168 cm (5'4\")  |  76 - 79 cm    |\n|  54  |  168 - 174 cm (5'6\")  |  78 - 82 cm    |\n|  56  | 174 - 180 cm (5'9\")  |  81 - 85 cm    |\n|  58  | 180 - 185 cm (5'11\") |  84 - 87 cm    |\n|  60  |  185 - 190 cm (6'1\")  |  86 - 90 cm    |\n|  62  |  190 - 195 cm (6'3\")  |  89 - 92 cm    |\n\n## Geometry\nThe table below provides the geometry measurements for each frame size of the Stealth R1X Pro:\n\n| Frame size number              | 47 cm | 50 cm | 52 cm | 54 cm | 56 cm | 58 cm | 60 cm | 62 cm |\n|-------------------------------|-------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size                    | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                 | 42.4  | 45.3  | 48.3  | 49.6  | 52.5  | 55.3  | 57.3  | 59.3  |\n| B — Seat tube angle           | 74.6° | 74.6° | 74.2° | 73.7° | 73.3° | 73.0° | 72.8° | 72.5° |\n| C — Head tube length          | 10.0  | 11.1  | 12.1  | 13.1  | 15.1  | 17.1  | 19.1  | 21.1  |\n| D — Head angle                | 72.1° | 72.1° | 72.8° | 73.0° | 73.5° | 73.8° | 73.9° | 73.9° |\n| E — Effective top tube        | 51.2  | 52.1  | 53.4  | 54.3  | 55.9  | 57.4  | 58.6  | 59.8  |\n| G — Bottom bracket drop       | 7.2   | 7.2   | 7.2   | 7.0   | 7.0   | 6.8   | 6.8   | 6.8   |\n| H — Chainstay length          | 41.0  | 41.0  | 41.0  | 41.0  | 41.0  | 41.1  | 41.1  | 41.2  |\n| I — Offset                    | 4.5   | 4.5   | 4.5   | 4.5   | 4.0   | 4.0   | 4.0   | 4.0   |\n| J — Trail                     | 6.8   | 6.2   | 5.8   | 5.6   | 5.8   | 5.7   | 5.6   | 5.6   |\n| K — Wheelbase                 | 97.2  | 97.4  | 97.7  | 98.1  | 98.3  | 99.2  | 100.1 | 101.0 |\n| L — Standover                 | 69.2  | 71.1  | 73.2  | 74.4  | 76.8  | 79.3  | 81.1  | 82.9  |\n| M — Frame reach               | 37.3  | 37.8  | 38.3  | 38.6  | 39.1  | 39.6  | 39.9  | 40.3  |\n| N — Frame stack               | 50.7  | 52.1  | 53.3  | 54.1  | 56.3  | 58.1  | 60.1  | 62.0  |\n| Saddle rail height min (short mast) | 55.5 | 58.5 | 61.5 | 64.0 | 67.0 | 69.0 | 71.0 | 73.0 |\n| Saddle rail height max (short mast) | 61.5 | 64.5 | 67.5 | 70.0 | 73.0 | 75.0 | 77.0 | 79.0 |\n| Saddle rail height min (tall mast)  | 59.0 | 62.0 | 65.0 | 67.5 | 70.5 | 72.5 | 74.5 | 76.5 |\n| Saddle rail height max (tall mast)  | 65.0 | 68.0 | 71.0 | 73.5 | 76.5 | 78.5 | 80.5 | 82.5 |",
    "price": 2999.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "Avant SLR 6 Disc Pro",
    "shortDescription": "Avant SLR 6 Disc Pro is a high-performance carbon road bike designed for riders who prioritize speed and handling. With its aero tube shaping, disc brakes, and lightweight carbon wheels, it offers the perfect balance of speed and control.",
    "description": "## Overview\nIt's right for you if...\nYou're a rider who values exceptional performance on fast group rides and races, and you want a complete package that includes lightweight carbon wheels. The Avant SLR 6 Disc Pro is designed to provide the speed and aerodynamics you need to excel on any road.\n\nThe tech you get\nThe Avant SLR 6 Disc Pro features a lightweight 500 Series ADV Carbon frame and fork, Bontrager Aeolus Elite 35 carbon wheels, a full Shimano Ultegra 11-speed drivetrain, and powerful Ultegra disc brakes.\n\nThe final word\nThe standout feature of this bike is the combination of its aero frame, high-performance drivetrain, and top-quality carbon wheels. Whether you're racing, tackling challenging climbs, or participating in professional stage races, the Avant SLR 6 Disc Pro is a worthy choice that will enhance your performance.\n\n## Features\nAll-new aero design\nThe Avant SLR 6 Disc Pro features innovative aero tube shapes that provide an advantage in all riding conditions, whether it's climbing or riding on flat roads. Additionally, it is equipped with a sleek new Aeolus RSL bar/stem that enhances front-end aero performance.\n\nAwesome bikes for everyone\nThe Avant SLR 6 Disc Pro is designed with the belief that every rider, regardless of gender, body type, riding style, or ability, deserves a great bike. It is equipped with size-specific components that ensure a perfect fit for competitive riders of all genders.\n\n## Specifications\nFrameset\n- Frame: Ultralight 500 Series ADV Carbon, Ride Tuned performance tube optimization, tapered head tube, internal routing, DuoTrap S compatible, flat mount disc, 142x12mm thru axle\n- Fork: Avant SL full carbon, tapered carbon steerer, internal brake routing, flat mount disc, 12x100mm thru axle\n- Frame fit: H1.5 Race\n\nWheels\n- Front wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, 100x12mm thru axle\n- Rear wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, Shimano 11/12-speed freehub, 142x12mm thru axle\n- Front skewer: Bontrager Switch thru axle, removable lever\n- Rear skewer: Bontrager Switch thru axle, removable lever\n- Tire: Bontrager R2 Hard-Case Lite, aramid bead, 60 tpi, 700x25c\n- Max tire size: 28mm\n\nDrivetrain\n- Shifter: \n    - Size 47, 50, 52: Shimano Ultegra R8025, short-reach lever, 11-speed\n    - Size 54, 56, 58, 60, 62: Shimano Ultegra R8020, 11-speed\n- Front derailleur: Shimano Ultegra R8000, braze-on\n- Rear derailleur: Shimano Ultegra R8000, short cage, 30T max cog\n- Crank: \n    - Size 47: Shimano Ultegra R8000, 52/36, 165mm length\n    - Size 50, 52: Shimano Ultegra R8000, 52/36, 170mm length\n    - Size 54, 56, 58: Shimano Ultegra R8000, 52/36, 172.5mm length\n    - Size 60, 62: Shimano Ultegra R8000, 52/36, 175mm length\n- Bottom bracket: Praxis, T47 threaded, internal bearing\n- Cassette: Shimano Ultegra R8000, 11-30, 11-speed\n- Chain: Shimano Ultegra HG701, 11-speed\n- Max chainring size: 1x: 50T, 2x: 53/39\n\nComponents\n- Saddle: Bontrager Aeolus Comp, steel rails, 145mm width\n- Seatpost: \n    - Size 47, 50, 52, 54: Bontrager carbon seatmast cap, 20mm offset, short length\n    - Size 56, 58, 60, 62: Bontrager carbon seatmast cap, 20mm offset, tall length\n- Handlebar: \n    - Size 47, 50: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 38cm width\n    - Size 52: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 40cm width\n    - Size 54, 56, 58: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 42cm width\n    - Size 60, 62: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 44cm width\n- Handlebar tape: Bontrager Supertack Perf tape\n- Stem: \n    - Size 47: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 70mm length\n    - Size 50: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 80mm length\n    - Size 52, 54: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 90mm length\n    - Size 56: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 100mm length\n    - Size 58, 60, 62: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 110mm length\n- Brake: Shimano Ultegra hydraulic disc, flat mount\n- Brake rotor: Shimano RT800, centerlock, 160mm\n\nWeight\n- Weight: 56 - 8.03 kg / 17.71 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  47  |  152 - 158 cm 5'0\" - 5'2\" | 71 - 75 cm 28\" - 30\" |\n|  50  |  158 - 163 cm 5'2\" - 5'4\" | 74 - 77 cm 29\" - 30\" |\n|  52  |  163 - 168 cm 5'4\" - 5'6\" | 76 - 79 cm 30\" - 31\" |\n|  54  |  168 - 174 cm 5'6\" - 5'9\" | 78 - 82 cm 31\" - 32\" |\n|  56  | 174 - 180 cm 5'9\" - 5'11\" | 81 - 85 cm 32\" - 33\" |\n|  58  | 180 - 185 cm 5'11\" - 6'1\" | 84 - 87 cm 33\" - 34\" |\n|  60  |  185 - 190 cm 6'1\" - 6'3\" | 86 - 90 cm 34\" - 35\" |\n|  62  |  190 - 195 cm 6'3\" - 6'5\" | 89 - 92 cm 35\" - 36\" |\n\n## Geometry\n| Frame size number                     | 47 cm | 50 cm | 52 cm | 54 cm | 56 cm | 58 cm | 60 cm | 62 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 42.4  | 45.3  | 48.3  | 49.6  | 52.5  | 55.3  | 57.3  | 59.3  |\n| B — Seat tube angle                   | 74.6° | 74.6° | 74.2° | 73.7° | 73.3° | 73.0° | 72.8° | 72.5° |\n| C — Head tube length                  | 10.0  | 11.1  | 12.1  | 13.1  | 15.1  | 17.1  | 19.1  | 21.1  |\n| D — Head angle                        | 72.1° | 72.1° | 72.8° | 73.0° | 73.5° | 73.8° | 73.9° | 73.9° |\n| E — Effective top tube                | 51.2  | 52.1  | 53.4  | 54.3  | 55.9  | 57.4  | 58.6  | 59.8  |\n| G — Bottom bracket drop               | 7.2   | 7.2   | 7.2   | 7.0   | 7.0   | 6.8   | 6.8   | 6.8   |\n| H — Chainstay length                  | 41.0  | 41.0  | 41.0  | 41.0  | 41.0  | 41.1  | 41.1  | 41.2  |\n| I — Offset                            | 4.5   | 4.5   | 4.5   | 4.5   | 4.0   | 4.0   | 4.0   | 4.0   |\n| J — Trail                             | 6.8   | 6.2   | 5.8   | 5.6   | 5.8   | 5.7   | 5.6   | 5.6   |\n| K — Wheelbase                         | 97.2  | 97.4  | 97.7  | 98.1  | 98.3  | 99.2  | 100.1 | 101.0 |\n| L — Standover                         | 69.2  | 71.1  | 73.2  | 74.4  | 76.8  | 79.3  | 81.1  | 82.9  |\n| M — Frame reach                       | 37.3  | 37.8  | 38.3  | 38.6  | 39.1  | 39.6  | 39.9  | 40.3  |\n| N — Frame stack                       | 50.7  | 52.1  | 53.3  | 54.1  | 56.3  | 58.1  | 60.1  | 62.0  |\n| Saddle rail height min (w/short mast) | 55.5  | 58.5  | 61.5  | 64.0  | 67.0  | 69.0  | 71.0  | 73.0  |\n| Saddle rail height max (w/short mast) | 61.5  | 64.5  | 67.5  | 70.0  | 73.0  | 75.0  | 77.0  | 79.0  |\n| Saddle rail height min (w/tall mast)  | 59.0  | 62.0  | 65.0  | 67.5  | 70.5  | 72.5  | 74.5  | 76.5  |\n| Saddle rail height max (w/tall mast)  | 65.0  | 68.0  | 71.0  | 73.5  | 76.5  | 78.5  | 80.5  | 82.5  |",
    "price": 999.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  }
]

---

### Models/Spring Ai Openai/Src/Test/Resources/Prompts/System Only Cache Prompt (models/spring-ai-openai/src/test/resources/prompts/system-only-cache-prompt.txt)

You are an expert software architect specializing in distributed systems and cloud-native applications.
Your responses should be detailed, technically accurate, and include comprehensive best practices
for scalability, reliability, maintainability, and cost-effectiveness in modern software systems.

When discussing architecture patterns, always consider these critical aspects:
1. Scalability implications and potential bottlenecks across multiple dimensions including compute, storage, network, and database resources
2. Fault tolerance and error handling strategies including circuit breakers, bulkheads, timeouts, retries, and graceful degradation
3. Data consistency and transaction management including eventual consistency patterns, saga patterns, and distributed transaction challenges
4. Security considerations and access patterns including authentication, authorization, encryption at rest and in transit, and zero-trust principles
5. Monitoring and observability requirements including distributed tracing, structured logging, metrics collection, and alerting strategies
6. Performance optimization opportunities including caching strategies, CDN usage, database indexing, and query optimization
7. Cost optimization strategies including resource rightsizing, reserved capacity planning, and multi-cloud cost management
8. Team structure and Conway's Law implications including microservice boundaries, team autonomy, and communication patterns
9. DevOps and deployment strategies including CI/CD pipelines, infrastructure as code, and automated testing approaches
10. Compliance and governance requirements including data privacy regulations, audit trails, and regulatory compliance frameworks

## Detailed Architecture Guidelines for System-Only Caching

### Microservices Design Patterns
When designing microservices, implement these essential patterns:
- API Gateway pattern for centralized request routing and cross-cutting concerns
- Service mesh for inter-service communication, security, and observability
- Event sourcing for maintaining audit trails and enabling event-driven architectures
- CQRS (Command Query Responsibility Segregation) for optimal read/write performance
- Bulkhead pattern to isolate critical resources and prevent cascade failures
- Circuit breaker pattern with exponential backoff for external service resilience
- Saga pattern for distributed transaction management across service boundaries

### Data Management Strategies
Implement robust data management approaches:
- Database per service pattern to ensure data encapsulation and service autonomy
- Event-driven data synchronization using message queues and event streams
- Polyglot persistence choosing optimal data stores for specific use cases
- Read replicas and sharding strategies for horizontal scaling
- Data versioning and schema evolution strategies for backward compatibility
- Distributed caching with Redis or similar for improved performance
- Data governance frameworks ensuring data quality, lineage, and compliance

### Security Best Practices
Implement defense-in-depth security measures:
- OAuth 2.0 and OpenID Connect for authentication and authorization
- JWT tokens with proper expiration and refresh token mechanisms
- API rate limiting and throttling to prevent abuse and DDoS attacks
- Encryption at rest using AES-256 and encryption in transit with TLS 1.3
- Secret management using HashiCorp Vault or AWS Secrets Manager
- Network segmentation with VPCs, subnets, and security groups
- Regular security audits, vulnerability scanning, and penetration testing

### Monitoring and Observability
Establish comprehensive observability:
- Distributed tracing with OpenTelemetry or Jaeger for request flow analysis
- Centralized logging with ELK stack or similar for log aggregation and analysis
- Application metrics using Prometheus and Grafana for monitoring and alerting
- Health checks and readiness probes for service availability monitoring
- SLA/SLO definitions with error budgets for reliability measurements
- Alert management with PagerDuty or similar for incident response
- Performance monitoring with APM tools like New Relic or AppDynamics

### Infrastructure and DevOps
Implement modern infrastructure practices:
- Infrastructure as Code using Terraform, CloudFormation, or Pulumi
- Container orchestration with Kubernetes for scalable deployments
- GitOps workflows with ArgoCD or Flux for automated deployments
- Blue-green or canary deployment strategies for zero-downtime releases
- Automated testing pipelines including unit, integration, and end-to-end tests
- Code quality gates with SonarQube and static analysis tools
- Disaster recovery planning with backup strategies and failover procedures

Always provide concrete examples, architectural diagrams when helpful, code snippets in relevant programming languages,
and real-world case studies from companies like Netflix, Amazon, Google, Microsoft, and other technology leaders.
Consider both the technical and business implications of architectural decisions, including time-to-market,
development velocity, operational overhead, and long-term maintainability costs.

This system prompt is specifically designed for testing system-only caching strategies and contains sufficient tokens
to trigger OpenAI's prompt caching mechanism with gpt-4o-mini (1024+ token threshold).

---

### Models/Spring Ai Postgresml/README (models/spring-ai-postgresml/README.md)

[PostgresML Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/postgresml-embeddings.html)

---

### Models/Spring Ai Stability Ai/README (models/spring-ai-stability-ai/README.md)

[Stability AI Image Generation](https://docs.spring.io/spring-ai/reference/api/image/stabilityai-image.html)

---

### Models/Spring Ai Transformers/README (models/spring-ai-transformers/README.md)

[Transformers Embedding Documentation](https://docs.spring.io/spring-ai/reference/api/embeddings/onnx.html)

---

### Models/Spring Ai Transformers/Src/Main/Resources/Onnx/All MiniLM L6 V2/Tokenizer.Json (models/spring-ai-transformers/src/main/resources/onnx/all-MiniLM-L6-v2/tokenizer.json)

{
  "version": "1.0",
  "truncation": {
    "direction": "Right",
    "max_length": 128,
    "strategy": "LongestFirst",
    "stride": 0
  },
  "padding": {
    "strategy": {
      "Fixed": 128
    },
    "direction": "Right",
    "pad_to_multiple_of": null,
    "pad_id": 0,
    "pad_type_id": 0,
    "pad_token": "[PAD]"
  },
  "added_tokens": [
    {
      "id": 0,
      "content": "[PAD]",
      "single_word": false,
      "lstrip": false,
      "rstrip": false,
      "normalized": false,
      "special": true
    },
    {
      "id": 100,
      "content": "[UNK]",
      "single_word": false,
      "lstrip": false,
      "rstrip": false,
      "normalized": false,
      "special": true
    },
    {
      "id": 101,
      "content": "[CLS]",
      "single_word": false,
      "lstrip": false,
      "rstrip": false,
      "normalized": false,
      "special": true
    },
    {
      "id": 102,
      "content": "[SEP]",
      "single_word": false,
      "lstrip": false,
      "rstrip": false,
      "normalized": false,
      "special": true
    },
    {
      "id": 103,
      "content": "[MASK]",
      "single_word": false,
      "lstrip": false,
      "rstrip": false,
      "normalized": false,
      "special": true
    }
  ],
  "normalizer": {
    "type": "BertNormalizer",
    "clean_text": true,
    "handle_chinese_chars": true,
    "strip_accents": null,
    "lowercase": true
  },
  "pre_tokenizer": {
    "type": "BertPreTokenizer"
  },
  "post_processor": {
    "type": "TemplateProcessing",
    "single": [
      {
        "SpecialToken": {
          "id": "[CLS]",
          "type_id": 0
        }
      },
      {
        "Sequence": {
          "id": "A",
          "type_id": 0
        }
      },
      {
        "SpecialToken": {
          "id": "[SEP]",
          "type_id": 0
        }
      }
    ],
    "pair": [
      {
        "SpecialToken": {
          "id": "[CLS]",
          "type_id": 0
        }
      },
      {
        "Sequence": {
          "id": "A",
          "type_id": 0
        }
      },
      {
        "SpecialToken": {
          "id": "[SEP]",
          "type_id": 0
        }
      },
      {
        "Sequence": {
          "id": "B",
          "type_id": 1
        }
      },
      {
        "SpecialToken": {
          "id": "[SEP]",
          "type_id": 1
        }
      }
    ],
    "special_tokens": {
      "[CLS]": {
        "id": "[CLS]",
        "ids": [
          101
        ],
        "tokens": [
          "[CLS]"
        ]
      },
      "[SEP]": {
        "id": "[SEP]",
        "ids": [
          102
        ],
        "tokens": [
          "[SEP]"
        ]
      }
    }
  },
  "decoder": {
    "type": "WordPiece",
    "prefix": "##",
    "cleanup": true
  },
  "model": {
    "type": "WordPiece",
    "unk_token": "[UNK]",
    "continuing_subword_prefix": "##",
    "max_input_chars_per_word": 100,
    "vocab": {
      "[PAD]": 0,
      "[unused0]": 1,
      "[unused1]": 2,
      "[unused2]": 3,
      "[unused3]": 4,
      "[unused4]": 5,
      "[unused5]": 6,
      "[unused6]": 7,
      "[unused7]": 8,
      "[unused8]": 9,
      "[unused9]": 10,
      "[unused10]": 11,
      "[unused11]": 12,
      "[unused12]": 13,
      "[unused13]": 14,
      "[unused14]": 15,
      "[unused15]": 16,
      "[unused16]": 17,
      "[unused17]": 18,
      "[unused18]": 19,
      "[unused19]": 20,
      "[unused20]": 21,
      "[unused21]": 22,
      "[unused22]": 23,
      "[unused23]": 24,
      "[unused24]": 25,
      "[unused25]": 26,
      "[unused26]": 27,
      "[unused27]": 28,
      "[unused28]": 29,
      "[unused29]": 30,
      "[unused30]": 31,
      "[unused31]": 32,
      "[unused32]": 33,
      "[unused33]": 34,
      "[unused34]": 35,
      "[unused35]": 36,
      "[unused36]": 37,
      "[unused37]": 38,
      "[unused38]": 39,
      "[unused39]": 40,
      "[unused40]": 41,
      "[unused41]": 42,
      "[unused42]": 43,
      "[unused43]": 44,
      "[unused44]": 45,
      "[unused45]": 46,
      "[unused46]": 47,
      "[unused47]": 48,
      "[unused48]": 49,
      "[unused49]": 50,
      "[unused50]": 51,
      "[unused51]": 52,
      "[unused52]": 53,
      "[unused53]": 54,
      "[unused54]": 55,
      "[unused55]": 56,
      "[unused56]": 57,
      "[unused57]": 58,
      "[unused58]": 59,
      "[unused59]": 60,
      "[unused60]": 61,
      "[unused61]": 62,
      "[unused62]": 63,
      "[unused63]": 64,
      "[unused64]": 65,
      "[unused65]": 66,
      "[unused66]": 67,
      "[unused67]": 68,
      "[unused68]": 69,
      "[unused69]": 70,
      "[unused70]": 71,
      "[unused71]": 72,
      "[unused72]": 73,
      "[unused73]": 74,
      "[unused74]": 75,
      "[unused75]": 76,
      "[unused76]": 77,
      "[unused77]": 78,
      "[unused78]": 79,
      "[unused79]": 80,
      "[unused80]": 81,
      "[unused81]": 82,
      "[unused82]": 83,
      "[unused83]": 84,
      "[unused84]": 85,
      "[unused85]": 86,
      "[unused86]": 87,
      "[unused87]": 88,
      "[unused88]": 89,
      "[unused89]": 90,
      "[unused90]": 91,
      "[unused91]": 92,
      "[unused92]": 93,
      "[unused93]": 94,
      "[unused94]": 95,
      "[unused95]": 96,
      "[unused96]": 97,
      "[unused97]": 98,
      "[unused98]": 99,
      "[UNK]": 100,
      "[CLS]": 101,
      "[SEP]": 102,
      "[MASK]": 103,
      "[unused99]": 104,
      "[unused100]": 105,
      "[unused101]": 106,
      "[unused102]": 107,
      "[unused103]": 108,
      "[unused104]": 109,
      "[unused105]": 110,
      "[unused106]": 111,
      "[unused107]": 112,
      "[unused108]": 113,
      "[unused109]": 114,
      "[unused110]": 115,
      "[unused111]": 116,
      "[unused112]": 117,
      "[unused113]": 118,
      "[unused114]": 119,
      "[unused115]": 120,
      "[unused116]": 121,
      "[unused117]": 122,
      "[unused118]": 123,
      "[unused119]": 124,
      "[unused120]": 125,
      "[unused121]": 126,
      "[unused122]": 127,
      "[unused123]": 128,
      "[unused124]": 129,
      "[unused125]": 130,
      "[unused126]": 131,
      "[unused127]": 132,
      "[unused128]": 133,
      "[unused129]": 134,
      "[unused130]": 135,
      "[unused131]": 136,
      "[unused132]": 137,
      "[unused133]": 138,
      "[unused134]": 139,
      "[unused135]": 140,
      "[unused136]": 141,
      "[unused137]": 142,
      "[unused138]": 143,
      "[unused139]": 144,
      "[unused140]": 145,
      "[unused141]": 146,
      "[unused142]": 147,
      "[unused143]": 148,
      "[unused144]": 149,
      "[unused145]": 150,
      "[unused146]": 151,
      "[unused147]": 152,
      "[unused148]": 153,
      "[unused149]": 154,
      "[unused150]": 155,
      "[unused151]": 156,
      "[unused152]": 157,
      "[unused153]": 158,
      "[unused154]": 159,
      "[unused155]": 160,
      "[unused156]": 161,
      "[unused157]": 162,
      "[unused158]": 163,
      "[unused159]": 164,
      "[unused160]": 165,
      "[unused161]": 166,
      "[unused162]": 167,
      "[unused163]": 168,
      "[unused164]": 169,
      "[unused165]": 170,
      "[unused166]": 171,
      "[unused167]": 172,
      "[unused168]": 173,
      "[unused169]": 174,
      "[unused170]": 175,
      "[unused171]": 176,
      "[unused172]": 177,
      "[unused173]": 178,
      "[unused174]": 179,
      "[unused175]": 180,
      "[unused176]": 181,
      "[unused177]": 182,
      "[unused178]": 183,
      "[unused179]": 184,
      "[unused180]": 185,
      "[unused181]": 186,
      "[unused182]": 187,
      "[unused183]": 188,
      "[unused184]": 189,
      "[unused185]": 190,
      "[unused186]": 191,
      "[unused187]": 192,
      "[unused188]": 193,
      "[unused189]": 194,
      "[unused190]": 195,
      "[unused191]": 196,
      "[unused192]": 197,
      "[unused193]": 198,
      "[unused194]": 199,
      "[unused195]": 200,
      "[unused196]": 201,
      "[unused197]": 202,
      "[unused198]": 203,
      "[unused199]": 204,
      "[unused200]": 205,
      "[unused201]": 206,
      "[unused202]": 207,
      "[unused203]": 208,
      "[unused204]": 209,
      "[unused205]": 210,
      "[unused206]": 211,
      "[unused207]": 212,
      "[unused208]": 213,
      "[unused209]": 214,
      "[unused210]": 215,
      "[unused211]": 216,
      "[unused212]": 217,
      "[unused213]": 218,
      "[unused214]": 219,
      "[unused215]": 220,
      "[unused216]": 221,
      "[unused217]": 222,
      "[unused218]": 223,
      "[unused219]": 224,
      "[unused220]": 225,
      "[unused221]": 226,
      "[unused222]": 227,
      "[unused223]": 228,
      "[unused224]": 229,
      "[unused225]": 230,
      "[unused226]": 231,
      "[unused227]": 232,
      "[unused228]": 233,
      "[unused229]": 234,
      "[unused230]": 235,
      "[unused231]": 236,
      "[unused232]": 237,
      "[unused233]": 238,
      "[unused234]": 239,
      "[unused235]": 240,
      "[unused236]": 241,
      "[unused237]": 242,
      "[unused238]": 243,
      "[unused239]": 244,
      "[unused240]": 245,
      "[unused241]": 246,
      "[unused242]": 247,
      "[unused243]": 248,
      "[unused244]": 249,
      "[unused245]": 250,
      "[unused246]": 251,
      "[unused247]": 252,
      "[unused248]": 253,
      "[unused249]": 254,
      "[unused250]": 255,
      "[unused251]": 256,
      "[unused252]": 257,
      "[unused253]": 258,
      "[unused254]": 259,
      "[unused255]": 260,
      "[unused256]": 261,
      "[unused257]": 262,
      "[unused258]": 263,
      "[unused259]": 264,
      "[unused260]": 265,
      "[unused261]": 266,
      "[unused262]": 267,
      "[unused263]": 268,
      "[unused264]": 269,
      "[unused265]": 270,
      "[unused266]": 271,
      "[unused267]": 272,
      "[unused268]": 273,
      "[unused269]": 274,
      "[unused270]": 275,
      "[unused271]": 276,
      "[unused272]": 277,
      "[unused273]": 278,
      "[unused274]": 279,
      "[unused275]": 280,
      "[unused276]": 281,
      "[unused277]": 282,
      "[unused278]": 283,
      "[unused279]": 284,
      "[unused280]": 285,
      "[unused281]": 286,
      "[unused282]": 287,
      "[unused283]": 288,
      "[unused284]": 289,
      "[unused285]": 290,
      "[unused286]": 291,
      "[unused287]": 292,
      "[unused288]": 293,
      "[unused289]": 294,
      "[unused290]": 295,
      "[unused291]": 296,
      "[unused292]": 297,
      "[unused293]": 298,
      "[unused294]": 299,
      "[unused295]": 300,
      "[unused296]": 301,
      "[unused297]": 302,
      "[unused298]": 303,
      "[unused299]": 304,
      "[unused300]": 305,
      "[unused301]": 306,
      "[unused302]": 307,
      "[unused303]": 308,
      "[unused304]": 309,
      "[unused305]": 310,
      "[unused306]": 311,
      "[unused307]": 312,
      "[unused308]": 313,
      "[unused309]": 314,
      "[unused310]": 315,
      "[unused311]": 316,
      "[unused312]": 317,
      "[unused313]": 318,
      "[unused314]": 319,
      "[unused315]": 320,
      "[unused316]": 321,
      "[unused317]": 322,
      "[unused318]": 323,
      "[unused319]": 324,
      "[unused320]": 325,
      "[unused321]": 326,
      "[unused322]": 327,
      "[unused323]": 328,
      "[unused324]": 329,
      "[unused325]": 330,
      "[unused326]": 331,
      "[unused327]": 332,
      "[unused328]": 333,
      "[unused329]": 334,
      "[unused330]": 335,
      "[unused331]": 336,
      "[unused332]": 337,
      "[unused333]": 338,
      "[unused334]": 339,
      "[unused335]": 340,
      "[unused336]": 341,
      "[unused337]": 342,
      "[unused338]": 343,
      "[unused339]": 344,
      "[unused340]": 345,
      "[unused341]": 346,
      "[unused342]": 347,
      "[unused343]": 348,
      "[unused344]": 349,
      "[unused345]": 350,
      "[unused346]": 351,
      "[unused347]": 352,
      "[unused348]": 353,
      "[unused349]": 354,
      "[unused350]": 355,
      "[unused351]": 356,
      "[unused352]": 357,
      "[unused353]": 358,
      "[unused354]": 359,
      "[unused355]": 360,
      "[unused356]": 361,
      "[unused357]": 362,
      "[unused358]": 363,
      "[unused359]": 364,
      "[unused360]": 365,
      "[unused361]": 366,
      "[unused362]": 367,
      "[unused363]": 368,
      "[unused364]": 369,
      "[unused365]": 370,
      "[unused366]": 371,
      "[unused367]": 372,
      "[unused368]": 373,
      "[unused369]": 374,
      "[unused370]": 375,
      "[unused371]": 376,
      "[unused372]": 377,
      "[unused373]": 378,
      "[unused374]": 379,
      "[unused375]": 380,
      "[unused376]": 381,
      "[unused377]": 382,
      "[unused378]": 383,
      "[unused379]": 384,
      "[unused380]": 385,
      "[unused381]": 386,
      "[unused382]": 387,
      "[unused383]": 388,
      "[unused384]": 389,
      "[unused385]": 390,
      "[unused386]": 391,
      "[unused387]": 392,
      "[unused388]": 393,
      "[unused389]": 394,
      "[unused390]": 395,
      "[unused391]": 396,
      "[unused392]": 397,
      "[unused393]": 398,
      "[unused394]": 399,
      "[unused395]": 400,
      "[unused396]": 401,
      "[unused397]": 402,
      "[unused398]": 403,
      "[unused399]": 404,
      "[unused400]": 405,
      "[unused401]": 406,
      "[unused402]": 407,
      "[unused403]": 408,
      "[unused404]": 409,
      "[unused405]": 410,
      "[unused406]": 411,
      "[unused407]": 412,
      "[unused408]": 413,
      "[unused409]": 414,
      "[unused410]": 415,
      "[unused411]": 416,
      "[unused412]": 417,
      "[unused413]": 418,
      "[unused414]": 419,
      "[unused415]": 420,
      "[unused416]": 421,
      "[unused417]": 422,
      "[unused418]": 423,
      "[unused419]": 424,
      "[unused420]": 425,
      "[unused421]": 426,
      "[unused422]": 427,
      "[unused423]": 428,
      "[unused424]": 429,
      "[unused425]": 430,
      "[unused426]": 431,
      "[unused427]": 432,
      "[unused428]": 433,
      "[unused429]": 434,
      "[unused430]": 435,
      "[unused431]": 436,
      "[unused432]": 437,
      "[unused433]": 438,
      "[unused434]": 439,
      "[unused435]": 440,
      "[unused436]": 441,
      "[unused437]": 442,
      "[unused438]": 443,
      "[unused439]": 444,
      "[unused440]": 445,
      "[unused441]": 446,
      "[unused442]": 447,
      "[unused443]": 448,
      "[unused444]": 449,
      "[unused445]": 450,
      "[unused446]": 451,
      "[unused447]": 452,
      "[unused448]": 453,
      "[unused449]": 454,
      "[unused450]": 455,
      "[unused451]": 456,
      "[unused452]": 457,
      "[unused453]": 458,
      "[unused454]": 459,
      "[unused455]": 460,
      "[unused456]": 461,
      "[unused457]": 462,
      "[unused458]": 463,
      "[unused459]": 464,
      "[unused460]": 465,
      "[unused461]": 466,
      "[unused462]": 467,
      "[unused463]": 468,
      "[unused464]": 469,
      "[unused465]": 470,
      "[unused466]": 471,
      "[unused467]": 472,
      "[unused468]": 473,
      "[unused469]": 474,
      "[unused470]": 475,
      "[unused471]": 476,
      "[unused472]": 477,
      "[unused473]": 478,
      "[unused474]": 479,
      "[unused475]": 480,
      "[unused476]": 481,
      "[unused477]": 482,
      "[unused478]": 483,
      "[unused479]": 484,
      "[unused480]": 485,
      "[unused481]": 486,
      "[unused482]": 487,
      "[unused483]": 488,
      "[unused484]": 489,
      "[unused485]": 490,
      "[unused486]": 491,
      "[unused487]": 492,
      "[unused488]": 493,
      "[unused489]": 494,
      "[unused490]": 495,
      "[unused491]": 496,
      "[unused492]": 497,
      "[unused493]": 498,
      "[unused494]": 499,
      "[unused495]": 500,
      "[unused496]": 501,
      "[unused497]": 502,
      "[unused498]": 503,
      "[unused499]": 504,
      "[unused500]": 505,
      "[unused501]": 506,
      "[unused502]": 507,
      "[unused503]": 508,
      "[unused504]": 509,
      "[unused505]": 510,
      "[unused506]": 511,
      "[unused507]": 512,
      "[unused508]": 513,
      "[unused509]": 514,
      "[unused510]": 515,
      "[unused511]": 516,
      "[unused512]": 517,
      "[unused513]": 518,
      "[unused514]": 519,
      "[unused515]": 520,
      "[unused516]": 521,
      "[unused517]": 522,
      "[unused518]": 523,
      "[unused519]": 524,
      "[unused520]": 525,
      "[unused521]": 526,
      "[unused522]": 527,
      "[unused523]": 528,
      "[unused524]": 529,
      "[unused525]": 530,
      "[unused526]": 531,
      "[unused527]": 532,
      "[unused528]": 533,
      "[unused529]": 534,
      "[unused530]": 535,
      "[unused531]": 536,
      "[unused532]": 537,
      "[unused533]": 538,
      "[unused534]": 539,
      "[unused535]": 540,
      "[unused536]": 541,
      "[unused537]": 542,
      "[unused538]": 543,
      "[unused539]": 544,
      "[unused540]": 545,
      "[unused541]": 546,
      "[unused542]": 547,
      "[unused543]": 548,
      "[unused544]": 549,
      "[unused545]": 550,
      "[unused546]": 551,
      "[unused547]": 552,
      "[unused548]": 553,
      "[unused549]": 554,
      "[unused550]": 555,
      "[unused551]": 556,
      "[unused552]": 557,
      "[unused553]": 558,
      "[unused554]": 559,
      "[unused555]": 560,
      "[unused556]": 561,
      "[unused557]": 562,
      "[unused558]": 563,
      "[unused559]": 564,
      "[unused560]": 565,
      "[unused561]": 566,
      "[unused562]": 567,
      "[unused563]": 568,
      "[unused564]": 569,
      "[unused565]": 570,
      "[unused566]": 571,
      "[unused567]": 572,
      "[unused568]": 573,
      "[unused569]": 574,
      "[unused570]": 575,
      "[unused571]": 576,
      "[unused572]": 577,
      "[unused573]": 578,
      "[unused574]": 579,
      "[unused575]": 580,
      "[unused576]": 581,
      "[unused577]": 582,
      "[unused578]": 583,
      "[unused579]": 584,
      "[unused580]": 585,
      "[unused581]": 586,
      "[unused582]": 587,
      "[unused583]": 588,
      "[unused584]": 589,
      "[unused585]": 590,
      "[unused586]": 591,
      "[unused587]": 592,
      "[unused588]": 593,
      "[unused589]": 594,
      "[unused590]": 595,
      "[unused591]": 596,
      "[unused592]": 597,
      "[unused593]": 598,
      "[unused594]": 599,
      "[unused595]": 600,
      "[unused596]": 601,
      "[unused597]": 602,
      "[unused598]": 603,
      "[unused599]": 604,
      "[unused600]": 605,
      "[unused601]": 606,
      "[unused602]": 607,
      "[unused603]": 608,
      "[unused604]": 609,
      "[unused605]": 610,
      "[unused606]": 611,
      "[unused607]": 612,
      "[unused608]": 613,
      "[unused609]": 614,
      "[unused610]": 615,
      "[unused611]": 616,
      "[unused612]": 617,
      "[unused613]": 618,
      "[unused614]": 619,
      "[unused615]": 620,
      "[unused616]": 621,
      "[unused617]": 622,
      "[unused618]": 623,
      "[unused619]": 624,
      "[unused620]": 625,
      "[unused621]": 626,
      "[unused622]": 627,
      "[unused623]": 628,
      "[unused624]": 629,
      "[unused625]": 630,
      "[unused626]": 631,
      "[unused627]": 632,
      "[unused628]": 633,
      "[unused629]": 634,
      "[unused630]": 635,
      "[unused631]": 636,
      "[unused632]": 637,
      "[unused633]": 638,
      "[unused634]": 639,
      "[unused635]": 640,
      "[unused636]": 641,
      "[unused637]": 642,
      "[unused638]": 643,
      "[unused639]": 644,
      "[unused640]": 645,
      "[unused641]": 646,
      "[unused642]": 647,
      "[unused643]": 648,
      "[unused644]": 649,
      "[unused645]": 650,
      "[unused646]": 651,
      "[unused647]": 652,
      "[unused648]": 653,
      "[unused649]": 654,
      "[unused650]": 655,
      "[unused651]": 656,
      "[unused652]": 657,
      "[unused653]": 658,
      "[unused654]": 659,
      "[unused655]": 660,
      "[unused656]": 661,
      "[unused657]": 662,
      "[unused658]": 663,
      "[unused659]": 664,
      "[unused660]": 665,
      "[unused661]": 666,
      "[unused662]": 667,
      "[unused663]": 668,
      "[unused664]": 669,
      "[unused665]": 670,
      "[unused666]": 671,
      "[unused667]": 672,
      "[unused668]": 673,
      "[unused669]": 674,
      "[unused670]": 675,
      "[unused671]": 676,
      "[unused672]": 677,
      "[unused673]": 678,
      "[unused674]": 679,
      "[unused675]": 680,
      "[unused676]": 681,
      "[unused677]": 682,
      "[unused678]": 683,
      "[unused679]": 684,
      "[unused680]": 685,
      "[unused681]": 686,
      "[unused682]": 687,
      "[unused683]": 688,
      "[unused684]": 689,
      "[unused685]": 690,
      "[unused686]": 691,
      "[unused687]": 692,
      "[unused688]": 693,
      "[unused689]": 694,
      "[unused690]": 695,
      "[unused691]": 696,
      "[unused692]": 697,
      "[unused693]": 698,
      "[unused694]": 699,
      "[unused695]": 700,
      "[unused696]": 701,
      "[unused697]": 702,
      "[unused698]": 703,
      "[unused699]": 704,
      "[unused700]": 705,
      "[unused701]": 706,
      "[unused702]": 707,
      "[unused703]": 708,
      "[unused704]": 709,
      "[unused705]": 710,
      "[unused706]": 711,
      "[unused707]": 712,
      "[unused708]": 713,
      "[unused709]": 714,
      "[unused710]": 715,
      "[unused711]": 716,
      "[unused712]": 717,
      "[unused713]": 718,
      "[unused714]": 719,
      "[unused715]": 720,
      "[unused716]": 721,
      "[unused717]": 722,
      "[unused718]": 723,
      "[unused719]": 724,
      "[unused720]": 725,
      "[unused721]": 726,
      "[unused722]": 727,
      "[unused723]": 728,
      "[unused724]": 729,
      "[unused725]": 730,
      "[unused726]": 731,
      "[unused727]": 732,
      "[unused728]": 733,
      "[unused729]": 734,
      "[unused730]": 735,
      "[unused731]": 736,
      "[unused732]": 737,
      "[unused733]": 738,
      "[unused734]": 739,
      "[unused735]": 740,
      "[unused736]": 741,
      "[unused737]": 742,
      "[unused738]": 743,
      "[unused739]": 744,
      "[unused740]": 745,
      "[unused741]": 746,
      "[unused742]": 747,
      "[unused743]": 748,
      "[unused744]": 749,
      "[unused745]": 750,
      "[unused746]": 751,
      "[unused747]": 752,
      "[unused748]": 753,
      "[unused749]": 754,
      "[unused750]": 755,
      "[unused751]": 756,
      "[unused752]": 757,
      "[unused753]": 758,
      "[unused754]": 759,
      "[unused755]": 760,
      "[unused756]": 761,
      "[unused757]": 762,
      "[unused758]": 763,
      "[unused759]": 764,
      "[unused760]": 765,
      "[unused761]": 766,
      "[unused762]": 767,
      "[unused763]": 768,
      "[unused764]": 769,
      "[unused765]": 770,
      "[unused766]": 771,
      "[unused767]": 772,
      "[unused768]": 773,
      "[unused769]": 774,
      "[unused770]": 775,
      "[unused771]": 776,
      "[unused772]": 777,
      "[unused773]": 778,
      "[unused774]": 779,
      "[unused775]": 780,
      "[unused776]": 781,
      "[unused777]": 782,
      "[unused778]": 783,
      "[unused779]": 784,
      "[unused780]": 785,
      "[unused781]": 786,
      "[unused782]": 787,
      "[unused783]": 788,
      "[unused784]": 789,
      "[unused785]": 790,
      "[unused786]": 791,
      "[unused787]": 792,
      "[unused788]": 793,
      "[unused789]": 794,
      "[unused790]": 795,
      "[unused791]": 796,
      "[unused792]": 797,
      "[unused793]": 798,
      "[unused794]": 799,
      "[unused795]": 800,
      "[unused796]": 801,
      "[unused797]": 802,
      "[unused798]": 803,
      "[unused799]": 804,
      "[unused800]": 805,
      "[unused801]": 806,
      "[unused802]": 807,
      "[unused803]": 808,
      "[unused804]": 809,
      "[unused805]": 810,
      "[unused806]": 811,
      "[unused807]": 812,
      "[unused808]": 813,
      "[unused809]": 814,
      "[unused810]": 815,
      "[unused811]": 816,
      "[unused812]": 817,
      "[unused813]": 818,
      "[unused814]": 819,
      "[unused815]": 820,
      "[unused816]": 821,
      "[unused817]": 822,
      "[unused818]": 823,
      "[unused819]": 824,
      "[unused820]": 825,
      "[unused821]": 826,
      "[unused822]": 827,
      "[unused823]": 828,
      "[unused824]": 829,
      "[unused825]": 830,
      "[unused826]": 831,
      "[unused827]": 832,
      "[unused828]": 833,
      "[unused829]": 834,
      "[unused830]": 835,
      "[unused831]": 836,
      "[unused832]": 837,
      "[unused833]": 838,
      "[unused834]": 839,
      "[unused835]": 840,
      "[unused836]": 841,
      "[unused837]": 842,
      "[unused838]": 843,
      "[unused839]": 844,
      "[unused840]": 845,
      "[unused841]": 846,
      "[unused842]": 847,
      "[unused843]": 848,
      "[unused844]": 849,
      "[unused845]": 850,
      "[unused846]": 851,
      "[unused847]": 852,
      "[unused848]": 853,
      "[unused849]": 854,
      "[unused850]": 855,
      "[unused851]": 856,
      "[unused852]": 857,
      "[unused853]": 858,
      "[unused854]": 859,
      "[unused855]": 860,
      "[unused856]": 861,
      "[unused857]": 862,
      "[unused858]": 863,
      "[unused859]": 864,
      "[unused860]": 865,
      "[unused861]": 866,
      "[unused862]": 867,
      "[unused863]": 868,
      "[unused864]": 869,
      "[unused865]": 870,
      "[unused866]": 871,
      "[unused867]": 872,
      "[unused868]": 873,
      "[unused869]": 874,
      "[unused870]": 875,
      "[unused871]": 876,
      "[unused872]": 877,
      "[unused873]": 878,
      "[unused874]": 879,
      "[unused875]": 880,
      "[unused876]": 881,
      "[unused877]": 882,
      "[unused878]": 883,
      "[unused879]": 884,
      "[unused880]": 885,
      "[unused881]": 886,
      "[unused882]": 887,
      "[unused883]": 888,
      "[unused884]": 889,
      "[unused885]": 890,
      "[unused886]": 891,
      "[unused887]": 892,
      "[unused888]": 893,
      "[unused889]": 894,
      "[unused890]": 895,
      "[unused891]": 896,
      "[unused892]": 897,
      "[unused893]": 898,
      "[unused894]": 899,
      "[unused895]": 900,
      "[unused896]": 901,
      "[unused897]": 902,
      "[unused898]": 903,
      "[unused899]": 904,
      "[unused900]": 905,
      "[unused901]": 906,
      "[unused902]": 907,
      "[unused903]": 908,
      "[unused904]": 909,
      "[unused905]": 910,
      "[unused906]": 911,
      "[unused907]": 912,
      "[unused908]": 913,
      "[unused909]": 914,
      "[unused910]": 915,
      "[unused911]": 916,
      "[unused912]": 917,
      "[unused913]": 918,
      "[unused914]": 919,
      "[unused915]": 920,
      "[unused916]": 921,
      "[unused917]": 922,
      "[unused918]": 923,
      "[unused919]": 924,
      "[unused920]": 925,
      "[unused921]": 926,
      "[unused922]": 927,
      "[unused923]": 928,
      "[unused924]": 929,
      "[unused925]": 930,
      "[unused926]": 931,
      "[unused927]": 932,
      "[unused928]": 933,
      "[unused929]": 934,
      "[unused930]": 935,
      "[unused931]": 936,
      "[unused932]": 937,
      "[unused933]": 938,
      "[unused934]": 939,
      "[unused935]": 940,
      "[unused936]": 941,
      "[unused937]": 942,
      "[unused938]": 943,
      "[unused939]": 944,
      "[unused940]": 945,
      "[unused941]": 946,
      "[unused942]": 947,
      "[unused943]": 948,
      "[unused944]": 949,
      "[unused945]": 950,
      "[unused946]": 951,
      "[unused947]": 952,
      "[unused948]": 953,
      "[unused949]": 954,
      "[unused950]": 955,
      "[unused951]": 956,
      "[unused952]": 957,
      "[unused953]": 958,
      "[unused954]": 959,
      "[unused955]": 960,
      "[unused956]": 961,
      "[unused957]": 962,
      "[unused958]": 963,
      "[unused959]": 964,
      "[unused960]": 965,
      "[unused961]": 966,
      "[unused962]": 967,
      "[unused963]": 968,
      "[unused964]": 969,
      "[unused965]": 970,
      "[unused966]": 971,
      "[unused967]": 972,
      "[unused968]": 973,
      "[unused969]": 974,
      "[unused970]": 975,
      "[unused971]": 976,
      "[unused972]": 977,
      "[unused973]": 978,
      "[unused974]": 979,
      "[unused975]": 980,
      "[unused976]": 981,
      "[unused977]": 982,
      "[unused978]": 983,
      "[unused979]": 984,
      "[unused980]": 985,
      "[unused981]": 986,
      "[unused982]": 987,
      "[unused983]": 988,
      "[unused984]": 989,
      "[unused985]": 990,
      "[unused986]": 991,
      "[unused987]": 992,
      "[unused988]": 993,
      "[unused989]": 994,
      "[unused990]": 995,
      "[unused991]": 996,
      "[unused992]": 997,
      "[unused993]": 998,
      "!": 999,
      "\"": 1000,
      "#": 1001,
      "$": 1002,
      "%": 1003,
      "&": 1004,
      "'": 1005,
      "(": 1006,
      ")": 1007,
      "*": 1008,
      "+": 1009,
      ",": 1010,
      "-": 1011,
      ".": 1012,
      "/": 1013,
      "0": 1014,
      "1": 1015,
      "2": 1016,
      "3": 1017,
      "4": 1018,
      "5": 1019,
      "6": 1020,
      "7": 1021,
      "8": 1022,
      "9": 1023,
      ":": 1024,
      ";": 1025,
      "<": 1026,
      "=": 1027,
      ">": 1028,
      "?": 1029,
      "@": 1030,
      "[": 1031,
      "\\": 1032,
      "]": 1033,
      "^": 1034,
      "_": 1035,
      "`": 1036,
      "a": 1037,
      "b": 1038,
      "c": 1039,
      "d": 1040,
      "e": 1041,
      "f": 1042,
      "g": 1043,
      "h": 1044,
      "i": 1045,
      "j": 1046,
      "k": 1047,
      "l": 1048,
      "m": 1049,
      "n": 1050,
      "o": 1051,
      "p": 1052,
      "q": 1053,
      "r": 1054,
      "s": 1055,
      "t": 1056,
      "u": 1057,
      "v": 1058,
      "w": 1059,
      "x": 1060,
      "y": 1061,
      "z": 1062,
      "{": 1063,
      "|": 1064,
      "}": 1065,
      "~": 1066,
      "¡": 1067,
      "¢": 1068,
      "£": 1069,
      "¤": 1070,
      "¥": 1071,
      "¦": 1072,
      "§": 1073,
      "¨": 1074,
      "©": 1075,
      "ª": 1076,
      "«": 1077,
      "¬": 1078,
      "®": 1079,
      "°": 1080,
      "±": 1081,
      "²": 1082,
      "³": 1083,
      "´": 1084,
      "µ": 1085,
      "¶": 1086,
      "·": 1087,
      "¹": 1088,
      "º": 1089,
      "»": 1090,
      "¼": 1091,
      "½": 1092,
      "¾": 1093,
      "¿": 1094,
      "×": 1095,
      "ß": 1096,
      "æ": 1097,
      "ð": 1098,
      "÷": 1099,
      "ø": 1100,
      "þ": 1101,
      "đ": 1102,
      "ħ": 1103,
      "ı": 1104,
      "ł": 1105,
      "ŋ": 1106,
      "œ": 1107,
      "ƒ": 1108,
      "ɐ": 1109,
      "ɑ": 1110,
      "ɒ": 1111,
      "ɔ": 1112,
      "ɕ": 1113,
      "ə": 1114,
      "ɛ": 1115,
      "ɡ": 1116,
      "ɣ": 1117,
      "ɨ": 1118,
      "ɪ": 1119,
      "ɫ": 1120,
      "ɬ": 1121,
      "ɯ": 1122,
      "ɲ": 1123,
      "ɴ": 1124,
      "ɹ": 1125,
      "ɾ": 1126,
      "ʀ": 1127,
      "ʁ": 1128,
      "ʂ": 1129,
      "ʃ": 1130,
      "ʉ": 1131,
      "ʊ": 1132,
      "ʋ": 1133,
      "ʌ": 1134,
      "ʎ": 1135,
      "ʐ": 1136,
      "ʑ": 1137,
      "ʒ": 1138,
      "ʔ": 1139,
      "ʰ": 1140,
      "ʲ": 1141,
      "ʳ": 1142,
      "ʷ": 1143,
      "ʸ": 1144,
      "ʻ": 1145,
      "ʼ": 1146,
      "ʾ": 1147,
      "ʿ": 1148,
      "ˈ": 1149,
      "ː": 1150,
      "ˡ": 1151,
      "ˢ": 1152,
      "ˣ": 1153,
      "ˤ": 1154,
      "α": 1155,
      "β": 1156,
      "γ": 1157,
      "δ": 1158,
      "ε": 1159,
      "ζ": 1160,
      "η": 1161,
      "θ": 1162,
      "ι": 1163,
      "κ": 1164,
      "λ": 1165,
      "μ": 1166,
      "ν": 1167,
      "ξ": 1168,
      "ο": 1169,
      "π": 1170,
      "ρ": 1171,
      "ς": 1172,
      "σ": 1173,
      "τ": 1174,
      "υ": 1175,
      "φ": 1176,
      "χ": 1177,
      "ψ": 1178,
      "ω": 1179,
      "а": 1180,
      "б": 1181,
      "в": 1182,
      "г": 1183,
      "д": 1184,
      "е": 1185,
      "ж": 1186,
      "з": 1187,
      "и": 1188,
      "к": 1189,
      "л": 1190,
      "м": 1191,
      "н": 1192,
      "о": 1193,
      "п": 1194,
      "р": 1195,
      "с": 1196,
      "т": 1197,
      "у": 1198,
      "ф": 1199,
      "х": 1200,
      "ц": 1201,
      "ч": 1202,
      "ш": 1203,
      "щ": 1204,
      "ъ": 1205,
      "ы": 1206,
      "ь": 1207,
      "э": 1208,
      "ю": 1209,
      "я": 1210,
      "ђ": 1211,
      "є": 1212,
      "і": 1213,
      "ј": 1214,
      "љ": 1215,
      "њ": 1216,
      "ћ": 1217,
      "ӏ": 1218,
      "ա": 1219,
      "բ": 1220,
      "գ": 1221,
      "դ": 1222,
      "ե": 1223,
      "թ": 1224,
      "ի": 1225,
      "լ": 1226,
      "կ": 1227,
      "հ": 1228,
      "մ": 1229,
      "յ": 1230,
      "ն": 1231,
      "ո": 1232,
      "պ": 1233,
      "ս": 1234,
      "վ": 1235,
      "տ": 1236,
      "ր": 1237,
      "ւ": 1238,
      "ք": 1239,
      "־": 1240,
      "א": 1241,
      "ב": 1242,
      "ג": 1243,
      "ד": 1244,
      "ה": 1245,
      "ו": 1246,
      "ז": 1247,
      "ח": 1248,
      "ט": 1249,
      "י": 1250,
      "ך": 1251,
      "כ": 1252,
      "ל": 1253,
      "ם": 1254,
      "מ": 1255,
      "ן": 1256,
      "נ": 1257,
      "ס": 1258,
      "ע": 1259,
      "ף": 1260,
      "פ": 1261,
      "ץ": 1262,
      "צ": 1263,
      "ק": 1264,
      "ר": 1265,
      "ש": 1266,
      "ת": 1267,
      "،": 1268,
      "ء": 1269,
      "ا": 1270,
      "ب": 1271,
      "ة": 1272,
      "ت": 1273,
      "ث": 1274,
      "ج": 1275,
      "ح": 1276,
      "خ": 1277,
      "د": 1278,
      "ذ": 1279,
      "ر": 1280,
      "ز": 1281,
      "س": 1282,
      "ش": 1283,
      "ص": 1284,
      "ض": 1285,
      "ط": 1286,
      "ظ": 1287,
      "ع": 1288,
      "غ": 1289,
      "ـ": 1290,
      "ف": 1291,
      "ق": 1292,
      "ك": 1293,
      "ل": 1294,
      "م": 1295,
      "ن": 1296,
      "ه": 1297,
      "و": 1298,
      "ى": 1299,
      "ي": 1300,
      "ٹ": 1301,
      "پ": 1302,
      "چ": 1303,
      "ک": 1304,
      "گ": 1305,
      "ں": 1306,
      "ھ": 1307,
      "ہ": 1308,
      "ی": 1309,
      "ے": 1310,
      "अ": 1311,
      "आ": 1312,
      "उ": 1313,
      "ए": 1314,
      "क": 1315,
      "ख": 1316,
      "ग": 1317,
      "च": 1318,
      "ज": 1319,
      "ट": 1320,
      "ड": 1321,
      "ण": 1322,
      "त": 1323,
      "थ": 1324,
      "द": 1325,
      "ध": 1326,
      "न": 1327,
      "प": 1328,
      "ब": 1329,
      "भ": 1330,
      "म": 1331,
      "य": 1332,
      "र": 1333,
      "ल": 1334,
      "व": 1335,
      "श": 1336,
      "ष": 1337,
      "स": 1338,
      "ह": 1339,
      "ा": 1340,
      "ि": 1341,
      "ी": 1342,
      "ो": 1343,
      "।": 1344,
      "॥": 1345,
      "ং": 1346,
      "অ": 1347,
      "আ": 1348,
      "ই": 1349,
      "উ": 1350,
      "এ": 1351,
      "ও": 1352,
      "ক": 1353,
      "খ": 1354,
      "গ": 1355,
      "চ": 1356,
      "ছ": 1357,
      "জ": 1358,
      "ট": 1359,
      "ড": 1360,
      "ণ": 1361,
      "ত": 1362,
      "থ": 1363,
      "দ": 1364,
      "ধ": 1365,
      "ন": 1366,
      "প": 1367,
      "ব": 1368,
      "ভ": 1369,
      "ম": 1370,
      "য": 1371,
      "র": 1372,
      "ল": 1373,
      "শ": 1374,
      "ষ": 1375,
      "স": 1376,
      "হ": 1377,
      "া": 1378,
      "ি": 1379,
      "ী": 1380,
      "ে": 1381,
      "க": 1382,
      "ச": 1383,
      "ட": 1384,
      "த": 1385,
      "ந": 1386,
      "ன": 1387,
      "ப": 1388,
      "ம": 1389,
      "ய": 1390,
      "ர": 1391,
      "ல": 1392,
      "ள": 1393,
      "வ": 1394,
      "ா": 1395,
      "ி": 1396,
      "ு": 1397,
      "ே": 1398,
      "ை": 1399,
      "ನ": 1400,
      "ರ": 1401,
      "ಾ": 1402,
      "ක": 1403,
      "ය": 1404,
      "ර": 1405,
      "ල": 1406,
      "ව": 1407,
      "ා": 1408,
      "ก": 1409,
      "ง": 1410,
      "ต": 1411,
      "ท": 1412,
      "น": 1413,
      "พ": 1414,
      "ม": 1415,
      "ย": 1416,
      "ร": 1417,
      "ล": 1418,
      "ว": 1419,
      "ส": 1420,
      "อ": 1421,
      "า": 1422,
      "เ": 1423,
      "་": 1424,
      "།": 1425,
      "ག": 1426,
      "ང": 1427,
      "ད": 1428,
      "ན": 1429,
      "པ": 1430,
      "བ": 1431,
      "མ": 1432,
      "འ": 1433,
      "ར": 1434,
      "ལ": 1435,
      "ས": 1436,
      "မ": 1437,
      "ა": 1438,
      "ბ": 1439,
      "გ": 1440,
      "დ": 1441,
      "ე": 1442,
      "ვ": 1443,
      "თ": 1444,
      "ი": 1445,
      "კ": 1446,
      "ლ": 1447,
      "მ": 1448,
      "ნ": 1449,
      "ო": 1450,
      "რ": 1451,
      "ს": 1452,
      "ტ": 1453,
      "უ": 1454,
      "ᄀ": 1455,
      "ᄂ": 1456,
      "ᄃ": 1457,
      "ᄅ": 1458,
      "ᄆ": 1459,
      "ᄇ": 1460,
      "ᄉ": 1461,
      "ᄊ": 1462,
      "ᄋ": 1463,
      "ᄌ": 1464,
      "ᄎ": 1465,
      "ᄏ": 1466,
      "ᄐ": 1467,
      "ᄑ": 1468,
      "ᄒ": 1469,
      "ᅡ": 1470,
      "ᅢ": 1471,
      "ᅥ": 1472,
      "ᅦ": 1473,
      "ᅧ": 1474,
      "ᅩ": 1475,
      "ᅪ": 1476,
      "ᅭ": 1477,
      "ᅮ": 1478,
      "ᅯ": 1479,
      "ᅲ": 1480,
      "ᅳ": 1481,
      "ᅴ": 1482,
      "ᅵ": 1483,
      "ᆨ": 1484,
      "ᆫ": 1485,
      "ᆯ": 1486,
      "ᆷ": 1487,
      "ᆸ": 1488,
      "ᆼ": 1489,
      "ᴬ": 1490,
      "ᴮ": 1491,
      "ᴰ": 1492,
      "ᴵ": 1493,
      "ᴺ": 1494,
      "ᵀ": 1495,
      "ᵃ": 1496,
      "ᵇ": 1497,
      "ᵈ": 1498,
      "ᵉ": 1499,
      "ᵍ": 1500,
      "ᵏ": 1501,
      "ᵐ": 1502,
      "ᵒ": 1503,
      "ᵖ": 1504,
      "ᵗ": 1505,
      "ᵘ": 1506,
      "ᵢ": 1507,
      "ᵣ": 1508,
      "ᵤ": 1509,
      "ᵥ": 1510,
      "ᶜ": 1511,
      "ᶠ": 1512,
      "‐": 1513,
      "‑": 1514,
      "‒": 1515,
      "–": 1516,
      "—": 1517,
      "―": 1518,
      "‖": 1519,
      "‘": 1520,
      "’": 1521,
      "‚": 1522,
      "“": 1523,
      "”": 1524,
      "„": 1525,
      "†": 1526,
      "‡": 1527,
      "•": 1528,
      "…": 1529,
      "‰": 1530,
      "′": 1531,
      "″": 1532,
      "›": 1533,
      "‿": 1534,
      "⁄": 1535,
      "⁰": 1536,
      "ⁱ": 1537,
      "⁴": 1538,
      "⁵": 1539,
      "⁶": 1540,
      "⁷": 1541,
      "⁸": 1542,
      "⁹": 1543,
      "⁺": 1544,
      "⁻": 1545,
      "ⁿ": 1546,
      "₀": 1547,
      "₁": 1548,
      "₂": 1549,
      "₃": 1550,
      "₄": 1551,
      "₅": 1552,
      "₆": 1553,
      "₇": 1554,
      "₈": 1555,
      "₉": 1556,
      "₊": 1557,
      "₍": 1558,
      "₎": 1559,
      "ₐ": 1560,
      "ₑ": 1561,
      "ₒ": 1562,
      "ₓ": 1563,
      "ₕ": 1564,
      "ₖ": 1565,
      "ₗ": 1566,
      "ₘ": 1567,
      "ₙ": 1568,
      "ₚ": 1569,
      "ₛ": 1570,
      "ₜ": 1571,
      "₤": 1572,
      "₩": 1573,
      "€": 1574,
      "₱": 1575,
      "₹": 1576,
      "ℓ": 1577,
      "№": 1578,
      "ℝ": 1579,
      "™": 1580,
      "⅓": 1581,
      "⅔": 1582,
      "←": 1583,
      "↑": 1584,
      "→": 1585,
      "↓": 1586,
      "↔": 1587,
      "↦": 1588,
      "⇄": 1589,
      "⇌": 1590,
      "⇒": 1591,
      "∂": 1592,
      "∅": 1593,
      "∆": 1594,
      "∇": 1595,
      "∈": 1596,
      "−": 1597,
      "∗": 1598,
      "∘": 1599,
      "√": 1600,
      "∞": 1601,
      "∧": 1602,
      "∨": 1603,
      "∩": 1604,
      "∪": 1605,
      "≈": 1606,
      "≡": 1607,
      "≤": 1608,
      "≥": 1609,
      "⊂": 1610,
      "⊆": 1611,
      "⊕": 1612,
      "⊗": 1613,
      "⋅": 1614,
      "─": 1615,
      "│": 1616,
      "■": 1617,
      "▪": 1618,
      "●": 1619,
      "★": 1620,
      "☆": 1621,
      "☉": 1622,
      "♠": 1623,
      "♣": 1624,
      "♥": 1625,
      "♦": 1626,
      "♭": 1627,
      "♯": 1628,
      "⟨": 1629,
      "⟩": 1630,
      "ⱼ": 1631,
      "⺩": 1632,
      "⺼": 1633,
      "⽥": 1634,
      "、": 1635,
      "。": 1636,
      "〈": 1637,
      "〉": 1638,
      "《": 1639,
      "》": 1640,
      "「": 1641,
      "」": 1642,
      "『": 1643,
      "』": 1644,
      "〜": 1645,
      "あ": 1646,
      "い": 1647,
      "う": 1648,
      "え": 1649,
      "お": 1650,
      "か": 1651,
      "き": 1652,
      "く": 1653,
      "け": 1654,
      "こ": 1655,
      "さ": 1656,
      "し": 1657,
      "す": 1658,
      "せ": 1659,
      "そ": 1660,
      "た": 1661,
      "ち": 1662,
      "っ": 1663,
      "つ": 1664,
      "て": 1665,
      "と": 1666,
      "な": 1667,
      "に": 1668,
      "ぬ": 1669,
      "ね": 1670,
      "の": 1671,
      "は": 1672,
      "ひ": 1673,
      "ふ": 1674,
      "へ": 1675,
      "ほ": 1676,
      "ま": 1677,
      "み": 1678,
      "む": 1679,
      "め": 1680,
      "も": 1681,
      "や": 1682,
      "ゆ": 1683,
      "よ": 1684,
      "ら": 1685,
      "り": 1686,
      "る": 1687,
      "れ": 1688,
      "ろ": 1689,
      "を": 1690,
      "ん": 1691,
      "ァ": 1692,
      "ア": 1693,
      "ィ": 1694,
      "イ": 1695,
      "ウ": 1696,
      "ェ": 1697,
      "エ": 1698,
      "オ": 1699,
      "カ": 1700,
      "キ": 1701,
      "ク": 1702,
      "ケ": 1703,
      "コ": 1704,
      "サ": 1705,
      "シ": 1706,
      "ス": 1707,
      "セ": 1708,
      "タ": 1709,
      "チ": 1710,
      "ッ": 1711,
      "ツ": 1712,
      "テ": 1713,
      "ト": 1714,
      "ナ": 1715,
      "ニ": 1716,
      "ノ": 1717,
      "ハ": 1718,
      "ヒ": 1719,
      "フ": 1720,
      "ヘ": 1721,
      "ホ": 1722,
      "マ": 1723,
      "ミ": 1724,
      "ム": 1725,
      "メ": 1726,
      "モ": 1727,
      "ャ": 1728,
      "ュ": 1729,
      "ョ": 1730,
      "ラ": 1731,
      "リ": 1732,
      "ル": 1733,
      "レ": 1734,
      "ロ": 1735,
      "ワ": 1736,
      "ン": 1737,
      "・": 1738,
      "ー": 1739,
      "一": 1740,
      "三": 1741,
      "上": 1742,
      "下": 1743,
      "不": 1744,
      "世": 1745,
      "中": 1746,
      "主": 1747,
      "久": 1748,
      "之": 1749,
      "也": 1750,
      "事": 1751,
      "二": 1752,
      "五": 1753,
      "井": 1754,
      "京": 1755,
      "人": 1756,
      "亻": 1757,
      "仁": 1758,
      "介": 1759,
      "代": 1760,
      "仮": 1761,
      "伊": 1762,
      "会": 1763,
      "佐": 1764,
      "侍": 1765,
      "保": 1766,
      "信": 1767,
      "健": 1768,
      "元": 1769,
      "光": 1770,
      "八": 1771,
      "公": 1772,
      "内": 1773,
      "出": 1774,
      "分": 1775,
      "前": 1776,
      "劉": 1777,
      "力": 1778,
      "加": 1779,
      "勝": 1780,
      "北": 1781,
      "区": 1782,
      "十": 1783,
      "千": 1784,
      "南": 1785,
      "博": 1786,
      "原": 1787,
      "口": 1788,
      "古": 1789,
      "史": 1790,
      "司": 1791,
      "合": 1792,
      "吉": 1793,
      "同": 1794,
      "名": 1795,
      "和": 1796,
      "囗": 1797,
      "四": 1798,
      "国": 1799,
      "國": 1800,
      "土": 1801,
      "地": 1802,
      "坂": 1803,
      "城": 1804,
      "堂": 1805,
      "場": 1806,
      "士": 1807,
      "夏": 1808,
      "外": 1809,
      "大": 1810,
      "天": 1811,
      "太": 1812,
      "夫": 1813,
      "奈": 1814,
      "女": 1815,
      "子": 1816,
      "学": 1817,
      "宀": 1818,
      "宇": 1819,
      "安": 1820,
      "宗": 1821,
      "定": 1822,
      "宣": 1823,
      "宮": 1824,
      "家": 1825,
      "宿": 1826,
      "寺": 1827,
      "將": 1828,
      "小": 1829,
      "尚": 1830,
      "山": 1831,
      "岡": 1832,
      "島": 1833,
      "崎": 1834,
      "川": 1835,
      "州": 1836,
      "巿": 1837,
      "帝": 1838,
      "平": 1839,
      "年": 1840,
      "幸": 1841,
      "广": 1842,
      "弘": 1843,
      "張": 1844,
      "彳": 1845,
      "後": 1846,
      "御": 1847,
      "德": 1848,
      "心": 1849,
      "忄": 1850,
      "志": 1851,
      "忠": 1852,
      "愛": 1853,
      "成": 1854,
      "我": 1855,
      "戦": 1856,
      "戸": 1857,
      "手": 1858,
      "扌": 1859,
      "政": 1860,
      "文": 1861,
      "新": 1862,
      "方": 1863,
      "日": 1864,
      "明": 1865,
      "星": 1866,
      "春": 1867,
      "昭": 1868,
      "智": 1869,
      "曲": 1870,
      "書": 1871,
      "月": 1872,
      "有": 1873,
      "朝": 1874,
      "木": 1875,
      "本": 1876,
      "李": 1877,
      "村": 1878,
      "東": 1879,
      "松": 1880,
      "林": 1881,
      "森": 1882,
      "楊": 1883,
      "樹": 1884,
      "橋": 1885,
      "歌": 1886,
      "止": 1887,
      "正": 1888,
      "武": 1889,
      "比": 1890,
      "氏": 1891,
      "民": 1892,
      "水": 1893,
      "氵": 1894,
      "氷": 1895,
      "永": 1896,
      "江": 1897,
      "沢": 1898,
      "河": 1899,
      "治": 1900,
      "法": 1901,
      "海": 1902,
      "清": 1903,
      "漢": 1904,
      "瀬": 1905,
      "火": 1906,
      "版": 1907,
      "犬": 1908,
      "王": 1909,
      "生": 1910,
      "田": 1911,
      "男": 1912,
      "疒": 1913,
      "発": 1914,
      "白": 1915,
      "的": 1916,
      "皇": 1917,
      "目": 1918,
      "相": 1919,
      "省": 1920,
      "真": 1921,
      "石": 1922,
      "示": 1923,
      "社": 1924,
      "神": 1925,
      "福": 1926,
      "禾": 1927,
      "秀": 1928,
      "秋": 1929,
      "空": 1930,
      "立": 1931,
      "章": 1932,
      "竹": 1933,
      "糹": 1934,
      "美": 1935,
      "義": 1936,
      "耳": 1937,
      "良": 1938,
      "艹": 1939,
      "花": 1940,
      "英": 1941,
      "華": 1942,
      "葉": 1943,
      "藤": 1944,
      "行": 1945,
      "街": 1946,
      "西": 1947,
      "見": 1948,
      "訁": 1949,
      "語": 1950,
      "谷": 1951,
      "貝": 1952,
      "貴": 1953,
      "車": 1954,
      "軍": 1955,
      "辶": 1956,
      "道": 1957,
      "郎": 1958,
      "郡": 1959,
      "部": 1960,
      "都": 1961,
      "里": 1962,
      "野": 1963,
      "金": 1964,
      "鈴": 1965,
      "镇": 1966,
      "長": 1967,
      "門": 1968,
      "間": 1969,
      "阝": 1970,
      "阿": 1971,
      "陳": 1972,
      "陽": 1973,
      "雄": 1974,
      "青": 1975,
      "面": 1976,
      "風": 1977,
      "食": 1978,
      "香": 1979,
      "馬": 1980,
      "高": 1981,
      "龍": 1982,
      "龸": 1983,
      "ﬁ": 1984,
      "ﬂ": 1985,
      "！": 1986,
      "（": 1987,
      "）": 1988,
      "，": 1989,
      "－": 1990,
      "．": 1991,
      "／": 1992,
      "：": 1993,
      "？": 1994,
      "～": 1995,
      "the": 1996,
      "of": 1997,
      "and": 1998,
      "in": 1999,
      "to": 2000,
      "was": 2001,
      "he": 2002,
      "is": 2003,
      "as": 2004,
      "for": 2005,
      "on": 2006,
      "with": 2007,
      "that": 2008,
      "it": 2009,
      "his": 2010,
      "by": 2011,
      "at": 2012,
      "from": 2013,
      "her": 2014,
      "##s": 2015,
      "she": 2016,
      "you": 2017,
      "had": 2018,
      "an": 2019,
      "were": 2020,
      "but": 2021,
      "be": 2022,
      "this": 2023,
      "are": 2024,
      "not": 2025,
      "my": 2026,
      "they": 2027,
      "one": 2028,
      "which": 2029,
      "or": 2030,
      "have": 2031,
      "him": 2032,
      "me": 2033,
      "first": 2034,
      "all": 2035,
      "also": 2036,
      "their": 2037,
      "has": 2038,
      "up": 2039,
      "who": 2040,
      "out": 2041,
      "been": 2042,
      "when": 2043,
      "after": 2044,
      "there": 2045,
      "into": 2046,
      "new": 2047,
      "two": 2048,
      "its": 2049,
      "##a": 2050,
      "time": 2051,
      "would": 2052,
      "no": 2053,
      "what": 2054,
      "about": 2055,
      "said": 2056,
      "we": 2057,
      "over": 2058,
      "then": 2059,
      "other": 2060,
      "so": 2061,
      "more": 2062,
      "##e": 2063,
      "can": 2064,
      "if": 2065,
      "like": 2066,
      "back": 2067,
      "them": 2068,
      "only": 2069,
      "some": 2070,
      "could": 2071,
      "##i": 2072,
      "where": 2073,
      "just": 2074,
      "##ing": 2075,
      "during": 2076,
      "before": 2077,
      "##n": 2078,
      "do": 2079,
      "##o": 2080,
      "made": 2081,
      "school": 2082,
      "through": 2083,
      "than": 2084,
      "now": 2085,
      "years": 2086,
      "most": 2087,
      "world": 2088,
      "may": 2089,
      "between": 2090,
      "down": 2091,
      "well": 2092,
      "three": 2093,
      "##d": 2094,
      "year": 2095,
      "while": 2096,
      "will": 2097,
      "##ed": 2098,
      "##r": 2099,
      "##y": 2100,
      "later": 2101,
      "##t": 2102,
      "city": 2103,
      "under": 2104,
      "around": 2105,
      "did": 2106,
      "such": 2107,
      "being": 2108,
      "used": 2109,
      "state": 2110,
      "people": 2111,
      "part": 2112,
      "know": 2113,
      "against": 2114,
      "your": 2115,
      "many": 2116,
      "second": 2117,
      "university": 2118,
      "both": 2119,
      "national": 2120,
      "##er": 2121,
      "these": 2122,
      "don": 2123,
      "known": 2124,
      "off": 2125,
      "way": 2126,
      "until": 2127,
      "re": 2128,
      "how": 2129,
      "even": 2130,
      "get": 2131,
      "head": 2132,
      "...": 2133,
      "didn": 2134,
      "##ly": 2135,
      "team": 2136,
      "american": 2137,
      "because": 2138,
      "de": 2139,
      "##l": 2140,
      "born": 2141,
      "united": 2142,
      "film": 2143,
      "since": 2144,
      "still": 2145,
      "long": 2146,
      "work": 2147,
      "south": 2148,
      "us": 2149,
      "became": 2150,
      "any": 2151,
      "high": 2152,
      "again": 2153,
      "day": 2154,
      "family": 2155,
      "see": 2156,
      "right": 2157,
      "man": 2158,
      "eyes": 2159,
      "house": 2160,
      "season": 2161,
      "war": 2162,
      "states": 2163,
      "including": 2164,
      "took": 2165,
      "life": 2166,
      "north": 2167,
      "same": 2168,
      "each": 2169,
      "called": 2170,
      "name": 2171,
      "much": 2172,
      "place": 2173,
      "however": 2174,
      "go": 2175,
      "four": 2176,
      "group": 2177,
      "another": 2178,
      "found": 2179,
      "won": 2180,
      "area": 2181,
      "here": 2182,
      "going": 2183,
      "10": 2184,
      "away": 2185,
      "series": 2186,
      "left": 2187,
      "home": 2188,
      "music": 2189,
      "best": 2190,
      "make": 2191,
      "hand": 2192,
      "number": 2193,
      "company": 2194,
      "several": 2195,
      "never": 2196,
      "last": 2197,
      "john": 2198,
      "000": 2199,
      "very": 2200,
      "album": 2201,
      "take": 2202,
      "end": 2203,
      "good": 2204,
      "too": 2205,
      "following": 2206,
      "released": 2207,
      "game": 2208,
      "played": 2209,
      "little": 2210,
      "began": 2211,
      "district": 2212,
      "##m": 2213,
      "old": 2214,
      "want": 2215,
      "those": 2216,
      "side": 2217,
      "held": 2218,
      "own": 2219,
      "early": 2220,
      "county": 2221,
      "ll": 2222,
      "league": 2223,
      "use": 2224,
      "west": 2225,
      "##u": 2226,
      "face": 2227,
      "think": 2228,
      "##es": 2229,
      "2010": 2230,
      "government": 2231,
      "##h": 2232,
      "march": 2233,
      "came": 2234,
      "small": 2235,
      "general": 2236,
      "town": 2237,
      "june": 2238,
      "##on": 2239,
      "line": 2240,
      "based": 2241,
      "something": 2242,
      "##k": 2243,
      "september": 2244,
      "thought": 2245,
      "looked": 2246,
      "along": 2247,
      "international": 2248,
      "2011": 2249,
      "air": 2250,
      "july": 2251,
      "club": 2252,
      "went": 2253,
      "january": 2254,
      "october": 2255,
      "our": 2256,
      "august": 2257,
      "april": 2258,
      "york": 2259,
      "12": 2260,
      "few": 2261,
      "2012": 2262,
      "2008": 2263,
      "east": 2264,
      "show": 2265,
      "member": 2266,
      "college": 2267,
      "2009": 2268,
      "father": 2269,
      "public": 2270,
      "##us": 2271,
      "come": 2272,
      "men": 2273,
      "five": 2274,
      "set": 2275,
      "station": 2276,
      "church": 2277,
      "##c": 2278,
      "next": 2279,
      "former": 2280,
      "november": 2281,
      "room": 2282,
      "party": 2283,
      "located": 2284,
      "december": 2285,
      "2013": 2286,
      "age": 2287,
      "got": 2288,
      "2007": 2289,
      "##g": 2290,
      "system": 2291,
      "let": 2292,
      "love": 2293,
      "2006": 2294,
      "though": 2295,
      "every": 2296,
      "2014": 2297,
      "look": 2298,
      "song": 2299,
      "water": 2300,
      "century": 2301,
      "without": 2302,
      "body": 2303,
      "black": 2304,
      "night": 2305,
      "within": 2306,
      "great": 2307,
      "women": 2308,
      "single": 2309,
      "ve": 2310,
      "building": 2311,
      "large": 2312,
      "population": 2313,
      "river": 2314,
      "named": 2315,
      "band": 2316,
      "white": 2317,
      "started": 2318,
      "##an": 2319,
      "once": 2320,
      "15": 2321,
      "20": 2322,
      "should": 2323,
      "18": 2324,
      "2015": 2325,
      "service": 2326,
      "top": 2327,
      "built": 2328,
      "british": 2329,
      "open": 2330,
      "death": 2331,
      "king": 2332,
      "moved": 2333,
      "local": 2334,
      "times": 2335,
      "children": 2336,
      "february": 2337,
      "book": 2338,
      "why": 2339,
      "11": 2340,
      "door": 2341,
      "need": 2342,
      "president": 2343,
      "order": 2344,
      "final": 2345,
      "road": 2346,
      "wasn": 2347,
      "although": 2348,
      "due": 2349,
      "major": 2350,
      "died": 2351,
      "village": 2352,
      "third": 2353,
      "knew": 2354,
      "2016": 2355,
      "asked": 2356,
      "turned": 2357,
      "st": 2358,
      "wanted": 2359,
      "say": 2360,
      "##p": 2361,
      "together": 2362,
      "received": 2363,
      "main": 2364,
      "son": 2365,
      "served": 2366,
      "different": 2367,
      "##en": 2368,
      "behind": 2369,
      "himself": 2370,
      "felt": 2371,
      "members": 2372,
      "power": 2373,
      "football": 2374,
      "law": 2375,
      "voice": 2376,
      "play": 2377,
      "##in": 2378,
      "near": 2379,
      "park": 2380,
      "history": 2381,
      "30": 2382,
      "having": 2383,
      "2005": 2384,
      "16": 2385,
      "##man": 2386,
      "saw": 2387,
      "mother": 2388,
      "##al": 2389,
      "army": 2390,
      "point": 2391,
      "front": 2392,
      "help": 2393,
      "english": 2394,
      "street": 2395,
      "art": 2396,
      "late": 2397,
      "hands": 2398,
      "games": 2399,
      "award": 2400,
      "##ia": 2401,
      "young": 2402,
      "14": 2403,
      "put": 2404,
      "published": 2405,
      "country": 2406,
      "division": 2407,
      "across": 2408,
      "told": 2409,
      "13": 2410,
      "often": 2411,
      "ever": 2412,
      "french": 2413,
      "london": 2414,
      "center": 2415,
      "six": 2416,
      "red": 2417,
      "2017": 2418,
      "led": 2419,
      "days": 2420,
      "include": 2421,
      "light": 2422,
      "25": 2423,
      "find": 2424,
      "tell": 2425,
      "among": 2426,
      "species": 2427,
      "really": 2428,
      "according": 2429,
      "central": 2430,
      "half": 2431,
      "2004": 2432,
      "form": 2433,
      "original": 2434,
      "gave": 2435,
      "office": 2436,
      "making": 2437,
      "enough": 2438,
      "lost": 2439,
      "full": 2440,
      "opened": 2441,
      "must": 2442,
      "included": 2443,
      "live": 2444,
      "given": 2445,
      "german": 2446,
      "player": 2447,
      "run": 2448,
      "business": 2449,
      "woman": 2450,
      "community": 2451,
      "cup": 2452,
      "might": 2453,
      "million": 2454,
      "land": 2455,
      "2000": 2456,
      "court": 2457,
      "development": 2458,
      "17": 2459,
      "short": 2460,
      "round": 2461,
      "ii": 2462,
      "km": 2463,
      "seen": 2464,
      "class": 2465,
      "story": 2466,
      "always": 2467,
      "become": 2468,
      "sure": 2469,
      "research": 2470,
      "almost": 2471,
      "director": 2472,
      "council": 2473,
      "la": 2474,
      "##2": 2475,
      "career": 2476,
      "things": 2477,
      "using": 2478,
      "island": 2479,
      "##z": 2480,
      "couldn": 2481,
      "car": 2482,
      "##is": 2483,
      "24": 2484,
      "close": 2485,
      "force": 2486,
      "##1": 2487,
      "better": 2488,
      "free": 2489,
      "support": 2490,
      "control": 2491,
      "field": 2492,
      "students": 2493,
      "2003": 2494,
      "education": 2495,
      "married": 2496,
      "##b": 2497,
      "nothing": 2498,
      "worked": 2499,
      "others": 2500,
      "record": 2501,
      "big": 2502,
      "inside": 2503,
      "level": 2504,
      "anything": 2505,
      "continued": 2506,
      "give": 2507,
      "james": 2508,
      "##3": 2509,
      "military": 2510,
      "established": 2511,
      "non": 2512,
      "returned": 2513,
      "feel": 2514,
      "does": 2515,
      "title": 2516,
      "written": 2517,
      "thing": 2518,
      "feet": 2519,
      "william": 2520,
      "far": 2521,
      "co": 2522,
      "association": 2523,
      "hard": 2524,
      "already": 2525,
      "2002": 2526,
      "##ra": 2527,
      "championship": 2528,
      "human": 2529,
      "western": 2530,
      "100": 2531,
      "##na": 2532,
      "department": 2533,
      "hall": 2534,
      "role": 2535,
      "various": 2536,
      "production": 2537,
      "21": 2538,
      "19": 2539,
      "heart": 2540,
      "2001": 2541,
      "living": 2542,
      "fire": 2543,
      "version": 2544,
      "##ers": 2545,
      "##f": 2546,
      "television": 2547,
      "royal": 2548,
      "##4": 2549,
      "produced": 2550,
      "working": 2551,
      "act": 2552,
      "case": 2553,
      "society": 2554,
      "region": 2555,
      "present": 2556,
      "radio": 2557,
      "period": 2558,
      "looking": 2559,
      "least": 2560,
      "total": 2561,
      "keep": 2562,
      "england": 2563,
      "wife": 2564,
      "program": 2565,
      "per": 2566,
      "brother": 2567,
      "mind": 2568,
      "special": 2569,
      "22": 2570,
      "##le": 2571,
      "am": 2572,
      "works": 2573,
      "soon": 2574,
      "##6": 2575,
      "political": 2576,
      "george": 2577,
      "services": 2578,
      "taken": 2579,
      "created": 2580,
      "##7": 2581,
      "further": 2582,
      "able": 2583,
      "reached": 2584,
      "david": 2585,
      "union": 2586,
      "joined": 2587,
      "upon": 2588,
      "done": 2589,
      "important": 2590,
      "social": 2591,
      "information": 2592,
      "either": 2593,
      "##ic": 2594,
      "##x": 2595,
      "appeared": 2596,
      "position": 2597,
      "ground": 2598,
      "lead": 2599,
      "rock": 2600,
      "dark": 2601,
      "election": 2602,
      "23": 2603,
      "board": 2604,
      "france": 2605,
      "hair": 2606,
      "course": 2607,
      "arms": 2608,
      "site": 2609,
      "police": 2610,
      "girl": 2611,
      "instead": 2612,
      "real": 2613,
      "sound": 2614,
      "##v": 2615,
      "words": 2616,
      "moment": 2617,
      "##te": 2618,
      "someone": 2619,
      "##8": 2620,
      "summer": 2621,
      "project": 2622,
      "announced": 2623,
      "san": 2624,
      "less": 2625,
      "wrote": 2626,
      "past": 2627,
      "followed": 2628,
      "##5": 2629,
      "blue": 2630,
      "founded": 2631,
      "al": 2632,
      "finally": 2633,
      "india": 2634,
      "taking": 2635,
      "records": 2636,
      "america": 2637,
      "##ne": 2638,
      "1999": 2639,
      "design": 2640,
      "considered": 2641,
      "northern": 2642,
      "god": 2643,
      "stop": 2644,
      "battle": 2645,
      "toward": 2646,
      "european": 2647,
      "outside": 2648,
      "described": 2649,
      "track": 2650,
      "today": 2651,
      "playing": 2652,
      "language": 2653,
      "28": 2654,
      "call": 2655,
      "26": 2656,
      "heard": 2657,
      "professional": 2658,
      "low": 2659,
      "australia": 2660,
      "miles": 2661,
      "california": 2662,
      "win": 2663,
      "yet": 2664,
      "green": 2665,
      "##ie": 2666,
      "trying": 2667,
      "blood": 2668,
      "##ton": 2669,
      "southern": 2670,
      "science": 2671,
      "maybe": 2672,
      "everything": 2673,
      "match": 2674,
      "square": 2675,
      "27": 2676,
      "mouth": 2677,
      "video": 2678,
      "race": 2679,
      "recorded": 2680,
      "leave": 2681,
      "above": 2682,
      "##9": 2683,
      "daughter": 2684,
      "points": 2685,
      "space": 2686,
      "1998": 2687,
      "museum": 2688,
      "change": 2689,
      "middle": 2690,
      "common": 2691,
      "##0": 2692,
      "move": 2693,
      "tv": 2694,
      "post": 2695,
      "##ta": 2696,
      "lake": 2697,
      "seven": 2698,
      "tried": 2699,
      "elected": 2700,
      "closed": 2701,
      "ten": 2702,
      "paul": 2703,
      "minister": 2704,
      "##th": 2705,
      "months": 2706,
      "start": 2707,
      "chief": 2708,
      "return": 2709,
      "canada": 2710,
      "person": 2711,
      "sea": 2712,
      "release": 2713,
      "similar": 2714,
      "modern": 2715,
      "brought": 2716,
      "rest": 2717,
      "hit": 2718,
      "formed": 2719,
      "mr": 2720,
      "##la": 2721,
      "1997": 2722,
      "floor": 2723,
      "event": 2724,
      "doing": 2725,
      "thomas": 2726,
      "1996": 2727,
      "robert": 2728,
      "care": 2729,
      "killed": 2730,
      "training": 2731,
      "star": 2732,
      "week": 2733,
      "needed": 2734,
      "turn": 2735,
      "finished": 2736,
      "railway": 2737,
      "rather": 2738,
      "news": 2739,
      "health": 2740,
      "sent": 2741,
      "example": 2742,
      "ran": 2743,
      "term": 2744,
      "michael": 2745,
      "coming": 2746,
      "currently": 2747,
      "yes": 2748,
      "forces": 2749,
      "despite": 2750,
      "gold": 2751,
      "areas": 2752,
      "50": 2753,
      "stage": 2754,
      "fact": 2755,
      "29": 2756,
      "dead": 2757,
      "says": 2758,
      "popular": 2759,
      "2018": 2760,
      "originally": 2761,
      "germany": 2762,
      "probably": 2763,
      "developed": 2764,
      "result": 2765,
      "pulled": 2766,
      "friend": 2767,
      "stood": 2768,
      "money": 2769,
      "running": 2770,
      "mi": 2771,
      "signed": 2772,
      "word": 2773,
      "songs": 2774,
      "child": 2775,
      "eventually": 2776,
      "met": 2777,
      "tour": 2778,
      "average": 2779,
      "teams": 2780,
      "minutes": 2781,
      "festival": 2782,
      "current": 2783,
      "deep": 2784,
      "kind": 2785,
      "1995": 2786,
      "decided": 2787,
      "usually": 2788,
      "eastern": 2789,
      "seemed": 2790,
      "##ness": 2791,
      "episode": 2792,
      "bed": 2793,
      "added": 2794,
      "table": 2795,
      "indian": 2796,
      "private": 2797,
      "charles": 2798,
      "route": 2799,
      "available": 2800,
      "idea": 2801,
      "throughout": 2802,
      "centre": 2803,
      "addition": 2804,
      "appointed": 2805,
      "style": 2806,
      "1994": 2807,
      "books": 2808,
      "eight": 2809,
      "construction": 2810,
      "press": 2811,
      "mean": 2812,
      "wall": 2813,
      "friends": 2814,
      "remained": 2815,
      "schools": 2816,
      "study": 2817,
      "##ch": 2818,
      "##um": 2819,
      "institute": 2820,
      "oh": 2821,
      "chinese": 2822,
      "sometimes": 2823,
      "events": 2824,
      "possible": 2825,
      "1992": 2826,
      "australian": 2827,
      "type": 2828,
      "brown": 2829,
      "forward": 2830,
      "talk": 2831,
      "process": 2832,
      "food": 2833,
      "debut": 2834,
      "seat": 2835,
      "performance": 2836,
      "committee": 2837,
      "features": 2838,
      "character": 2839,
      "arts": 2840,
      "herself": 2841,
      "else": 2842,
      "lot": 2843,
      "strong": 2844,
      "russian": 2845,
      "range": 2846,
      "hours": 2847,
      "peter": 2848,
      "arm": 2849,
      "##da": 2850,
      "morning": 2851,
      "dr": 2852,
      "sold": 2853,
      "##ry": 2854,
      "quickly": 2855,
      "directed": 2856,
      "1993": 2857,
      "guitar": 2858,
      "china": 2859,
      "##w": 2860,
      "31": 2861,
      "list": 2862,
      "##ma": 2863,
      "performed": 2864,
      "media": 2865,
      "uk": 2866,
      "players": 2867,
      "smile": 2868,
      "##rs": 2869,
      "myself": 2870,
      "40": 2871,
      "placed": 2872,
      "coach": 2873,
      "province": 2874,
      "towards": 2875,
      "wouldn": 2876,
      "leading": 2877,
      "whole": 2878,
      "boy": 2879,
      "official": 2880,
      "designed": 2881,
      "grand": 2882,
      "census": 2883,
      "##el": 2884,
      "europe": 2885,
      "attack": 2886,
      "japanese": 2887,
      "henry": 2888,
      "1991": 2889,
      "##re": 2890,
      "##os": 2891,
      "cross": 2892,
      "getting": 2893,
      "alone": 2894,
      "action": 2895,
      "lower": 2896,
      "network": 2897,
      "wide": 2898,
      "washington": 2899,
      "japan": 2900,
      "1990": 2901,
      "hospital": 2902,
      "believe": 2903,
      "changed": 2904,
      "sister": 2905,
      "##ar": 2906,
      "hold": 2907,
      "gone": 2908,
      "sir": 2909,
      "hadn": 2910,
      "ship": 2911,
      "##ka": 2912,
      "studies": 2913,
      "academy": 2914,
      "shot": 2915,
      "rights": 2916,
      "below": 2917,
      "base": 2918,
      "bad": 2919,
      "involved": 2920,
      "kept": 2921,
      "largest": 2922,
      "##ist": 2923,
      "bank": 2924,
      "future": 2925,
      "especially": 2926,
      "beginning": 2927,
      "mark": 2928,
      "movement": 2929,
      "section": 2930,
      "female": 2931,
      "magazine": 2932,
      "plan": 2933,
      "professor": 2934,
      "lord": 2935,
      "longer": 2936,
      "##ian": 2937,
      "sat": 2938,
      "walked": 2939,
      "hill": 2940,
      "actually": 2941,
      "civil": 2942,
      "energy": 2943,
      "model": 2944,
      "families": 2945,
      "size": 2946,
      "thus": 2947,
      "aircraft": 2948,
      "completed": 2949,
      "includes": 2950,
      "data": 2951,
      "captain": 2952,
      "##or": 2953,
      "fight": 2954,
      "vocals": 2955,
      "featured": 2956,
      "richard": 2957,
      "bridge": 2958,
      "fourth": 2959,
      "1989": 2960,
      "officer": 2961,
      "stone": 2962,
      "hear": 2963,
      "##ism": 2964,
      "means": 2965,
      "medical": 2966,
      "groups": 2967,
      "management": 2968,
      "self": 2969,
      "lips": 2970,
      "competition": 2971,
      "entire": 2972,
      "lived": 2973,
      "technology": 2974,
      "leaving": 2975,
      "federal": 2976,
      "tournament": 2977,
      "bit": 2978,
      "passed": 2979,
      "hot": 2980,
      "independent": 2981,
      "awards": 2982,
      "kingdom": 2983,
      "mary": 2984,
      "spent": 2985,
      "fine": 2986,
      "doesn": 2987,
      "reported": 2988,
      "##ling": 2989,
      "jack": 2990,
      "fall": 2991,
      "raised": 2992,
      "itself": 2993,
      "stay": 2994,
      "true": 2995,
      "studio": 2996,
      "1988": 2997,
      "sports": 2998,
      "replaced": 2999,
      "paris": 3000,
      "systems": 3001,
      "saint": 3002,
      "leader": 3003,
      "theatre": 3004,
      "whose": 3005,
      "market": 3006,
      "capital": 3007,
      "parents": 3008,
      "spanish": 3009,
      "canadian": 3010,
      "earth": 3011,
      "##ity": 3012,
      "cut": 3013,
      "degree": 3014,
      "writing": 3015,
      "bay": 3016,
      "christian": 3017,
      "awarded": 3018,
      "natural": 3019,
      "higher": 3020,
      "bill": 3021,
      "##as": 3022,
      "coast": 3023,
      "provided": 3024,
      "previous": 3025,
      "senior": 3026,
      "ft": 3027,
      "valley": 3028,
      "organization": 3029,
      "stopped": 3030,
      "onto": 3031,
      "countries": 3032,
      "parts": 3033,
      "conference": 3034,
      "queen": 3035,
      "security": 3036,
      "interest": 3037,
      "saying": 3038,
      "allowed": 3039,
      "master": 3040,
      "earlier": 3041,
      "phone": 3042,
      "matter": 3043,
      "smith": 3044,
      "winning": 3045,
      "try": 3046,
      "happened": 3047,
      "moving": 3048,
      "campaign": 3049,
      "los": 3050,
      "##ley": 3051,
      "breath": 3052,
      "nearly": 3053,
      "mid": 3054,
      "1987": 3055,
      "certain": 3056,
      "girls": 3057,
      "date": 3058,
      "italian": 3059,
      "african": 3060,
      "standing": 3061,
      "fell": 3062,
      "artist": 3063,
      "##ted": 3064,
      "shows": 3065,
      "deal": 3066,
      "mine": 3067,
      "industry": 3068,
      "1986": 3069,
      "##ng": 3070,
      "everyone": 3071,
      "republic": 3072,
      "provide": 3073,
      "collection": 3074,
      "library": 3075,
      "student": 3076,
      "##ville": 3077,
      "primary": 3078,
      "owned": 3079,
      "older": 3080,
      "via": 3081,
      "heavy": 3082,
      "1st": 3083,
      "makes": 3084,
      "##able": 3085,
      "attention": 3086,
      "anyone": 3087,
      "africa": 3088,
      "##ri": 3089,
      "stated": 3090,
      "length": 3091,
      "ended": 3092,
      "fingers": 3093,
      "command": 3094,
      "staff": 3095,
      "skin": 3096,
      "foreign": 3097,
      "opening": 3098,
      "governor": 3099,
      "okay": 3100,
      "medal": 3101,
      "kill": 3102,
      "sun": 3103,
      "cover": 3104,
      "job": 3105,
      "1985": 3106,
      "introduced": 3107,
      "chest": 3108,
      "hell": 3109,
      "feeling": 3110,
      "##ies": 3111,
      "success": 3112,
      "meet": 3113,
      "reason": 3114,
      "standard": 3115,
      "meeting": 3116,
      "novel": 3117,
      "1984": 3118,
      "trade": 3119,
      "source": 3120,
      "buildings": 3121,
      "##land": 3122,
      "rose": 3123,
      "guy": 3124,
      "goal": 3125,
      "##ur": 3126,
      "chapter": 3127,
      "native": 3128,
      "husband": 3129,
      "previously": 3130,
      "unit": 3131,
      "limited": 3132,
      "entered": 3133,
      "weeks": 3134,
      "producer": 3135,
      "operations": 3136,
      "mountain": 3137,
      "takes": 3138,
      "covered": 3139,
      "forced": 3140,
      "related": 3141,
      "roman": 3142,
      "complete": 3143,
      "successful": 3144,
      "key": 3145,
      "texas": 3146,
      "cold": 3147,
      "##ya": 3148,
      "channel": 3149,
      "1980": 3150,
      "traditional": 3151,
      "films": 3152,
      "dance": 3153,
      "clear": 3154,
      "approximately": 3155,
      "500": 3156,
      "nine": 3157,
      "van": 3158,
      "prince": 3159,
      "question": 3160,
      "active": 3161,
      "tracks": 3162,
      "ireland": 3163,
      "regional": 3164,
      "silver": 3165,
      "author": 3166,
      "personal": 3167,
      "sense": 3168,
      "operation": 3169,
      "##ine": 3170,
      "economic": 3171,
      "1983": 3172,
      "holding": 3173,
      "twenty": 3174,
      "isbn": 3175,
      "additional": 3176,
      "speed": 3177,
      "hour": 3178,
      "edition": 3179,
      "regular": 3180,
      "historic": 3181,
      "places": 3182,
      "whom": 3183,
      "shook": 3184,
      "movie": 3185,
      "km²": 3186,
      "secretary": 3187,
      "prior": 3188,
      "report": 3189,
      "chicago": 3190,
      "read": 3191,
      "foundation": 3192,
      "view": 3193,
      "engine": 3194,
      "scored": 3195,
      "1982": 3196,
      "units": 3197,
      "ask": 3198,
      "airport": 3199,
      "property": 3200,
      "ready": 3201,
      "immediately": 3202,
      "lady": 3203,
      "month": 3204,
      "listed": 3205,
      "contract": 3206,
      "##de": 3207,
      "manager": 3208,
      "themselves": 3209,
      "lines": 3210,
      "##ki": 3211,
      "navy": 3212,
      "writer": 3213,
      "meant": 3214,
      "##ts": 3215,
      "runs": 3216,
      "##ro": 3217,
      "practice": 3218,
      "championships": 3219,
      "singer": 3220,
      "glass": 3221,
      "commission": 3222,
      "required": 3223,
      "forest": 3224,
      "starting": 3225,
      "culture": 3226,
      "generally": 3227,
      "giving": 3228,
      "access": 3229,
      "attended": 3230,
      "test": 3231,
      "couple": 3232,
      "stand": 3233,
      "catholic": 3234,
      "martin": 3235,
      "caught": 3236,
      "executive": 3237,
      "##less": 3238,
      "eye": 3239,
      "##ey": 3240,
      "thinking": 3241,
      "chair": 3242,
      "quite": 3243,
      "shoulder": 3244,
      "1979": 3245,
      "hope": 3246,
      "decision": 3247,
      "plays": 3248,
      "defeated": 3249,
      "municipality": 3250,
      "whether": 3251,
      "structure": 3252,
      "offered": 3253,
      "slowly": 3254,
      "pain": 3255,
      "ice": 3256,
      "direction": 3257,
      "##ion": 3258,
      "paper": 3259,
      "mission": 3260,
      "1981": 3261,
      "mostly": 3262,
      "200": 3263,
      "noted": 3264,
      "individual": 3265,
      "managed": 3266,
      "nature": 3267,
      "lives": 3268,
      "plant": 3269,
      "##ha": 3270,
      "helped": 3271,
      "except": 3272,
      "studied": 3273,
      "computer": 3274,
      "figure": 3275,
      "relationship": 3276,
      "issue": 3277,
      "significant": 3278,
      "loss": 3279,
      "die": 3280,
      "smiled": 3281,
      "gun": 3282,
      "ago": 3283,
      "highest": 3284,
      "1972": 3285,
      "##am": 3286,
      "male": 3287,
      "bring": 3288,
      "goals": 3289,
      "mexico": 3290,
      "problem": 3291,
      "distance": 3292,
      "commercial": 3293,
      "completely": 3294,
      "location": 3295,
      "annual": 3296,
      "famous": 3297,
      "drive": 3298,
      "1976": 3299,
      "neck": 3300,
      "1978": 3301,
      "surface": 3302,
      "caused": 3303,
      "italy": 3304,
      "understand": 3305,
      "greek": 3306,
      "highway": 3307,
      "wrong": 3308,
      "hotel": 3309,
      "comes": 3310,
      "appearance": 3311,
      "joseph": 3312,
      "double": 3313,
      "issues": 3314,
      "musical": 3315,
      "companies": 3316,
      "castle": 3317,
      "income": 3318,
      "review": 3319,
      "assembly": 3320,
      "bass": 3321,
      "initially": 3322,
      "parliament": 3323,
      "artists": 3324,
      "experience": 3325,
      "1974": 3326,
      "particular": 3327,
      "walk": 3328,
      "foot": 3329,
      "engineering": 3330,
      "talking": 3331,
      "window": 3332,
      "dropped": 3333,
      "##ter": 3334,
      "miss": 3335,
      "baby": 3336,
      "boys": 3337,
      "break": 3338,
      "1975": 3339,
      "stars": 3340,
      "edge": 3341,
      "remember": 3342,
      "policy": 3343,
      "carried": 3344,
      "train": 3345,
      "stadium": 3346,
      "bar": 3347,
      "sex": 3348,
      "angeles": 3349,
      "evidence": 3350,
      "##ge": 3351,
      "becoming": 3352,
      "assistant": 3353,
      "soviet": 3354,
      "1977": 3355,
      "upper": 3356,
      "step": 3357,
      "wing": 3358,
      "1970": 3359,
      "youth": 3360,
      "financial": 3361,
      "reach": 3362,
      "##ll": 3363,
      "actor": 3364,
      "numerous": 3365,
      "##se": 3366,
      "##st": 3367,
      "nodded": 3368,
      "arrived": 3369,
      "##ation": 3370,
      "minute": 3371,
      "##nt": 3372,
      "believed": 3373,
      "sorry": 3374,
      "complex": 3375,
      "beautiful": 3376,
      "victory": 3377,
      "associated": 3378,
      "temple": 3379,
      "1968": 3380,
      "1973": 3381,
      "chance": 3382,
      "perhaps": 3383,
      "metal": 3384,
      "##son": 3385,
      "1945": 3386,
      "bishop": 3387,
      "##et": 3388,
      "lee": 3389,
      "launched": 3390,
      "particularly": 3391,
      "tree": 3392,
      "le": 3393,
      "retired": 3394,
      "subject": 3395,
      "prize": 3396,
      "contains": 3397,
      "yeah": 3398,
      "theory": 3399,
      "empire": 3400,
      "##ce": 3401,
      "suddenly": 3402,
      "waiting": 3403,
      "trust": 3404,
      "recording": 3405,
      "##to": 3406,
      "happy": 3407,
      "terms": 3408,
      "camp": 3409,
      "champion": 3410,
      "1971": 3411,
      "religious": 3412,
      "pass": 3413,
      "zealand": 3414,
      "names": 3415,
      "2nd": 3416,
      "port": 3417,
      "ancient": 3418,
      "tom": 3419,
      "corner": 3420,
      "represented": 3421,
      "watch": 3422,
      "legal": 3423,
      "anti": 3424,
      "justice": 3425,
      "cause": 3426,
      "watched": 3427,
      "brothers": 3428,
      "45": 3429,
      "material": 3430,
      "changes": 3431,
      "simply": 3432,
      "response": 3433,
      "louis": 3434,
      "fast": 3435,
      "##ting": 3436,
      "answer": 3437,
      "60": 3438,
      "historical": 3439,
      "1969": 3440,
      "stories": 3441,
      "straight": 3442,
      "create": 3443,
      "feature": 3444,
      "increased": 3445,
      "rate": 3446,
      "administration": 3447,
      "virginia": 3448,
      "el": 3449,
      "activities": 3450,
      "cultural": 3451,
      "overall": 3452,
      "winner": 3453,
      "programs": 3454,
      "basketball": 3455,
      "legs": 3456,
      "guard": 3457,
      "beyond": 3458,
      "cast": 3459,
      "doctor": 3460,
      "mm": 3461,
      "flight": 3462,
      "results": 3463,
      "remains": 3464,
      "cost": 3465,
      "effect": 3466,
      "winter": 3467,
      "##ble": 3468,
      "larger": 3469,
      "islands": 3470,
      "problems": 3471,
      "chairman": 3472,
      "grew": 3473,
      "commander": 3474,
      "isn": 3475,
      "1967": 3476,
      "pay": 3477,
      "failed": 3478,
      "selected": 3479,
      "hurt": 3480,
      "fort": 3481,
      "box": 3482,
      "regiment": 3483,
      "majority": 3484,
      "journal": 3485,
      "35": 3486,
      "edward": 3487,
      "plans": 3488,
      "##ke": 3489,
      "##ni": 3490,
      "shown": 3491,
      "pretty": 3492,
      "irish": 3493,
      "characters": 3494,
      "directly": 3495,
      "scene": 3496,
      "likely": 3497,
      "operated": 3498,
      "allow": 3499,
      "spring": 3500,
      "##j": 3501,
      "junior": 3502,
      "matches": 3503,
      "looks": 3504,
      "mike": 3505,
      "houses": 3506,
      "fellow": 3507,
      "##tion": 3508,
      "beach": 3509,
      "marriage": 3510,
      "##ham": 3511,
      "##ive": 3512,
      "rules": 3513,
      "oil": 3514,
      "65": 3515,
      "florida": 3516,
      "expected": 3517,
      "nearby": 3518,
      "congress": 3519,
      "sam": 3520,
      "peace": 3521,
      "recent": 3522,
      "iii": 3523,
      "wait": 3524,
      "subsequently": 3525,
      "cell": 3526,
      "##do": 3527,
      "variety": 3528,
      "serving": 3529,
      "agreed": 3530,
      "please": 3531,
      "poor": 3532,
      "joe": 3533,
      "pacific": 3534,
      "attempt": 3535,
      "wood": 3536,
      "democratic": 3537,
      "piece": 3538,
      "prime": 3539,
      "##ca": 3540,
      "rural": 3541,
      "mile": 3542,
      "touch": 3543,
      "appears": 3544,
      "township": 3545,
      "1964": 3546,
      "1966": 3547,
      "soldiers": 3548,
      "##men": 3549,
      "##ized": 3550,
      "1965": 3551,
      "pennsylvania": 3552,
      "closer": 3553,
      "fighting": 3554,
      "claimed": 3555,
      "score": 3556,
      "jones": 3557,
      "physical": 3558,
      "editor": 3559,
      "##ous": 3560,
      "filled": 3561,
      "genus": 3562,
      "specific": 3563,
      "sitting": 3564,
      "super": 3565,
      "mom": 3566,
      "##va": 3567,
      "therefore": 3568,
      "supported": 3569,
      "status": 3570,
      "fear": 3571,
      "cases": 3572,
      "store": 3573,
      "meaning": 3574,
      "wales": 3575,
      "minor": 3576,
      "spain": 3577,
      "tower": 3578,
      "focus": 3579,
      "vice": 3580,
      "frank": 3581,
      "follow": 3582,
      "parish": 3583,
      "separate": 3584,
      "golden": 3585,
      "horse": 3586,
      "fifth": 3587,
      "remaining": 3588,
      "branch": 3589,
      "32": 3590,
      "presented": 3591,
      "stared": 3592,
      "##id": 3593,
      "uses": 3594,
      "secret": 3595,
      "forms": 3596,
      "##co": 3597,
      "baseball": 3598,
      "exactly": 3599,
      "##ck": 3600,
      "choice": 3601,
      "note": 3602,
      "discovered": 3603,
      "travel": 3604,
      "composed": 3605,
      "truth": 3606,
      "russia": 3607,
      "ball": 3608,
      "color": 3609,
      "kiss": 3610,
      "dad": 3611,
      "wind": 3612,
      "continue": 3613,
      "ring": 3614,
      "referred": 3615,
      "numbers": 3616,
      "digital": 3617,
      "greater": 3618,
      "##ns": 3619,
      "metres": 3620,
      "slightly": 3621,
      "direct": 3622,
      "increase": 3623,
      "1960": 3624,
      "responsible": 3625,
      "crew": 3626,
      "rule": 3627,
      "trees": 3628,
      "troops": 3629,
      "##no": 3630,
      "broke": 3631,
      "goes": 3632,
      "individuals": 3633,
      "hundred": 3634,
      "weight": 3635,
      "creek": 3636,
      "sleep": 3637,
      "memory": 3638,
      "defense": 3639,
      "provides": 3640,
      "ordered": 3641,
      "code": 3642,
      "value": 3643,
      "jewish": 3644,
      "windows": 3645,
      "1944": 3646,
      "safe": 3647,
      "judge": 3648,
      "whatever": 3649,
      "corps": 3650,
      "realized": 3651,
      "growing": 3652,
      "pre": 3653,
      "##ga": 3654,
      "cities": 3655,
      "alexander": 3656,
      "gaze": 3657,
      "lies": 3658,
      "spread": 3659,
      "scott": 3660,
      "letter": 3661,
      "showed": 3662,
      "situation": 3663,
      "mayor": 3664,
      "transport": 3665,
      "watching": 3666,
      "workers": 3667,
      "extended": 3668,
      "##li": 3669,
      "expression": 3670,
      "normal": 3671,
      "##ment": 3672,
      "chart": 3673,
      "multiple": 3674,
      "border": 3675,
      "##ba": 3676,
      "host": 3677,
      "##ner": 3678,
      "daily": 3679,
      "mrs": 3680,
      "walls": 3681,
      "piano": 3682,
      "##ko": 3683,
      "heat": 3684,
      "cannot": 3685,
      "##ate": 3686,
      "earned": 3687,
      "products": 3688,
      "drama": 3689,
      "era": 3690,
      "authority": 3691,
      "seasons": 3692,
      "join": 3693,
      "grade": 3694,
      "##io": 3695,
      "sign": 3696,
      "difficult": 3697,
      "machine": 3698,
      "1963": 3699,
      "territory": 3700,
      "mainly": 3701,
      "##wood": 3702,
      "stations": 3703,
      "squadron": 3704,
      "1962": 3705,
      "stepped": 3706,
      "iron": 3707,
      "19th": 3708,
      "##led": 3709,
      "serve": 3710,
      "appear": 3711,
      "sky": 3712,
      "speak": 3713,
      "broken": 3714,
      "charge": 3715,
      "knowledge": 3716,
      "kilometres": 3717,
      "removed": 3718,
      "ships": 3719,
      "article": 3720,
      "campus": 3721,
      "simple": 3722,
      "##ty": 3723,
      "pushed": 3724,
      "britain": 3725,
      "##ve": 3726,
      "leaves": 3727,
      "recently": 3728,
      "cd": 3729,
      "soft": 3730,
      "boston": 3731,
      "latter": 3732,
      "easy": 3733,
      "acquired": 3734,
      "poland": 3735,
      "##sa": 3736,
      "quality": 3737,
      "officers": 3738,
      "presence": 3739,
      "planned": 3740,
      "nations": 3741,
      "mass": 3742,
      "broadcast": 3743,
      "jean": 3744,
      "share": 3745,
      "image": 3746,
      "influence": 3747,
      "wild": 3748,
      "offer": 3749,
      "emperor": 3750,
      "electric": 3751,
      "reading": 3752,
      "headed": 3753,
      "ability": 3754,
      "promoted": 3755,
      "yellow": 3756,
      "ministry": 3757,
      "1942": 3758,
      "throat": 3759,
      "smaller": 3760,
      "politician": 3761,
      "##by": 3762,
      "latin": 3763,
      "spoke": 3764,
      "cars": 3765,
      "williams": 3766,
      "males": 3767,
      "lack": 3768,
      "pop": 3769,
      "80": 3770,
      "##ier": 3771,
      "acting": 3772,
      "seeing": 3773,
      "consists": 3774,
      "##ti": 3775,
      "estate": 3776,
      "1961": 3777,
      "pressure": 3778,
      "johnson": 3779,
      "newspaper": 3780,
      "jr": 3781,
      "chris": 3782,
      "olympics": 3783,
      "online": 3784,
      "conditions": 3785,
      "beat": 3786,
      "elements": 3787,
      "walking": 3788,
      "vote": 3789,
      "##field": 3790,
      "needs": 3791,
      "carolina": 3792,
      "text": 3793,
      "featuring": 3794,
      "global": 3795,
      "block": 3796,
      "shirt": 3797,
      "levels": 3798,
      "francisco": 3799,
      "purpose": 3800,
      "females": 3801,
      "et": 3802,
      "dutch": 3803,
      "duke": 3804,
      "ahead": 3805,
      "gas": 3806,
      "twice": 3807,
      "safety": 3808,
      "serious": 3809,
      "turning": 3810,
      "highly": 3811,
      "lieutenant": 3812,
      "firm": 3813,
      "maria": 3814,
      "amount": 3815,
      "mixed": 3816,
      "daniel": 3817,
      "proposed": 3818,
      "perfect": 3819,
      "agreement": 3820,
      "affairs": 3821,
      "3rd": 3822,
      "seconds": 3823,
      "contemporary": 3824,
      "paid": 3825,
      "1943": 3826,
      "prison": 3827,
      "save": 3828,
      "kitchen": 3829,
      "label": 3830,
      "administrative": 3831,
      "intended": 3832,
      "constructed": 3833,
      "academic": 3834,
      "nice": 3835,
      "teacher": 3836,
      "races": 3837,
      "1956": 3838,
      "formerly": 3839,
      "corporation": 3840,
      "ben": 3841,
      "nation": 3842,
      "issued": 3843,
      "shut": 3844,
      "1958": 3845,
      "drums": 3846,
      "housing": 3847,
      "victoria": 3848,
      "seems": 3849,
      "opera": 3850,
      "1959": 3851,
      "graduated": 3852,
      "function": 3853,
      "von": 3854,
      "mentioned": 3855,
      "picked": 3856,
      "build": 3857,
      "recognized": 3858,
      "shortly": 3859,
      "protection": 3860,
      "picture": 3861,
      "notable": 3862,
      "exchange": 3863,
      "elections": 3864,
      "1980s": 3865,
      "loved": 3866,
      "percent": 3867,
      "racing": 3868,
      "fish": 3869,
      "elizabeth": 3870,
      "garden": 3871,
      "volume": 3872,
      "hockey": 3873,
      "1941": 3874,
      "beside": 3875,
      "settled": 3876,
      "##ford": 3877,
      "1940": 3878,
      "competed": 3879,
      "replied": 3880,
      "drew": 3881,
      "1948": 3882,
      "actress": 3883,
      "marine": 3884,
      "scotland": 3885,
      "steel": 3886,
      "glanced": 3887,
      "farm": 3888,
      "steve": 3889,
      "1957": 3890,
      "risk": 3891,
      "tonight": 3892,
      "positive": 3893,
      "magic": 3894,
      "singles": 3895,
      "effects": 3896,
      "gray": 3897,
      "screen": 3898,
      "dog": 3899,
      "##ja": 3900,
      "residents": 3901,
      "bus": 3902,
      "sides": 3903,
      "none": 3904,
      "secondary": 3905,
      "literature": 3906,
      "polish": 3907,
      "destroyed": 3908,
      "flying": 3909,
      "founder": 3910,
      "households": 3911,
      "1939": 3912,
      "lay": 3913,
      "reserve": 3914,
      "usa": 3915,
      "gallery": 3916,
      "##ler": 3917,
      "1946": 3918,
      "industrial": 3919,
      "younger": 3920,
      "approach": 3921,
      "appearances": 3922,
      "urban": 3923,
      "ones": 3924,
      "1950": 3925,
      "finish": 3926,
      "avenue": 3927,
      "powerful": 3928,
      "fully": 3929,
      "growth": 3930,
      "page": 3931,
      "honor": 3932,
      "jersey": 3933,
      "projects": 3934,
      "advanced": 3935,
      "revealed": 3936,
      "basic": 3937,
      "90": 3938,
      "infantry": 3939,
      "pair": 3940,
      "equipment": 3941,
      "visit": 3942,
      "33": 3943,
      "evening": 3944,
      "search": 3945,
      "grant": 3946,
      "effort": 3947,
      "solo": 3948,
      "treatment": 3949,
      "buried": 3950,
      "republican": 3951,
      "primarily": 3952,
      "bottom": 3953,
      "owner": 3954,
      "1970s": 3955,
      "israel": 3956,
      "gives": 3957,
      "jim": 3958,
      "dream": 3959,
      "bob": 3960,
      "remain": 3961,
      "spot": 3962,
      "70": 3963,
      "notes": 3964,
      "produce": 3965,
      "champions": 3966,
      "contact": 3967,
      "ed": 3968,
      "soul": 3969,
      "accepted": 3970,
      "ways": 3971,
      "del": 3972,
      "##ally": 3973,
      "losing": 3974,
      "split": 3975,
      "price": 3976,
      "capacity": 3977,
      "basis": 3978,
      "trial": 3979,
      "questions": 3980,
      "##ina": 3981,
      "1955": 3982,
      "20th": 3983,
      "guess": 3984,
      "officially": 3985,
      "memorial": 3986,
      "naval": 3987,
      "initial": 3988,
      "##ization": 3989,
      "whispered": 3990,
      "median": 3991,
      "engineer": 3992,
      "##ful": 3993,
      "sydney": 3994,
      "##go": 3995,
      "columbia": 3996,
      "strength": 3997,
      "300": 3998,
      "1952": 3999,
      "tears": 4000,
      "senate": 4001,
      "00": 4002,
      "card": 4003,
      "asian": 4004,
      "agent": 4005,
      "1947": 4006,
      "software": 4007,
      "44": 4008,
      "draw": 4009,
      "warm": 4010,
      "supposed": 4011,
      "com": 4012,
      "pro": 4013,
      "##il": 4014,
      "transferred": 4015,
      "leaned": 4016,
      "##at": 4017,
      "candidate": 4018,
      "escape": 4019,
      "mountains": 4020,
      "asia": 4021,
      "potential": 4022,
      "activity": 4023,
      "entertainment": 4024,
      "seem": 4025,
      "traffic": 4026,
      "jackson": 4027,
      "murder": 4028,
      "36": 4029,
      "slow": 4030,
      "product": 4031,
      "orchestra": 4032,
      "haven": 4033,
      "agency": 4034,
      "bbc": 4035,
      "taught": 4036,
      "website": 4037,
      "comedy": 4038,
      "unable": 4039,
      "storm": 4040,
      "planning": 4041,
      "albums": 4042,
      "rugby": 4043,
      "environment": 4044,
      "scientific": 4045,
      "grabbed": 4046,
      "protect": 4047,
      "##hi": 4048,
      "boat": 4049,
      "typically": 4050,
      "1954": 4051,
      "1953": 4052,
      "damage": 4053,
      "principal": 4054,
      "divided": 4055,
      "dedicated": 4056,
      "mount": 4057,
      "ohio": 4058,
      "##berg": 4059,
      "pick": 4060,
      "fought": 4061,
      "driver": 4062,
      "##der": 4063,
      "empty": 4064,
      "shoulders": 4065,
      "sort": 4066,
      "thank": 4067,
      "berlin": 4068,
      "prominent": 4069,
      "account": 4070,
      "freedom": 4071,
      "necessary": 4072,
      "efforts": 4073,
      "alex": 4074,
      "headquarters": 4075,
      "follows": 4076,
      "alongside": 4077,
      "des": 4078,
      "simon": 4079,
      "andrew": 4080,
      "suggested": 4081,
      "operating": 4082,
      "learning": 4083,
      "steps": 4084,
      "1949": 4085,
      "sweet": 4086,
      "technical": 4087,
      "begin": 4088,
      "easily": 4089,
      "34": 4090,
      "teeth": 4091,
      "speaking": 4092,
      "settlement": 4093,
      "scale": 4094,
      "##sh": 4095,
      "renamed": 4096,
      "ray": 4097,
      "max": 4098,
      "enemy": 4099,
      "semi": 4100,
      "joint": 4101,
      "compared": 4102,
      "##rd": 4103,
      "scottish": 4104,
      "leadership": 4105,
      "analysis": 4106,
      "offers": 4107,
      "georgia": 4108,
      "pieces": 4109,
      "captured": 4110,
      "animal": 4111,
      "deputy": 4112,
      "guest": 4113,
      "organized": 4114,
      "##lin": 4115,
      "tony": 4116,
      "combined": 4117,
      "method": 4118,
      "challenge": 4119,
      "1960s": 4120,
      "huge": 4121,
      "wants": 4122,
      "battalion": 4123,
      "sons": 4124,
      "rise": 4125,
      "crime": 4126,
      "types": 4127,
      "facilities": 4128,
      "telling": 4129,
      "path": 4130,
      "1951": 4131,
      "platform": 4132,
      "sit": 4133,
      "1990s": 4134,
      "##lo": 4135,
      "tells": 4136,
      "assigned": 4137,
      "rich": 4138,
      "pull": 4139,
      "##ot": 4140,
      "commonly": 4141,
      "alive": 4142,
      "##za": 4143,
      "letters": 4144,
      "concept": 4145,
      "conducted": 4146,
      "wearing": 4147,
      "happen": 4148,
      "bought": 4149,
      "becomes": 4150,
      "holy": 4151,
      "gets": 4152,
      "ocean": 4153,
      "defeat": 4154,
      "languages": 4155,
      "purchased": 4156,
      "coffee": 4157,
      "occurred": 4158,
      "titled": 4159,
      "##q": 4160,
      "declared": 4161,
      "applied": 4162,
      "sciences": 4163,
      "concert": 4164,
      "sounds": 4165,
      "jazz": 4166,
      "brain": 4167,
      "##me": 4168,
      "painting": 4169,
      "fleet": 4170,
      "tax": 4171,
      "nick": 4172,
      "##ius": 4173,
      "michigan": 4174,
      "count": 4175,
      "animals": 4176,
      "leaders": 4177,
      "episodes": 4178,
      "##line": 4179,
      "content": 4180,
      "##den": 4181,
      "birth": 4182,
      "##it": 4183,
      "clubs": 4184,
      "64": 4185,
      "palace": 4186,
      "critical": 4187,
      "refused": 4188,
      "fair": 4189,
      "leg": 4190,
      "laughed": 4191,
      "returning": 4192,
      "surrounding": 4193,
      "participated": 4194,
      "formation": 4195,
      "lifted": 4196,
      "pointed": 4197,
      "connected": 4198,
      "rome": 4199,
      "medicine": 4200,
      "laid": 4201,
      "taylor": 4202,
      "santa": 4203,
      "powers": 4204,
      "adam": 4205,
      "tall": 4206,
      "shared": 4207,
      "focused": 4208,
      "knowing": 4209,
      "yards": 4210,
      "entrance": 4211,
      "falls": 4212,
      "##wa": 4213,
      "calling": 4214,
      "##ad": 4215,
      "sources": 4216,
      "chosen": 4217,
      "beneath": 4218,
      "resources": 4219,
      "yard": 4220,
      "##ite": 4221,
      "nominated": 4222,
      "silence": 4223,
      "zone": 4224,
      "defined": 4225,
      "##que": 4226,
      "gained": 4227,
      "thirty": 4228,
      "38": 4229,
      "bodies": 4230,
      "moon": 4231,
      "##ard": 4232,
      "adopted": 4233,
      "christmas": 4234,
      "widely": 4235,
      "register": 4236,
      "apart": 4237,
      "iran": 4238,
      "premier": 4239,
      "serves": 4240,
      "du": 4241,
      "unknown": 4242,
      "parties": 4243,
      "##les": 4244,
      "generation": 4245,
      "##ff": 4246,
      "continues": 4247,
      "quick": 4248,
      "fields": 4249,
      "brigade": 4250,
      "quiet": 4251,
      "teaching": 4252,
      "clothes": 4253,
      "impact": 4254,
      "weapons": 4255,
      "partner": 4256,
      "flat": 4257,
      "theater": 4258,
      "supreme": 4259,
      "1938": 4260,
      "37": 4261,
      "relations": 4262,
      "##tor": 4263,
      "plants": 4264,
      "suffered": 4265,
      "1936": 4266,
      "wilson": 4267,
      "kids": 4268,
      "begins": 4269,
      "##age": 4270,
      "1918": 4271,
      "seats": 4272,
      "armed": 4273,
      "internet": 4274,
      "models": 4275,
      "worth": 4276,
      "laws": 4277,
      "400": 4278,
      "communities": 4279,
      "classes": 4280,
      "background": 4281,
      "knows": 4282,
      "thanks": 4283,
      "quarter": 4284,
      "reaching": 4285,
      "humans": 4286,
      "carry": 4287,
      "killing": 4288,
      "format": 4289,
      "kong": 4290,
      "hong": 4291,
      "setting": 4292,
      "75": 4293,
      "architecture": 4294,
      "disease": 4295,
      "railroad": 4296,
      "inc": 4297,
      "possibly": 4298,
      "wish": 4299,
      "arthur": 4300,
      "thoughts": 4301,
      "harry": 4302,
      "doors": 4303,
      "density": 4304,
      "##di": 4305,
      "crowd": 4306,
      "illinois": 4307,
      "stomach": 4308,
      "tone": 4309,
      "unique": 4310,
      "reports": 4311,
      "anyway": 4312,
      "##ir": 4313,
      "liberal": 4314,
      "der": 4315,
      "vehicle": 4316,
      "thick": 4317,
      "dry": 4318,
      "drug": 4319,
      "faced": 4320,
      "largely": 4321,
      "facility": 4322,
      "theme": 4323,
      "holds": 4324,
      "creation": 4325,
      "strange": 4326,
      "colonel": 4327,
      "##mi": 4328,
      "revolution": 4329,
      "bell": 4330,
      "politics": 4331,
      "turns": 4332,
      "silent": 4333,
      "rail": 4334,
      "relief": 4335,
      "independence": 4336,
      "combat": 4337,
      "shape": 4338,
      "write": 4339,
      "determined": 4340,
      "sales": 4341,
      "learned": 4342,
      "4th": 4343,
      "finger": 4344,
      "oxford": 4345,
      "providing": 4346,
      "1937": 4347,
      "heritage": 4348,
      "fiction": 4349,
      "situated": 4350,
      "designated": 4351,
      "allowing": 4352,
      "distribution": 4353,
      "hosted": 4354,
      "##est": 4355,
      "sight": 4356,
      "interview": 4357,
      "estimated": 4358,
      "reduced": 4359,
      "##ria": 4360,
      "toronto": 4361,
      "footballer": 4362,
      "keeping": 4363,
      "guys": 4364,
      "damn": 4365,
      "claim": 4366,
      "motion": 4367,
      "sport": 4368,
      "sixth": 4369,
      "stayed": 4370,
      "##ze": 4371,
      "en": 4372,
      "rear": 4373,
      "receive": 4374,
      "handed": 4375,
      "twelve": 4376,
      "dress": 4377,
      "audience": 4378,
      "granted": 4379,
      "brazil": 4380,
      "##well": 4381,
      "spirit": 4382,
      "##ated": 4383,
      "noticed": 4384,
      "etc": 4385,
      "olympic": 4386,
      "representative": 4387,
      "eric": 4388,
      "tight": 4389,
      "trouble": 4390,
      "reviews": 4391,
      "drink": 4392,
      "vampire": 4393,
      "missing": 4394,
      "roles": 4395,
      "ranked": 4396,
      "newly": 4397,
      "household": 4398,
      "finals": 4399,
      "wave": 4400,
      "critics": 4401,
      "##ee": 4402,
      "phase": 4403,
      "massachusetts": 4404,
      "pilot": 4405,
      "unlike": 4406,
      "philadelphia": 4407,
      "bright": 4408,
      "guns": 4409,
      "crown": 4410,
      "organizations": 4411,
      "roof": 4412,
      "42": 4413,
      "respectively": 4414,
      "clearly": 4415,
      "tongue": 4416,
      "marked": 4417,
      "circle": 4418,
      "fox": 4419,
      "korea": 4420,
      "bronze": 4421,
      "brian": 4422,
      "expanded": 4423,
      "sexual": 4424,
      "supply": 4425,
      "yourself": 4426,
      "inspired": 4427,
      "labour": 4428,
      "fc": 4429,
      "##ah": 4430,
      "reference": 4431,
      "vision": 4432,
      "draft": 4433,
      "connection": 4434,
      "brand": 4435,
      "reasons": 4436,
      "1935": 4437,
      "classic": 4438,
      "driving": 4439,
      "trip": 4440,
      "jesus": 4441,
      "cells": 4442,
      "entry": 4443,
      "1920": 4444,
      "neither": 4445,
      "trail": 4446,
      "claims": 4447,
      "atlantic": 4448,
      "orders": 4449,
      "labor": 4450,
      "nose": 4451,
      "afraid": 4452,
      "identified": 4453,
      "intelligence": 4454,
      "calls": 4455,
      "cancer": 4456,
      "attacked": 4457,
      "passing": 4458,
      "stephen": 4459,
      "positions": 4460,
      "imperial": 4461,
      "grey": 4462,
      "jason": 4463,
      "39": 4464,
      "sunday": 4465,
      "48": 4466,
      "swedish": 4467,
      "avoid": 4468,
      "extra": 4469,
      "uncle": 4470,
      "message": 4471,
      "covers": 4472,
      "allows": 4473,
      "surprise": 4474,
      "materials": 4475,
      "fame": 4476,
      "hunter": 4477,
      "##ji": 4478,
      "1930": 4479,
      "citizens": 4480,
      "figures": 4481,
      "davis": 4482,
      "environmental": 4483,
      "confirmed": 4484,
      "shit": 4485,
      "titles": 4486,
      "di": 4487,
      "performing": 4488,
      "difference": 4489,
      "acts": 4490,
      "attacks": 4491,
      "##ov": 4492,
      "existing": 4493,
      "votes": 4494,
      "opportunity": 4495,
      "nor": 4496,
      "shop": 4497,
      "entirely": 4498,
      "trains": 4499,
      "opposite": 4500,
      "pakistan": 4501,
      "##pa": 4502,
      "develop": 4503,
      "resulted": 4504,
      "representatives": 4505,
      "actions": 4506,
      "reality": 4507,
      "pressed": 4508,
      "##ish": 4509,
      "barely": 4510,
      "wine": 4511,
      "conversation": 4512,
      "faculty": 4513,
      "northwest": 4514,
      "ends": 4515,
      "documentary": 4516,
      "nuclear": 4517,
      "stock": 4518,
      "grace": 4519,
      "sets": 4520,
      "eat": 4521,
      "alternative": 4522,
      "##ps": 4523,
      "bag": 4524,
      "resulting": 4525,
      "creating": 4526,
      "surprised": 4527,
      "cemetery": 4528,
      "1919": 4529,
      "drop": 4530,
      "finding": 4531,
      "sarah": 4532,
      "cricket": 4533,
      "streets": 4534,
      "tradition": 4535,
      "ride": 4536,
      "1933": 4537,
      "exhibition": 4538,
      "target": 4539,
      "ear": 4540,
      "explained": 4541,
      "rain": 4542,
      "composer": 4543,
      "injury": 4544,
      "apartment": 4545,
      "municipal": 4546,
      "educational": 4547,
      "occupied": 4548,
      "netherlands": 4549,
      "clean": 4550,
      "billion": 4551,
      "constitution": 4552,
      "learn": 4553,
      "1914": 4554,
      "maximum": 4555,
      "classical": 4556,
      "francis": 4557,
      "lose": 4558,
      "opposition": 4559,
      "jose": 4560,
      "ontario": 4561,
      "bear": 4562,
      "core": 4563,
      "hills": 4564,
      "rolled": 4565,
      "ending": 4566,
      "drawn": 4567,
      "permanent": 4568,
      "fun": 4569,
      "##tes": 4570,
      "##lla": 4571,
      "lewis": 4572,
      "sites": 4573,
      "chamber": 4574,
      "ryan": 4575,
      "##way": 4576,
      "scoring": 4577,
      "height": 4578,
      "1934": 4579,
      "##house": 4580,
      "lyrics": 4581,
      "staring": 4582,
      "55": 4583,
      "officials": 4584,
      "1917": 4585,
      "snow": 4586,
      "oldest": 4587,
      "##tic": 4588,
      "orange": 4589,
      "##ger": 4590,
      "qualified": 4591,
      "interior": 4592,
      "apparently": 4593,
      "succeeded": 4594,
      "thousand": 4595,
      "dinner": 4596,
      "lights": 4597,
      "existence": 4598,
      "fans": 4599,
      "heavily": 4600,
      "41": 4601,
      "greatest": 4602,
      "conservative": 4603,
      "send": 4604,
      "bowl": 4605,
      "plus": 4606,
      "enter": 4607,
      "catch": 4608,
      "##un": 4609,
      "economy": 4610,
      "duty": 4611,
      "1929": 4612,
      "speech": 4613,
      "authorities": 4614,
      "princess": 4615,
      "performances": 4616,
      "versions": 4617,
      "shall": 4618,
      "graduate": 4619,
      "pictures": 4620,
      "effective": 4621,
      "remembered": 4622,
      "poetry": 4623,
      "desk": 4624,
      "crossed": 4625,
      "starring": 4626,
      "starts": 4627,
      "passenger": 4628,
      "sharp": 4629,
      "##ant": 4630,
      "acres": 4631,
      "ass": 4632,
      "weather": 4633,
      "falling": 4634,
      "rank": 4635,
      "fund": 4636,
      "supporting": 4637,
      "check": 4638,
      "adult": 4639,
      "publishing": 4640,
      "heads": 4641,
      "cm": 4642,
      "southeast": 4643,
      "lane": 4644,
      "##burg": 4645,
      "application": 4646,
      "bc": 4647,
      "##ura": 4648,
      "les": 4649,
      "condition": 4650,
      "transfer": 4651,
      "prevent": 4652,
      "display": 4653,
      "ex": 4654,
      "regions": 4655,
      "earl": 4656,
      "federation": 4657,
      "cool": 4658,
      "relatively": 4659,
      "answered": 4660,
      "besides": 4661,
      "1928": 4662,
      "obtained": 4663,
      "portion": 4664,
      "##town": 4665,
      "mix": 4666,
      "##ding": 4667,
      "reaction": 4668,
      "liked": 4669,
      "dean": 4670,
      "express": 4671,
      "peak": 4672,
      "1932": 4673,
      "##tte": 4674,
      "counter": 4675,
      "religion": 4676,
      "chain": 4677,
      "rare": 4678,
      "miller": 4679,
      "convention": 4680,
      "aid": 4681,
      "lie": 4682,
      "vehicles": 4683,
      "mobile": 4684,
      "perform": 4685,
      "squad": 4686,
      "wonder": 4687,
      "lying": 4688,
      "crazy": 4689,
      "sword": 4690,
      "##ping": 4691,
      "attempted": 4692,
      "centuries": 4693,
      "weren": 4694,
      "philosophy": 4695,
      "category": 4696,
      "##ize": 4697,
      "anna": 4698,
      "interested": 4699,
      "47": 4700,
      "sweden": 4701,
      "wolf": 4702,
      "frequently": 4703,
      "abandoned": 4704,
      "kg": 4705,
      "literary": 4706,
      "alliance": 4707,
      "task": 4708,
      "entitled": 4709,
      "##ay": 4710,
      "threw": 4711,
      "promotion": 4712,
      "factory": 4713,
      "tiny": 4714,
      "soccer": 4715,
      "visited": 4716,
      "matt": 4717,
      "fm": 4718,
      "achieved": 4719,
      "52": 4720,
      "defence": 4721,
      "internal": 4722,
      "persian": 4723,
      "43": 4724,
      "methods": 4725,
      "##ging": 4726,
      "arrested": 4727,
      "otherwise": 4728,
      "cambridge": 4729,
      "programming": 4730,
      "villages": 4731,
      "elementary": 4732,
      "districts": 4733,
      "rooms": 4734,
      "criminal": 4735,
      "conflict": 4736,
      "worry": 4737,
      "trained": 4738,
      "1931": 4739,
      "attempts": 4740,
      "waited": 4741,
      "signal": 4742,
      "bird": 4743,
      "truck": 4744,
      "subsequent": 4745,
      "programme": 4746,
      "##ol": 4747,
      "ad": 4748,
      "49": 4749,
      "communist": 4750,
      "details": 4751,
      "faith": 4752,
      "sector": 4753,
      "patrick": 4754,
      "carrying": 4755,
      "laugh": 4756,
      "##ss": 4757,
      "controlled": 4758,
      "korean": 4759,
      "showing": 4760,
      "origin": 4761,
      "fuel": 4762,
      "evil": 4763,
      "1927": 4764,
      "##ent": 4765,
      "brief": 4766,
      "identity": 4767,
      "darkness": 4768,
      "address": 4769,
      "pool": 4770,
      "missed": 4771,
      "publication": 4772,
      "web": 4773,
      "planet": 4774,
      "ian": 4775,
      "anne": 4776,
      "wings": 4777,
      "invited": 4778,
      "##tt": 4779,
      "briefly": 4780,
      "standards": 4781,
      "kissed": 4782,
      "##be": 4783,
      "ideas": 4784,
      "climate": 4785,
      "causing": 4786,
      "walter": 4787,
      "worse": 4788,
      "albert": 4789,
      "articles": 4790,
      "winners": 4791,
      "desire": 4792,
      "aged": 4793,
      "northeast": 4794,
      "dangerous": 4795,
      "gate": 4796,
      "doubt": 4797,
      "1922": 4798,
      "wooden": 4799,
      "multi": 4800,
      "##ky": 4801,
      "poet": 4802,
      "rising": 4803,
      "funding": 4804,
      "46": 4805,
      "communications": 4806,
      "communication": 4807,
      "violence": 4808,
      "copies": 4809,
      "prepared": 4810,
      "ford": 4811,
      "investigation": 4812,
      "skills": 4813,
      "1924": 4814,
      "pulling": 4815,
      "electronic": 4816,
      "##ak": 4817,
      "##ial": 4818,
      "##han": 4819,
      "containing": 4820,
      "ultimately": 4821,
      "offices": 4822,
      "singing": 4823,
      "understanding": 4824,
      "restaurant": 4825,
      "tomorrow": 4826,
      "fashion": 4827,
      "christ": 4828,
      "ward": 4829,
      "da": 4830,
      "pope": 4831,
      "stands": 4832,
      "5th": 4833,
      "flow": 4834,
      "studios": 4835,
      "aired": 4836,
      "commissioned": 4837,
      "contained": 4838,
      "exist": 4839,
      "fresh": 4840,
      "americans": 4841,
      "##per": 4842,
      "wrestling": 4843,
      "approved": 4844,
      "kid": 4845,
      "employed": 4846,
      "respect": 4847,
      "suit": 4848,
      "1925": 4849,
      "angel": 4850,
      "asking": 4851,
      "increasing": 4852,
      "frame": 4853,
      "angry": 4854,
      "selling": 4855,
      "1950s": 4856,
      "thin": 4857,
      "finds": 4858,
      "##nd": 4859,
      "temperature": 4860,
      "statement": 4861,
      "ali": 4862,
      "explain": 4863,
      "inhabitants": 4864,
      "towns": 4865,
      "extensive": 4866,
      "narrow": 4867,
      "51": 4868,
      "jane": 4869,
      "flowers": 4870,
      "images": 4871,
      "promise": 4872,
      "somewhere": 4873,
      "object": 4874,
      "fly": 4875,
      "closely": 4876,
      "##ls": 4877,
      "1912": 4878,
      "bureau": 4879,
      "cape": 4880,
      "1926": 4881,
      "weekly": 4882,
      "presidential": 4883,
      "legislative": 4884,
      "1921": 4885,
      "##ai": 4886,
      "##au": 4887,
      "launch": 4888,
      "founding": 4889,
      "##ny": 4890,
      "978": 4891,
      "##ring": 4892,
      "artillery": 4893,
      "strike": 4894,
      "un": 4895,
      "institutions": 4896,
      "roll": 4897,
      "writers": 4898,
      "landing": 4899,
      "chose": 4900,
      "kevin": 4901,
      "anymore": 4902,
      "pp": 4903,
      "##ut": 4904,
      "attorney": 4905,
      "fit": 4906,
      "dan": 4907,
      "billboard": 4908,
      "receiving": 4909,
      "agricultural": 4910,
      "breaking": 4911,
      "sought": 4912,
      "dave": 4913,
      "admitted": 4914,
      "lands": 4915,
      "mexican": 4916,
      "##bury": 4917,
      "charlie": 4918,
      "specifically": 4919,
      "hole": 4920,
      "iv": 4921,
      "howard": 4922,
      "credit": 4923,
      "moscow": 4924,
      "roads": 4925,
      "accident": 4926,
      "1923": 4927,
      "proved": 4928,
      "wear": 4929,
      "struck": 4930,
      "hey": 4931,
      "guards": 4932,
      "stuff": 4933,
      "slid": 4934,
      "expansion": 4935,
      "1915": 4936,
      "cat": 4937,
      "anthony": 4938,
      "##kin": 4939,
      "melbourne": 4940,
      "opposed": 4941,
      "sub": 4942,
      "southwest": 4943,
      "architect": 4944,
      "failure": 4945,
      "plane": 4946,
      "1916": 4947,
      "##ron": 4948,
      "map": 4949,
      "camera": 4950,
      "tank": 4951,
      "listen": 4952,
      "regarding": 4953,
      "wet": 4954,
      "introduction": 4955,
      "metropolitan": 4956,
      "link": 4957,
      "ep": 4958,
      "fighter": 4959,
      "inch": 4960,
      "grown": 4961,
      "gene": 4962,
      "anger": 4963,
      "fixed": 4964,
      "buy": 4965,
      "dvd": 4966,
      "khan": 4967,
      "domestic": 4968,
      "worldwide": 4969,
      "chapel": 4970,
      "mill": 4971,
      "functions": 4972,
      "examples": 4973,
      "##head": 4974,
      "developing": 4975,
      "1910": 4976,
      "turkey": 4977,
      "hits": 4978,
      "pocket": 4979,
      "antonio": 4980,
      "papers": 4981,
      "grow": 4982,
      "unless": 4983,
      "circuit": 4984,
      "18th": 4985,
      "concerned": 4986,
      "attached": 4987,
      "journalist": 4988,
      "selection": 4989,
      "journey": 4990,
      "converted": 4991,
      "provincial": 4992,
      "painted": 4993,
      "hearing": 4994,
      "aren": 4995,
      "bands": 4996,
      "negative": 4997,
      "aside": 4998,
      "wondered": 4999,
      "knight": 5000,
      "lap": 5001,
      "survey": 5002,
      "ma": 5003,
      "##ow": 5004,
      "noise": 5005,
      "billy": 5006,
      "##ium": 5007,
      "shooting": 5008,
      "guide": 5009,
      "bedroom": 5010,
      "priest": 5011,
      "resistance": 5012,
      "motor": 5013,
      "homes": 5014,
      "sounded": 5015,
      "giant": 5016,
      "##mer": 5017,
      "150": 5018,
      "scenes": 5019,
      "equal": 5020,
      "comic": 5021,
      "patients": 5022,
      "hidden": 5023,
      "solid": 5024,
      "actual": 5025,
      "bringing": 5026,
      "afternoon": 5027,
      "touched": 5028,
      "funds": 5029,
      "wedding": 5030,
      "consisted": 5031,
      "marie": 5032,
      "canal": 5033,
      "sr": 5034,
      "kim": 5035,
      "treaty": 5036,
      "turkish": 5037,
      "recognition": 5038,
      "residence": 5039,
      "cathedral": 5040,
      "broad": 5041,
      "knees": 5042,
      "incident": 5043,
      "shaped": 5044,
      "fired": 5045,
      "norwegian": 5046,
      "handle": 5047,
      "cheek": 5048,
      "contest": 5049,
      "represent": 5050,
      "##pe": 5051,
      "representing": 5052,
      "beauty": 5053,
      "##sen": 5054,
      "birds": 5055,
      "advantage": 5056,
      "emergency": 5057,
      "wrapped": 5058,
      "drawing": 5059,
      "notice": 5060,
      "pink": 5061,
      "broadcasting": 5062,
      "##ong": 5063,
      "somehow": 5064,
      "bachelor": 5065,
      "seventh": 5066,
      "collected": 5067,
      "registered": 5068,
      "establishment": 5069,
      "alan": 5070,
      "assumed": 5071,
      "chemical": 5072,
      "personnel": 5073,
      "roger": 5074,
      "retirement": 5075,
      "jeff": 5076,
      "portuguese": 5077,
      "wore": 5078,
      "tied": 5079,
      "device": 5080,
      "threat": 5081,
      "progress": 5082,
      "advance": 5083,
      "##ised": 5084,
      "banks": 5085,
      "hired": 5086,
      "manchester": 5087,
      "nfl": 5088,
      "teachers": 5089,
      "structures": 5090,
      "forever": 5091,
      "##bo": 5092,
      "tennis": 5093,
      "helping": 5094,
      "saturday": 5095,
      "sale": 5096,
      "applications": 5097,
      "junction": 5098,
      "hip": 5099,
      "incorporated": 5100,
      "neighborhood": 5101,
      "dressed": 5102,
      "ceremony": 5103,
      "##ds": 5104,
      "influenced": 5105,
      "hers": 5106,
      "visual": 5107,
      "stairs": 5108,
      "decades": 5109,
      "inner": 5110,
      "kansas": 5111,
      "hung": 5112,
      "hoped": 5113,
      "gain": 5114,
      "scheduled": 5115,
      "downtown": 5116,
      "engaged": 5117,
      "austria": 5118,
      "clock": 5119,
      "norway": 5120,
      "certainly": 5121,
      "pale": 5122,
      "protected": 5123,
      "1913": 5124,
      "victor": 5125,
      "employees": 5126,
      "plate": 5127,
      "putting": 5128,
      "surrounded": 5129,
      "##ists": 5130,
      "finishing": 5131,
      "blues": 5132,
      "tropical": 5133,
      "##ries": 5134,
      "minnesota": 5135,
      "consider": 5136,
      "philippines": 5137,
      "accept": 5138,
      "54": 5139,
      "retrieved": 5140,
      "1900": 5141,
      "concern": 5142,
      "anderson": 5143,
      "properties": 5144,
      "institution": 5145,
      "gordon": 5146,
      "successfully": 5147,
      "vietnam": 5148,
      "##dy": 5149,
      "backing": 5150,
      "outstanding": 5151,
      "muslim": 5152,
      "crossing": 5153,
      "folk": 5154,
      "producing": 5155,
      "usual": 5156,
      "demand": 5157,
      "occurs": 5158,
      "observed": 5159,
      "lawyer": 5160,
      "educated": 5161,
      "##ana": 5162,
      "kelly": 5163,
      "string": 5164,
      "pleasure": 5165,
      "budget": 5166,
      "items": 5167,
      "quietly": 5168,
      "colorado": 5169,
      "philip": 5170,
      "typical": 5171,
      "##worth": 5172,
      "derived": 5173,
      "600": 5174,
      "survived": 5175,
      "asks": 5176,
      "mental": 5177,
      "##ide": 5178,
      "56": 5179,
      "jake": 5180,
      "jews": 5181,
      "distinguished": 5182,
      "ltd": 5183,
      "1911": 5184,
      "sri": 5185,
      "extremely": 5186,
      "53": 5187,
      "athletic": 5188,
      "loud": 5189,
      "thousands": 5190,
      "worried": 5191,
      "shadow": 5192,
      "transportation": 5193,
      "horses": 5194,
      "weapon": 5195,
      "arena": 5196,
      "importance": 5197,
      "users": 5198,
      "tim": 5199,
      "objects": 5200,
      "contributed": 5201,
      "dragon": 5202,
      "douglas": 5203,
      "aware": 5204,
      "senator": 5205,
      "johnny": 5206,
      "jordan": 5207,
      "sisters": 5208,
      "engines": 5209,
      "flag": 5210,
      "investment": 5211,
      "samuel": 5212,
      "shock": 5213,
      "capable": 5214,
      "clark": 5215,
      "row": 5216,
      "wheel": 5217,
      "refers": 5218,
      "session": 5219,
      "familiar": 5220,
      "biggest": 5221,
      "wins": 5222,
      "hate": 5223,
      "maintained": 5224,
      "drove": 5225,
      "hamilton": 5226,
      "request": 5227,
      "expressed": 5228,
      "injured": 5229,
      "underground": 5230,
      "churches": 5231,
      "walker": 5232,
      "wars": 5233,
      "tunnel": 5234,
      "passes": 5235,
      "stupid": 5236,
      "agriculture": 5237,
      "softly": 5238,
      "cabinet": 5239,
      "regarded": 5240,
      "joining": 5241,
      "indiana": 5242,
      "##ea": 5243,
      "##ms": 5244,
      "push": 5245,
      "dates": 5246,
      "spend": 5247,
      "behavior": 5248,
      "woods": 5249,
      "protein": 5250,
      "gently": 5251,
      "chase": 5252,
      "morgan": 5253,
      "mention": 5254,
      "burning": 5255,
      "wake": 5256,
      "combination": 5257,
      "occur": 5258,
      "mirror": 5259,
      "leads": 5260,
      "jimmy": 5261,
      "indeed": 5262,
      "impossible": 5263,
      "singapore": 5264,
      "paintings": 5265,
      "covering": 5266,
      "##nes": 5267,
      "soldier": 5268,
      "locations": 5269,
      "attendance": 5270,
      "sell": 5271,
      "historian": 5272,
      "wisconsin": 5273,
      "invasion": 5274,
      "argued": 5275,
      "painter": 5276,
      "diego": 5277,
      "changing": 5278,
      "egypt": 5279,
      "##don": 5280,
      "experienced": 5281,
      "inches": 5282,
      "##ku": 5283,
      "missouri": 5284,
      "vol": 5285,
      "grounds": 5286,
      "spoken": 5287,
      "switzerland": 5288,
      "##gan": 5289,
      "reform": 5290,
      "rolling": 5291,
      "ha": 5292,
      "forget": 5293,
      "massive": 5294,
      "resigned": 5295,
      "burned": 5296,
      "allen": 5297,
      "tennessee": 5298,
      "locked": 5299,
      "values": 5300,
      "improved": 5301,
      "##mo": 5302,
      "wounded": 5303,
      "universe": 5304,
      "sick": 5305,
      "dating": 5306,
      "facing": 5307,
      "pack": 5308,
      "purchase": 5309,
      "user": 5310,
      "##pur": 5311,
      "moments": 5312,
      "##ul": 5313,
      "merged": 5314,
      "anniversary": 5315,
      "1908": 5316,
      "coal": 5317,
      "brick": 5318,
      "understood": 5319,
      "causes": 5320,
      "dynasty": 5321,
      "queensland": 5322,
      "establish": 5323,
      "stores": 5324,
      "crisis": 5325,
      "promote": 5326,
      "hoping": 5327,
      "views": 5328,
      "cards": 5329,
      "referee": 5330,
      "extension": 5331,
      "##si": 5332,
      "raise": 5333,
      "arizona": 5334,
      "improve": 5335,
      "colonial": 5336,
      "formal": 5337,
      "charged": 5338,
      "##rt": 5339,
      "palm": 5340,
      "lucky": 5341,
      "hide": 5342,
      "rescue": 5343,
      "faces": 5344,
      "95": 5345,
      "feelings": 5346,
      "candidates": 5347,
      "juan": 5348,
      "##ell": 5349,
      "goods": 5350,
      "6th": 5351,
      "courses": 5352,
      "weekend": 5353,
      "59": 5354,
      "luke": 5355,
      "cash": 5356,
      "fallen": 5357,
      "##om": 5358,
      "delivered": 5359,
      "affected": 5360,
      "installed": 5361,
      "carefully": 5362,
      "tries": 5363,
      "swiss": 5364,
      "hollywood": 5365,
      "costs": 5366,
      "lincoln": 5367,
      "responsibility": 5368,
      "##he": 5369,
      "shore": 5370,
      "file": 5371,
      "proper": 5372,
      "normally": 5373,
      "maryland": 5374,
      "assistance": 5375,
      "jump": 5376,
      "constant": 5377,
      "offering": 5378,
      "friendly": 5379,
      "waters": 5380,
      "persons": 5381,
      "realize": 5382,
      "contain": 5383,
      "trophy": 5384,
      "800": 5385,
      "partnership": 5386,
      "factor": 5387,
      "58": 5388,
      "musicians": 5389,
      "cry": 5390,
      "bound": 5391,
      "oregon": 5392,
      "indicated": 5393,
      "hero": 5394,
      "houston": 5395,
      "medium": 5396,
      "##ure": 5397,
      "consisting": 5398,
      "somewhat": 5399,
      "##ara": 5400,
      "57": 5401,
      "cycle": 5402,
      "##che": 5403,
      "beer": 5404,
      "moore": 5405,
      "frederick": 5406,
      "gotten": 5407,
      "eleven": 5408,
      "worst": 5409,
      "weak": 5410,
      "approached": 5411,
      "arranged": 5412,
      "chin": 5413,
      "loan": 5414,
      "universal": 5415,
      "bond": 5416,
      "fifteen": 5417,
      "pattern": 5418,
      "disappeared": 5419,
      "##ney": 5420,
      "translated": 5421,
      "##zed": 5422,
      "lip": 5423,
      "arab": 5424,
      "capture": 5425,
      "interests": 5426,
      "insurance": 5427,
      "##chi": 5428,
      "shifted": 5429,
      "cave": 5430,
      "prix": 5431,
      "warning": 5432,
      "sections": 5433,
      "courts": 5434,
      "coat": 5435,
      "plot": 5436,
      "smell": 5437,
      "feed": 5438,
      "golf": 5439,
      "favorite": 5440,
      "maintain": 5441,
      "knife": 5442,
      "vs": 5443,
      "voted": 5444,
      "degrees": 5445,
      "finance": 5446,
      "quebec": 5447,
      "opinion": 5448,
      "translation": 5449,
      "manner": 5450,
      "ruled": 5451,
      "operate": 5452,
      "productions": 5453,
      "choose": 5454,
      "musician": 5455,
      "discovery": 5456,
      "confused": 5457,
      "tired": 5458,
      "separated": 5459,
      "stream": 5460,
      "techniques": 5461,
      "committed": 5462,
      "attend": 5463,
      "ranking": 5464,
      "kings": 5465,
      "throw": 5466,
      "passengers": 5467,
      "measure": 5468,
      "horror": 5469,
      "fan": 5470,
      "mining": 5471,
      "sand": 5472,
      "danger": 5473,
      "salt": 5474,
      "calm": 5475,
      "decade": 5476,
      "dam": 5477,
      "require": 5478,
      "runner": 5479,
      "##ik": 5480,
      "rush": 5481,
      "associate": 5482,
      "greece": 5483,
      "##ker": 5484,
      "rivers": 5485,
      "consecutive": 5486,
      "matthew": 5487,
      "##ski": 5488,
      "sighed": 5489,
      "sq": 5490,
      "documents": 5491,
      "steam": 5492,
      "edited": 5493,
      "closing": 5494,
      "tie": 5495,
      "accused": 5496,
      "1905": 5497,
      "##ini": 5498,
      "islamic": 5499,
      "distributed": 5500,
      "directors": 5501,
      "organisation": 5502,
      "bruce": 5503,
      "7th": 5504,
      "breathing": 5505,
      "mad": 5506,
      "lit": 5507,
      "arrival": 5508,
      "concrete": 5509,
      "taste": 5510,
      "08": 5511,
      "composition": 5512,
      "shaking": 5513,
      "faster": 5514,
      "amateur": 5515,
      "adjacent": 5516,
      "stating": 5517,
      "1906": 5518,
      "twin": 5519,
      "flew": 5520,
      "##ran": 5521,
      "tokyo": 5522,
      "publications": 5523,
      "##tone": 5524,
      "obviously": 5525,
      "ridge": 5526,
      "storage": 5527,
      "1907": 5528,
      "carl": 5529,
      "pages": 5530,
      "concluded": 5531,
      "desert": 5532,
      "driven": 5533,
      "universities": 5534,
      "ages": 5535,
      "terminal": 5536,
      "sequence": 5537,
      "borough": 5538,
      "250": 5539,
      "constituency": 5540,
      "creative": 5541,
      "cousin": 5542,
      "economics": 5543,
      "dreams": 5544,
      "margaret": 5545,
      "notably": 5546,
      "reduce": 5547,
      "montreal": 5548,
      "mode": 5549,
      "17th": 5550,
      "ears": 5551,
      "saved": 5552,
      "jan": 5553,
      "vocal": 5554,
      "##ica": 5555,
      "1909": 5556,
      "andy": 5557,
      "##jo": 5558,
      "riding": 5559,
      "roughly": 5560,
      "threatened": 5561,
      "##ise": 5562,
      "meters": 5563,
      "meanwhile": 5564,
      "landed": 5565,
      "compete": 5566,
      "repeated": 5567,
      "grass": 5568,
      "czech": 5569,
      "regularly": 5570,
      "charges": 5571,
      "tea": 5572,
      "sudden": 5573,
      "appeal": 5574,
      "##ung": 5575,
      "solution": 5576,
      "describes": 5577,
      "pierre": 5578,
      "classification": 5579,
      "glad": 5580,
      "parking": 5581,
      "##ning": 5582,
      "belt": 5583,
      "physics": 5584,
      "99": 5585,
      "rachel": 5586,
      "add": 5587,
      "hungarian": 5588,
      "participate": 5589,
      "expedition": 5590,
      "damaged": 5591,
      "gift": 5592,
      "childhood": 5593,
      "85": 5594,
      "fifty": 5595,
      "##red": 5596,
      "mathematics": 5597,
      "jumped": 5598,
      "letting": 5599,
      "defensive": 5600,
      "mph": 5601,
      "##ux": 5602,
      "##gh": 5603,
      "testing": 5604,
      "##hip": 5605,
      "hundreds": 5606,
      "shoot": 5607,
      "owners": 5608,
      "matters": 5609,
      "smoke": 5610,
      "israeli": 5611,
      "kentucky": 5612,
      "dancing": 5613,
      "mounted": 5614,
      "grandfather": 5615,
      "emma": 5616,
      "designs": 5617,
      "profit": 5618,
      "argentina": 5619,
      "##gs": 5620,
      "truly": 5621,
      "li": 5622,
      "lawrence": 5623,
      "cole": 5624,
      "begun": 5625,
      "detroit": 5626,
      "willing": 5627,
      "branches": 5628,
      "smiling": 5629,
      "decide": 5630,
      "miami": 5631,
      "enjoyed": 5632,
      "recordings": 5633,
      "##dale": 5634,
      "poverty": 5635,
      "ethnic": 5636,
      "gay": 5637,
      "##bi": 5638,
      "gary": 5639,
      "arabic": 5640,
      "09": 5641,
      "accompanied": 5642,
      "##one": 5643,
      "##ons": 5644,
      "fishing": 5645,
      "determine": 5646,
      "residential": 5647,
      "acid": 5648,
      "##ary": 5649,
      "alice": 5650,
      "returns": 5651,
      "starred": 5652,
      "mail": 5653,
      "##ang": 5654,
      "jonathan": 5655,
      "strategy": 5656,
      "##ue": 5657,
      "net": 5658,
      "forty": 5659,
      "cook": 5660,
      "businesses": 5661,
      "equivalent": 5662,
      "commonwealth": 5663,
      "distinct": 5664,
      "ill": 5665,
      "##cy": 5666,
      "seriously": 5667,
      "##ors": 5668,
      "##ped": 5669,
      "shift": 5670,
      "harris": 5671,
      "replace": 5672,
      "rio": 5673,
      "imagine": 5674,
      "formula": 5675,
      "ensure": 5676,
      "##ber": 5677,
      "additionally": 5678,
      "scheme": 5679,
      "conservation": 5680,
      "occasionally": 5681,
      "purposes": 5682,
      "feels": 5683,
      "favor": 5684,
      "##and": 5685,
      "##ore": 5686,
      "1930s": 5687,
      "contrast": 5688,
      "hanging": 5689,
      "hunt": 5690,
      "movies": 5691,
      "1904": 5692,
      "instruments": 5693,
      "victims": 5694,
      "danish": 5695,
      "christopher": 5696,
      "busy": 5697,
      "demon": 5698,
      "sugar": 5699,
      "earliest": 5700,
      "colony": 5701,
      "studying": 5702,
      "balance": 5703,
      "duties": 5704,
      "##ks": 5705,
      "belgium": 5706,
      "slipped": 5707,
      "carter": 5708,
      "05": 5709,
      "visible": 5710,
      "stages": 5711,
      "iraq": 5712,
      "fifa": 5713,
      "##im": 5714,
      "commune": 5715,
      "forming": 5716,
      "zero": 5717,
      "07": 5718,
      "continuing": 5719,
      "talked": 5720,
      "counties": 5721,
      "legend": 5722,
      "bathroom": 5723,
      "option": 5724,
      "tail": 5725,
      "clay": 5726,
      "daughters": 5727,
      "afterwards": 5728,
      "severe": 5729,
      "jaw": 5730,
      "visitors": 5731,
      "##ded": 5732,
      "devices": 5733,
      "aviation": 5734,
      "russell": 5735,
      "kate": 5736,
      "##vi": 5737,
      "entering": 5738,
      "subjects": 5739,
      "##ino": 5740,
      "temporary": 5741,
      "swimming": 5742,
      "forth": 5743,
      "smooth": 5744,
      "ghost": 5745,
      "audio": 5746,
      "bush": 5747,
      "operates": 5748,
      "rocks": 5749,
      "movements": 5750,
      "signs": 5751,
      "eddie": 5752,
      "##tz": 5753,
      "ann": 5754,
      "voices": 5755,
      "honorary": 5756,
      "06": 5757,
      "memories": 5758,
      "dallas": 5759,
      "pure": 5760,
      "measures": 5761,
      "racial": 5762,
      "promised": 5763,
      "66": 5764,
      "harvard": 5765,
      "ceo": 5766,
      "16th": 5767,
      "parliamentary": 5768,
      "indicate": 5769,
      "benefit": 5770,
      "flesh": 5771,
      "dublin": 5772,
      "louisiana": 5773,
      "1902": 5774,
      "1901": 5775,
      "patient": 5776,
      "sleeping": 5777,
      "1903": 5778,
      "membership": 5779,
      "coastal": 5780,
      "medieval": 5781,
      "wanting": 5782,
      "element": 5783,
      "scholars": 5784,
      "rice": 5785,
      "62": 5786,
      "limit": 5787,
      "survive": 5788,
      "makeup": 5789,
      "rating": 5790,
      "definitely": 5791,
      "collaboration": 5792,
      "obvious": 5793,
      "##tan": 5794,
      "boss": 5795,
      "ms": 5796,
      "baron": 5797,
      "birthday": 5798,
      "linked": 5799,
      "soil": 5800,
      "diocese": 5801,
      "##lan": 5802,
      "ncaa": 5803,
      "##mann": 5804,
      "offensive": 5805,
      "shell": 5806,
      "shouldn": 5807,
      "waist": 5808,
      "##tus": 5809,
      "plain": 5810,
      "ross": 5811,
      "organ": 5812,
      "resolution": 5813,
      "manufacturing": 5814,
      "adding": 5815,
      "relative": 5816,
      "kennedy": 5817,
      "98": 5818,
      "whilst": 5819,
      "moth": 5820,
      "marketing": 5821,
      "gardens": 5822,
      "crash": 5823,
      "72": 5824,
      "heading": 5825,
      "partners": 5826,
      "credited": 5827,
      "carlos": 5828,
      "moves": 5829,
      "cable": 5830,
      "##zi": 5831,
      "marshall": 5832,
      "##out": 5833,
      "depending": 5834,
      "bottle": 5835,
      "represents": 5836,
      "rejected": 5837,
      "responded": 5838,
      "existed": 5839,
      "04": 5840,
      "jobs": 5841,
      "denmark": 5842,
      "lock": 5843,
      "##ating": 5844,
      "treated": 5845,
      "graham": 5846,
      "routes": 5847,
      "talent": 5848,
      "commissioner": 5849,
      "drugs": 5850,
      "secure": 5851,
      "tests": 5852,
      "reign": 5853,
      "restored": 5854,
      "photography": 5855,
      "##gi": 5856,
      "contributions": 5857,
      "oklahoma": 5858,
      "designer": 5859,
      "disc": 5860,
      "grin": 5861,
      "seattle": 5862,
      "robin": 5863,
      "paused": 5864,
      "atlanta": 5865,
      "unusual": 5866,
      "##gate": 5867,
      "praised": 5868,
      "las": 5869,
      "laughing": 5870,
      "satellite": 5871,
      "hungary": 5872,
      "visiting": 5873,
      "##sky": 5874,
      "interesting": 5875,
      "factors": 5876,
      "deck": 5877,
      "poems": 5878,
      "norman": 5879,
      "##water": 5880,
      "stuck": 5881,
      "speaker": 5882,
      "rifle": 5883,
      "domain": 5884,
      "premiered": 5885,
      "##her": 5886,
      "dc": 5887,
      "comics": 5888,
      "actors": 5889,
      "01": 5890,
      "reputation": 5891,
      "eliminated": 5892,
      "8th": 5893,
      "ceiling": 5894,
      "prisoners": 5895,
      "script": 5896,
      "##nce": 5897,
      "leather": 5898,
      "austin": 5899,
      "mississippi": 5900,
      "rapidly": 5901,
      "admiral": 5902,
      "parallel": 5903,
      "charlotte": 5904,
      "guilty": 5905,
      "tools": 5906,
      "gender": 5907,
      "divisions": 5908,
      "fruit": 5909,
      "##bs": 5910,
      "laboratory": 5911,
      "nelson": 5912,
      "fantasy": 5913,
      "marry": 5914,
      "rapid": 5915,
      "aunt": 5916,
      "tribe": 5917,
      "requirements": 5918,
      "aspects": 5919,
      "suicide": 5920,
      "amongst": 5921,
      "adams": 5922,
      "bone": 5923,
      "ukraine": 5924,
      "abc": 5925,
      "kick": 5926,
      "sees": 5927,
      "edinburgh": 5928,
      "clothing": 5929,
      "column": 5930,
      "rough": 5931,
      "gods": 5932,
      "hunting": 5933,
      "broadway": 5934,
      "gathered": 5935,
      "concerns": 5936,
      "##ek": 5937,
      "spending": 5938,
      "ty": 5939,
      "12th": 5940,
      "snapped": 5941,
      "requires": 5942,
      "solar": 5943,
      "bones": 5944,
      "cavalry": 5945,
      "##tta": 5946,
      "iowa": 5947,
      "drinking": 5948,
      "waste": 5949,
      "index": 5950,
      "franklin": 5951,
      "charity": 5952,
      "thompson": 5953,
      "stewart": 5954,
      "tip": 5955,
      "flash": 5956,
      "landscape": 5957,
      "friday": 5958,
      "enjoy": 5959,
      "singh": 5960,
      "poem": 5961,
      "listening": 5962,
      "##back": 5963,
      "eighth": 5964,
      "fred": 5965,
      "differences": 5966,
      "adapted": 5967,
      "bomb": 5968,
      "ukrainian": 5969,
      "surgery": 5970,
      "corporate": 5971,
      "masters": 5972,
      "anywhere": 5973,
      "##more": 5974,
      "waves": 5975,
      "odd": 5976,
      "sean": 5977,
      "portugal": 5978,
      "orleans": 5979,
      "dick": 5980,
      "debate": 5981,
      "kent": 5982,
      "eating": 5983,
      "puerto": 5984,
      "cleared": 5985,
      "96": 5986,
      "expect": 5987,
      "cinema": 5988,
      "97": 5989,
      "guitarist": 5990,
      "blocks": 5991,
      "electrical": 5992,
      "agree": 5993,
      "involving": 5994,
      "depth": 5995,
      "dying": 5996,
      "panel": 5997,
      "struggle": 5998,
      "##ged": 5999,
      "peninsula": 6000,
      "adults": 6001,
      "novels": 6002,
      "emerged": 6003,
      "vienna": 6004,
      "metro": 6005,
      "debuted": 6006,
      "shoes": 6007,
      "tamil": 6008,
      "songwriter": 6009,
      "meets": 6010,
      "prove": 6011,
      "beating": 6012,
      "instance": 6013,
      "heaven": 6014,
      "scared": 6015,
      "sending": 6016,
      "marks": 6017,
      "artistic": 6018,
      "passage": 6019,
      "superior": 6020,
      "03": 6021,
      "significantly": 6022,
      "shopping": 6023,
      "##tive": 6024,
      "retained": 6025,
      "##izing": 6026,
      "malaysia": 6027,
      "technique": 6028,
      "cheeks": 6029,
      "##ola": 6030,
      "warren": 6031,
      "maintenance": 6032,
      "destroy": 6033,
      "extreme": 6034,
      "allied": 6035,
      "120": 6036,
      "appearing": 6037,
      "##yn": 6038,
      "fill": 6039,
      "advice": 6040,
      "alabama": 6041,
      "qualifying": 6042,
      "policies": 6043,
      "cleveland": 6044,
      "hat": 6045,
      "battery": 6046,
      "smart": 6047,
      "authors": 6048,
      "10th": 6049,
      "soundtrack": 6050,
      "acted": 6051,
      "dated": 6052,
      "lb": 6053,
      "glance": 6054,
      "equipped": 6055,
      "coalition": 6056,
      "funny": 6057,
      "outer": 6058,
      "ambassador": 6059,
      "roy": 6060,
      "possibility": 6061,
      "couples": 6062,
      "campbell": 6063,
      "dna": 6064,
      "loose": 6065,
      "ethan": 6066,
      "supplies": 6067,
      "1898": 6068,
      "gonna": 6069,
      "88": 6070,
      "monster": 6071,
      "##res": 6072,
      "shake": 6073,
      "agents": 6074,
      "frequency": 6075,
      "springs": 6076,
      "dogs": 6077,
      "practices": 6078,
      "61": 6079,
      "gang": 6080,
      "plastic": 6081,
      "easier": 6082,
      "suggests": 6083,
      "gulf": 6084,
      "blade": 6085,
      "exposed": 6086,
      "colors": 6087,
      "industries": 6088,
      "markets": 6089,
      "pan": 6090,
      "nervous": 6091,
      "electoral": 6092,
      "charts": 6093,
      "legislation": 6094,
      "ownership": 6095,
      "##idae": 6096,
      "mac": 6097,
      "appointment": 6098,
      "shield": 6099,
      "copy": 6100,
      "assault": 6101,
      "socialist": 6102,
      "abbey": 6103,
      "monument": 6104,
      "license": 6105,
      "throne": 6106,
      "employment": 6107,
      "jay": 6108,
      "93": 6109,
      "replacement": 6110,
      "charter": 6111,
      "cloud": 6112,
      "powered": 6113,
      "suffering": 6114,
      "accounts": 6115,
      "oak": 6116,
      "connecticut": 6117,
      "strongly": 6118,
      "wright": 6119,
      "colour": 6120,
      "crystal": 6121,
      "13th": 6122,
      "context": 6123,
      "welsh": 6124,
      "networks": 6125,
      "voiced": 6126,
      "gabriel": 6127,
      "jerry": 6128,
      "##cing": 6129,
      "forehead": 6130,
      "mp": 6131,
      "##ens": 6132,
      "manage": 6133,
      "schedule": 6134,
      "totally": 6135,
      "remix": 6136,
      "##ii": 6137,
      "forests": 6138,
      "occupation": 6139,
      "print": 6140,
      "nicholas": 6141,
      "brazilian": 6142,
      "strategic": 6143,
      "vampires": 6144,
      "engineers": 6145,
      "76": 6146,
      "roots": 6147,
      "seek": 6148,
      "correct": 6149,
      "instrumental": 6150,
      "und": 6151,
      "alfred": 6152,
      "backed": 6153,
      "hop": 6154,
      "##des": 6155,
      "stanley": 6156,
      "robinson": 6157,
      "traveled": 6158,
      "wayne": 6159,
      "welcome": 6160,
      "austrian": 6161,
      "achieve": 6162,
      "67": 6163,
      "exit": 6164,
      "rates": 6165,
      "1899": 6166,
      "strip": 6167,
      "whereas": 6168,
      "##cs": 6169,
      "sing": 6170,
      "deeply": 6171,
      "adventure": 6172,
      "bobby": 6173,
      "rick": 6174,
      "jamie": 6175,
      "careful": 6176,
      "components": 6177,
      "cap": 6178,
      "useful": 6179,
      "personality": 6180,
      "knee": 6181,
      "##shi": 6182,
      "pushing": 6183,
      "hosts": 6184,
      "02": 6185,
      "protest": 6186,
      "ca": 6187,
      "ottoman": 6188,
      "symphony": 6189,
      "##sis": 6190,
      "63": 6191,
      "boundary": 6192,
      "1890": 6193,
      "processes": 6194,
      "considering": 6195,
      "considerable": 6196,
      "tons": 6197,
      "##work": 6198,
      "##ft": 6199,
      "##nia": 6200,
      "cooper": 6201,
      "trading": 6202,
      "dear": 6203,
      "conduct": 6204,
      "91": 6205,
      "illegal": 6206,
      "apple": 6207,
      "revolutionary": 6208,
      "holiday": 6209,
      "definition": 6210,
      "harder": 6211,
      "##van": 6212,
      "jacob": 6213,
      "circumstances": 6214,
      "destruction": 6215,
      "##lle": 6216,
      "popularity": 6217,
      "grip": 6218,
      "classified": 6219,
      "liverpool": 6220,
      "donald": 6221,
      "baltimore": 6222,
      "flows": 6223,
      "seeking": 6224,
      "honour": 6225,
      "approval": 6226,
      "92": 6227,
      "mechanical": 6228,
      "till": 6229,
      "happening": 6230,
      "statue": 6231,
      "critic": 6232,
      "increasingly": 6233,
      "immediate": 6234,
      "describe": 6235,
      "commerce": 6236,
      "stare": 6237,
      "##ster": 6238,
      "indonesia": 6239,
      "meat": 6240,
      "rounds": 6241,
      "boats": 6242,
      "baker": 6243,
      "orthodox": 6244,
      "depression": 6245,
      "formally": 6246,
      "worn": 6247,
      "naked": 6248,
      "claire": 6249,
      "muttered": 6250,
      "sentence": 6251,
      "11th": 6252,
      "emily": 6253,
      "document": 6254,
      "77": 6255,
      "criticism": 6256,
      "wished": 6257,
      "vessel": 6258,
      "spiritual": 6259,
      "bent": 6260,
      "virgin": 6261,
      "parker": 6262,
      "minimum": 6263,
      "murray": 6264,
      "lunch": 6265,
      "danny": 6266,
      "printed": 6267,
      "compilation": 6268,
      "keyboards": 6269,
      "false": 6270,
      "blow": 6271,
      "belonged": 6272,
      "68": 6273,
      "raising": 6274,
      "78": 6275,
      "cutting": 6276,
      "##board": 6277,
      "pittsburgh": 6278,
      "##up": 6279,
      "9th": 6280,
      "shadows": 6281,
      "81": 6282,
      "hated": 6283,
      "indigenous": 6284,
      "jon": 6285,
      "15th": 6286,
      "barry": 6287,
      "scholar": 6288,
      "ah": 6289,
      "##zer": 6290,
      "oliver": 6291,
      "##gy": 6292,
      "stick": 6293,
      "susan": 6294,
      "meetings": 6295,
      "attracted": 6296,
      "spell": 6297,
      "romantic": 6298,
      "##ver": 6299,
      "ye": 6300,
      "1895": 6301,
      "photo": 6302,
      "demanded": 6303,
      "customers": 6304,
      "##ac": 6305,
      "1896": 6306,
      "logan": 6307,
      "revival": 6308,
      "keys": 6309,
      "modified": 6310,
      "commanded": 6311,
      "jeans": 6312,
      "##ious": 6313,
      "upset": 6314,
      "raw": 6315,
      "phil": 6316,
      "detective": 6317,
      "hiding": 6318,
      "resident": 6319,
      "vincent": 6320,
      "##bly": 6321,
      "experiences": 6322,
      "diamond": 6323,
      "defeating": 6324,
      "coverage": 6325,
      "lucas": 6326,
      "external": 6327,
      "parks": 6328,
      "franchise": 6329,
      "helen": 6330,
      "bible": 6331,
      "successor": 6332,
      "percussion": 6333,
      "celebrated": 6334,
      "il": 6335,
      "lift": 6336,
      "profile": 6337,
      "clan": 6338,
      "romania": 6339,
      "##ied": 6340,
      "mills": 6341,
      "##su": 6342,
      "nobody": 6343,
      "achievement": 6344,
      "shrugged": 6345,
      "fault": 6346,
      "1897": 6347,
      "rhythm": 6348,
      "initiative": 6349,
      "breakfast": 6350,
      "carbon": 6351,
      "700": 6352,
      "69": 6353,
      "lasted": 6354,
      "violent": 6355,
      "74": 6356,
      "wound": 6357,
      "ken": 6358,
      "killer": 6359,
      "gradually": 6360,
      "filmed": 6361,
      "°c": 6362,
      "dollars": 6363,
      "processing": 6364,
      "94": 6365,
      "remove": 6366,
      "criticized": 6367,
      "guests": 6368,
      "sang": 6369,
      "chemistry": 6370,
      "##vin": 6371,
      "legislature": 6372,
      "disney": 6373,
      "##bridge": 6374,
      "uniform": 6375,
      "escaped": 6376,
      "integrated": 6377,
      "proposal": 6378,
      "purple": 6379,
      "denied": 6380,
      "liquid": 6381,
      "karl": 6382,
      "influential": 6383,
      "morris": 6384,
      "nights": 6385,
      "stones": 6386,
      "intense": 6387,
      "experimental": 6388,
      "twisted": 6389,
      "71": 6390,
      "84": 6391,
      "##ld": 6392,
      "pace": 6393,
      "nazi": 6394,
      "mitchell": 6395,
      "ny": 6396,
      "blind": 6397,
      "reporter": 6398,
      "newspapers": 6399,
      "14th": 6400,
      "centers": 6401,
      "burn": 6402,
      "basin": 6403,
      "forgotten": 6404,
      "surviving": 6405,
      "filed": 6406,
      "collections": 6407,
      "monastery": 6408,
      "losses": 6409,
      "manual": 6410,
      "couch": 6411,
      "description": 6412,
      "appropriate": 6413,
      "merely": 6414,
      "tag": 6415,
      "missions": 6416,
      "sebastian": 6417,
      "restoration": 6418,
      "replacing": 6419,
      "triple": 6420,
      "73": 6421,
      "elder": 6422,
      "julia": 6423,
      "warriors": 6424,
      "benjamin": 6425,
      "julian": 6426,
      "convinced": 6427,
      "stronger": 6428,
      "amazing": 6429,
      "declined": 6430,
      "versus": 6431,
      "merchant": 6432,
      "happens": 6433,
      "output": 6434,
      "finland": 6435,
      "bare": 6436,
      "barbara": 6437,
      "absence": 6438,
      "ignored": 6439,
      "dawn": 6440,
      "injuries": 6441,
      "##port": 6442,
      "producers": 6443,
      "##ram": 6444,
      "82": 6445,
      "luis": 6446,
      "##ities": 6447,
      "kw": 6448,
      "admit": 6449,
      "expensive": 6450,
      "electricity": 6451,
      "nba": 6452,
      "exception": 6453,
      "symbol": 6454,
      "##ving": 6455,
      "ladies": 6456,
      "shower": 6457,
      "sheriff": 6458,
      "characteristics": 6459,
      "##je": 6460,
      "aimed": 6461,
      "button": 6462,
      "ratio": 6463,
      "effectively": 6464,
      "summit": 6465,
      "angle": 6466,
      "jury": 6467,
      "bears": 6468,
      "foster": 6469,
      "vessels": 6470,
      "pants": 6471,
      "executed": 6472,
      "evans": 6473,
      "dozen": 6474,
      "advertising": 6475,
      "kicked": 6476,
      "patrol": 6477,
      "1889": 6478,
      "competitions": 6479,
      "lifetime": 6480,
      "principles": 6481,
      "athletics": 6482,
      "##logy": 6483,
      "birmingham": 6484,
      "sponsored": 6485,
      "89": 6486,
      "rob": 6487,
      "nomination": 6488,
      "1893": 6489,
      "acoustic": 6490,
      "##sm": 6491,
      "creature": 6492,
      "longest": 6493,
      "##tra": 6494,
      "credits": 6495,
      "harbor": 6496,
      "dust": 6497,
      "josh": 6498,
      "##so": 6499,
      "territories": 6500,
      "milk": 6501,
      "infrastructure": 6502,
      "completion": 6503,
      "thailand": 6504,
      "indians": 6505,
      "leon": 6506,
      "archbishop": 6507,
      "##sy": 6508,
      "assist": 6509,
      "pitch": 6510,
      "blake": 6511,
      "arrangement": 6512,
      "girlfriend": 6513,
      "serbian": 6514,
      "operational": 6515,
      "hence": 6516,
      "sad": 6517,
      "scent": 6518,
      "fur": 6519,
      "dj": 6520,
      "sessions": 6521,
      "hp": 6522,
      "refer": 6523,
      "rarely": 6524,
      "##ora": 6525,
      "exists": 6526,
      "1892": 6527,
      "##ten": 6528,
      "scientists": 6529,
      "dirty": 6530,
      "penalty": 6531,
      "burst": 6532,
      "portrait": 6533,
      "seed": 6534,
      "79": 6535,
      "pole": 6536,
      "limits": 6537,
      "rival": 6538,
      "1894": 6539,
      "stable": 6540,
      "alpha": 6541,
      "grave": 6542,
      "constitutional": 6543,
      "alcohol": 6544,
      "arrest": 6545,
      "flower": 6546,
      "mystery": 6547,
      "devil": 6548,
      "architectural": 6549,
      "relationships": 6550,
      "greatly": 6551,
      "habitat": 6552,
      "##istic": 6553,
      "larry": 6554,
      "progressive": 6555,
      "remote": 6556,
      "cotton": 6557,
      "##ics": 6558,
      "##ok": 6559,
      "preserved": 6560,
      "reaches": 6561,
      "##ming": 6562,
      "cited": 6563,
      "86": 6564,
      "vast": 6565,
      "scholarship": 6566,
      "decisions": 6567,
      "cbs": 6568,
      "joy": 6569,
      "teach": 6570,
      "1885": 6571,
      "editions": 6572,
      "knocked": 6573,
      "eve": 6574,
      "searching": 6575,
      "partly": 6576,
      "participation": 6577,
      "gap": 6578,
      "animated": 6579,
      "fate": 6580,
      "excellent": 6581,
      "##ett": 6582,
      "na": 6583,
      "87": 6584,
      "alternate": 6585,
      "saints": 6586,
      "youngest": 6587,
      "##ily": 6588,
      "climbed": 6589,
      "##ita": 6590,
      "##tors": 6591,
      "suggest": 6592,
      "##ct": 6593,
      "discussion": 6594,
      "staying": 6595,
      "choir": 6596,
      "lakes": 6597,
      "jacket": 6598,
      "revenue": 6599,
      "nevertheless": 6600,
      "peaked": 6601,
      "instrument": 6602,
      "wondering": 6603,
      "annually": 6604,
      "managing": 6605,
      "neil": 6606,
      "1891": 6607,
      "signing": 6608,
      "terry": 6609,
      "##ice": 6610,
      "apply": 6611,
      "clinical": 6612,
      "brooklyn": 6613,
      "aim": 6614,
      "catherine": 6615,
      "fuck": 6616,
      "farmers": 6617,
      "figured": 6618,
      "ninth": 6619,
      "pride": 6620,
      "hugh": 6621,
      "evolution": 6622,
      "ordinary": 6623,
      "involvement": 6624,
      "comfortable": 6625,
      "shouted": 6626,
      "tech": 6627,
      "encouraged": 6628,
      "taiwan": 6629,
      "representation": 6630,
      "sharing": 6631,
      "##lia": 6632,
      "##em": 6633,
      "panic": 6634,
      "exact": 6635,
      "cargo": 6636,
      "competing": 6637,
      "fat": 6638,
      "cried": 6639,
      "83": 6640,
      "1920s": 6641,
      "occasions": 6642,
      "pa": 6643,
      "cabin": 6644,
      "borders": 6645,
      "utah": 6646,
      "marcus": 6647,
      "##isation": 6648,
      "badly": 6649,
      "muscles": 6650,
      "##ance": 6651,
      "victorian": 6652,
      "transition": 6653,
      "warner": 6654,
      "bet": 6655,
      "permission": 6656,
      "##rin": 6657,
      "slave": 6658,
      "terrible": 6659,
      "similarly": 6660,
      "shares": 6661,
      "seth": 6662,
      "uefa": 6663,
      "possession": 6664,
      "medals": 6665,
      "benefits": 6666,
      "colleges": 6667,
      "lowered": 6668,
      "perfectly": 6669,
      "mall": 6670,
      "transit": 6671,
      "##ye": 6672,
      "##kar": 6673,
      "publisher": 6674,
      "##ened": 6675,
      "harrison": 6676,
      "deaths": 6677,
      "elevation": 6678,
      "##ae": 6679,
      "asleep": 6680,
      "machines": 6681,
      "sigh": 6682,
      "ash": 6683,
      "hardly": 6684,
      "argument": 6685,
      "occasion": 6686,
      "parent": 6687,
      "leo": 6688,
      "decline": 6689,
      "1888": 6690,
      "contribution": 6691,
      "##ua": 6692,
      "concentration": 6693,
      "1000": 6694,
      "opportunities": 6695,
      "hispanic": 6696,
      "guardian": 6697,
      "extent": 6698,
      "emotions": 6699,
      "hips": 6700,
      "mason": 6701,
      "volumes": 6702,
      "bloody": 6703,
      "controversy": 6704,
      "diameter": 6705,
      "steady": 6706,
      "mistake": 6707,
      "phoenix": 6708,
      "identify": 6709,
      "violin": 6710,
      "##sk": 6711,
      "departure": 6712,
      "richmond": 6713,
      "spin": 6714,
      "funeral": 6715,
      "enemies": 6716,
      "1864": 6717,
      "gear": 6718,
      "literally": 6719,
      "connor": 6720,
      "random": 6721,
      "sergeant": 6722,
      "grab": 6723,
      "confusion": 6724,
      "1865": 6725,
      "transmission": 6726,
      "informed": 6727,
      "op": 6728,
      "leaning": 6729,
      "sacred": 6730,
      "suspended": 6731,
      "thinks": 6732,
      "gates": 6733,
      "portland": 6734,
      "luck": 6735,
      "agencies": 6736,
      "yours": 6737,
      "hull": 6738,
      "expert": 6739,
      "muscle": 6740,
      "layer": 6741,
      "practical": 6742,
      "sculpture": 6743,
      "jerusalem": 6744,
      "latest": 6745,
      "lloyd": 6746,
      "statistics": 6747,
      "deeper": 6748,
      "recommended": 6749,
      "warrior": 6750,
      "arkansas": 6751,
      "mess": 6752,
      "supports": 6753,
      "greg": 6754,
      "eagle": 6755,
      "1880": 6756,
      "recovered": 6757,
      "rated": 6758,
      "concerts": 6759,
      "rushed": 6760,
      "##ano": 6761,
      "stops": 6762,
      "eggs": 6763,
      "files": 6764,
      "premiere": 6765,
      "keith": 6766,
      "##vo": 6767,
      "delhi": 6768,
      "turner": 6769,
      "pit": 6770,
      "affair": 6771,
      "belief": 6772,
      "paint": 6773,
      "##zing": 6774,
      "mate": 6775,
      "##ach": 6776,
      "##ev": 6777,
      "victim": 6778,
      "##ology": 6779,
      "withdrew": 6780,
      "bonus": 6781,
      "styles": 6782,
      "fled": 6783,
      "##ud": 6784,
      "glasgow": 6785,
      "technologies": 6786,
      "funded": 6787,
      "nbc": 6788,
      "adaptation": 6789,
      "##ata": 6790,
      "portrayed": 6791,
      "cooperation": 6792,
      "supporters": 6793,
      "judges": 6794,
      "bernard": 6795,
      "justin": 6796,
      "hallway": 6797,
      "ralph": 6798,
      "##ick": 6799,
      "graduating": 6800,
      "controversial": 6801,
      "distant": 6802,
      "continental": 6803,
      "spider": 6804,
      "bite": 6805,
      "##ho": 6806,
      "recognize": 6807,
      "intention": 6808,
      "mixing": 6809,
      "##ese": 6810,
      "egyptian": 6811,
      "bow": 6812,
      "tourism": 6813,
      "suppose": 6814,
      "claiming": 6815,
      "tiger": 6816,
      "dominated": 6817,
      "participants": 6818,
      "vi": 6819,
      "##ru": 6820,
      "nurse": 6821,
      "partially": 6822,
      "tape": 6823,
      "##rum": 6824,
      "psychology": 6825,
      "##rn": 6826,
      "essential": 6827,
      "touring": 6828,
      "duo": 6829,
      "voting": 6830,
      "civilian": 6831,
      "emotional": 6832,
      "channels": 6833,
      "##king": 6834,
      "apparent": 6835,
      "hebrew": 6836,
      "1887": 6837,
      "tommy": 6838,
      "carrier": 6839,
      "intersection": 6840,
      "beast": 6841,
      "hudson": 6842,
      "##gar": 6843,
      "##zo": 6844,
      "lab": 6845,
      "nova": 6846,
      "bench": 6847,
      "discuss": 6848,
      "costa": 6849,
      "##ered": 6850,
      "detailed": 6851,
      "behalf": 6852,
      "drivers": 6853,
      "unfortunately": 6854,
      "obtain": 6855,
      "##lis": 6856,
      "rocky": 6857,
      "##dae": 6858,
      "siege": 6859,
      "friendship": 6860,
      "honey": 6861,
      "##rian": 6862,
      "1861": 6863,
      "amy": 6864,
      "hang": 6865,
      "posted": 6866,
      "governments": 6867,
      "collins": 6868,
      "respond": 6869,
      "wildlife": 6870,
      "preferred": 6871,
      "operator": 6872,
      "##po": 6873,
      "laura": 6874,
      "pregnant": 6875,
      "videos": 6876,
      "dennis": 6877,
      "suspected": 6878,
      "boots": 6879,
      "instantly": 6880,
      "weird": 6881,
      "automatic": 6882,
      "businessman": 6883,
      "alleged": 6884,
      "placing": 6885,
      "throwing": 6886,
      "ph": 6887,
      "mood": 6888,
      "1862": 6889,
      "perry": 6890,
      "venue": 6891,
      "jet": 6892,
      "remainder": 6893,
      "##lli": 6894,
      "##ci": 6895,
      "passion": 6896,
      "biological": 6897,
      "boyfriend": 6898,
      "1863": 6899,
      "dirt": 6900,
      "buffalo": 6901,
      "ron": 6902,
      "segment": 6903,
      "fa": 6904,
      "abuse": 6905,
      "##era": 6906,
      "genre": 6907,
      "thrown": 6908,
      "stroke": 6909,
      "colored": 6910,
      "stress": 6911,
      "exercise": 6912,
      "displayed": 6913,
      "##gen": 6914,
      "struggled": 6915,
      "##tti": 6916,
      "abroad": 6917,
      "dramatic": 6918,
      "wonderful": 6919,
      "thereafter": 6920,
      "madrid": 6921,
      "component": 6922,
      "widespread": 6923,
      "##sed": 6924,
      "tale": 6925,
      "citizen": 6926,
      "todd": 6927,
      "monday": 6928,
      "1886": 6929,
      "vancouver": 6930,
      "overseas": 6931,
      "forcing": 6932,
      "crying": 6933,
      "descent": 6934,
      "##ris": 6935,
      "discussed": 6936,
      "substantial": 6937,
      "ranks": 6938,
      "regime": 6939,
      "1870": 6940,
      "provinces": 6941,
      "switch": 6942,
      "drum": 6943,
      "zane": 6944,
      "ted": 6945,
      "tribes": 6946,
      "proof": 6947,
      "lp": 6948,
      "cream": 6949,
      "researchers": 6950,
      "volunteer": 6951,
      "manor": 6952,
      "silk": 6953,
      "milan": 6954,
      "donated": 6955,
      "allies": 6956,
      "venture": 6957,
      "principle": 6958,
      "delivery": 6959,
      "enterprise": 6960,
      "##ves": 6961,
      "##ans": 6962,
      "bars": 6963,
      "traditionally": 6964,
      "witch": 6965,
      "reminded": 6966,
      "copper": 6967,
      "##uk": 6968,
      "pete": 6969,
      "inter": 6970,
      "links": 6971,
      "colin": 6972,
      "grinned": 6973,
      "elsewhere": 6974,
      "competitive": 6975,
      "frequent": 6976,
      "##oy": 6977,
      "scream": 6978,
      "##hu": 6979,
      "tension": 6980,
      "texts": 6981,
      "submarine": 6982,
      "finnish": 6983,
      "defending": 6984,
      "defend": 6985,
      "pat": 6986,
      "detail": 6987,
      "1884": 6988,
      "affiliated": 6989,
      "stuart": 6990,
      "themes": 6991,
      "villa": 6992,
      "periods": 6993,
      "tool": 6994,
      "belgian": 6995,
      "ruling": 6996,
      "crimes": 6997,
      "answers": 6998,
      "folded": 6999,
      "licensed": 7000,
      "resort": 7001,
      "demolished": 7002,
      "hans": 7003,
      "lucy": 7004,
      "1881": 7005,
      "lion": 7006,
      "traded": 7007,
      "photographs": 7008,
      "writes": 7009,
      "craig": 7010,
      "##fa": 7011,
      "trials": 7012,
      "generated": 7013,
      "beth": 7014,
      "noble": 7015,
      "debt": 7016,
      "percentage": 7017,
      "yorkshire": 7018,
      "erected": 7019,
      "ss": 7020,
      "viewed": 7021,
      "grades": 7022,
      "confidence": 7023,
      "ceased": 7024,
      "islam": 7025,
      "telephone": 7026,
      "retail": 7027,
      "##ible": 7028,
      "chile": 7029,
      "m²": 7030,
      "roberts": 7031,
      "sixteen": 7032,
      "##ich": 7033,
      "commented": 7034,
      "hampshire": 7035,
      "innocent": 7036,
      "dual": 7037,
      "pounds": 7038,
      "checked": 7039,
      "regulations": 7040,
      "afghanistan": 7041,
      "sung": 7042,
      "rico": 7043,
      "liberty": 7044,
      "assets": 7045,
      "bigger": 7046,
      "options": 7047,
      "angels": 7048,
      "relegated": 7049,
      "tribute": 7050,
      "wells": 7051,
      "attending": 7052,
      "leaf": 7053,
      "##yan": 7054,
      "butler": 7055,
      "romanian": 7056,
      "forum": 7057,
      "monthly": 7058,
      "lisa": 7059,
      "patterns": 7060,
      "gmina": 7061,
      "##tory": 7062,
      "madison": 7063,
      "hurricane": 7064,
      "rev": 7065,
      "##ians": 7066,
      "bristol": 7067,
      "##ula": 7068,
      "elite": 7069,
      "valuable": 7070,
      "disaster": 7071,
      "democracy": 7072,
      "awareness": 7073,
      "germans": 7074,
      "freyja": 7075,
      "##ins": 7076,
      "loop": 7077,
      "absolutely": 7078,
      "paying": 7079,
      "populations": 7080,
      "maine": 7081,
      "sole": 7082,
      "prayer": 7083,
      "spencer": 7084,
      "releases": 7085,
      "doorway": 7086,
      "bull": 7087,
      "##ani": 7088,
      "lover": 7089,
      "midnight": 7090,
      "conclusion": 7091,
      "##sson": 7092,
      "thirteen": 7093,
      "lily": 7094,
      "mediterranean": 7095,
      "##lt": 7096,
      "nhl": 7097,
      "proud": 7098,
      "sample": 7099,
      "##hill": 7100,
      "drummer": 7101,
      "guinea": 7102,
      "##ova": 7103,
      "murphy": 7104,
      "climb": 7105,
      "##ston": 7106,
      "instant": 7107,
      "attributed": 7108,
      "horn": 7109,
      "ain": 7110,
      "railways": 7111,
      "steven": 7112,
      "##ao": 7113,
      "autumn": 7114,
      "ferry": 7115,
      "opponent": 7116,
      "root": 7117,
      "traveling": 7118,
      "secured": 7119,
      "corridor": 7120,
      "stretched": 7121,
      "tales": 7122,
      "sheet": 7123,
      "trinity": 7124,
      "cattle": 7125,
      "helps": 7126,
      "indicates": 7127,
      "manhattan": 7128,
      "murdered": 7129,
      "fitted": 7130,
      "1882": 7131,
      "gentle": 7132,
      "grandmother": 7133,
      "mines": 7134,
      "shocked": 7135,
      "vegas": 7136,
      "produces": 7137,
      "##light": 7138,
      "caribbean": 7139,
      "##ou": 7140,
      "belong": 7141,
      "continuous": 7142,
      "desperate": 7143,
      "drunk": 7144,
      "historically": 7145,
      "trio": 7146,
      "waved": 7147,
      "raf": 7148,
      "dealing": 7149,
      "nathan": 7150,
      "bat": 7151,
      "murmured": 7152,
      "interrupted": 7153,
      "residing": 7154,
      "scientist": 7155,
      "pioneer": 7156,
      "harold": 7157,
      "aaron": 7158,
      "##net": 7159,
      "delta": 7160,
      "attempting": 7161,
      "minority": 7162,
      "mini": 7163,
      "believes": 7164,
      "chorus": 7165,
      "tend": 7166,
      "lots": 7167,
      "eyed": 7168,
      "indoor": 7169,
      "load": 7170,
      "shots": 7171,
      "updated": 7172,
      "jail": 7173,
      "##llo": 7174,
      "concerning": 7175,
      "connecting": 7176,
      "wealth": 7177,
      "##ved": 7178,
      "slaves": 7179,
      "arrive": 7180,
      "rangers": 7181,
      "sufficient": 7182,
      "rebuilt": 7183,
      "##wick": 7184,
      "cardinal": 7185,
      "flood": 7186,
      "muhammad": 7187,
      "whenever": 7188,
      "relation": 7189,
      "runners": 7190,
      "moral": 7191,
      "repair": 7192,
      "viewers": 7193,
      "arriving": 7194,
      "revenge": 7195,
      "punk": 7196,
      "assisted": 7197,
      "bath": 7198,
      "fairly": 7199,
      "breathe": 7200,
      "lists": 7201,
      "innings": 7202,
      "illustrated": 7203,
      "whisper": 7204,
      "nearest": 7205,
      "voters": 7206,
      "clinton": 7207,
      "ties": 7208,
      "ultimate": 7209,
      "screamed": 7210,
      "beijing": 7211,
      "lions": 7212,
      "andre": 7213,
      "fictional": 7214,
      "gathering": 7215,
      "comfort": 7216,
      "radar": 7217,
      "suitable": 7218,
      "dismissed": 7219,
      "hms": 7220,
      "ban": 7221,
      "pine": 7222,
      "wrist": 7223,
      "atmosphere": 7224,
      "voivodeship": 7225,
      "bid": 7226,
      "timber": 7227,
      "##ned": 7228,
      "##nan": 7229,
      "giants": 7230,
      "##ane": 7231,
      "cameron": 7232,
      "recovery": 7233,
      "uss": 7234,
      "identical": 7235,
      "categories": 7236,
      "switched": 7237,
      "serbia": 7238,
      "laughter": 7239,
      "noah": 7240,
      "ensemble": 7241,
      "therapy": 7242,
      "peoples": 7243,
      "touching": 7244,
      "##off": 7245,
      "locally": 7246,
      "pearl": 7247,
      "platforms": 7248,
      "everywhere": 7249,
      "ballet": 7250,
      "tables": 7251,
      "lanka": 7252,
      "herbert": 7253,
      "outdoor": 7254,
      "toured": 7255,
      "derek": 7256,
      "1883": 7257,
      "spaces": 7258,
      "contested": 7259,
      "swept": 7260,
      "1878": 7261,
      "exclusive": 7262,
      "slight": 7263,
      "connections": 7264,
      "##dra": 7265,
      "winds": 7266,
      "prisoner": 7267,
      "collective": 7268,
      "bangladesh": 7269,
      "tube": 7270,
      "publicly": 7271,
      "wealthy": 7272,
      "thai": 7273,
      "##ys": 7274,
      "isolated": 7275,
      "select": 7276,
      "##ric": 7277,
      "insisted": 7278,
      "pen": 7279,
      "fortune": 7280,
      "ticket": 7281,
      "spotted": 7282,
      "reportedly": 7283,
      "animation": 7284,
      "enforcement": 7285,
      "tanks": 7286,
      "110": 7287,
      "decides": 7288,
      "wider": 7289,
      "lowest": 7290,
      "owen": 7291,
      "##time": 7292,
      "nod": 7293,
      "hitting": 7294,
      "##hn": 7295,
      "gregory": 7296,
      "furthermore": 7297,
      "magazines": 7298,
      "fighters": 7299,
      "solutions": 7300,
      "##ery": 7301,
      "pointing": 7302,
      "requested": 7303,
      "peru": 7304,
      "reed": 7305,
      "chancellor": 7306,
      "knights": 7307,
      "mask": 7308,
      "worker": 7309,
      "eldest": 7310,
      "flames": 7311,
      "reduction": 7312,
      "1860": 7313,
      "volunteers": 7314,
      "##tis": 7315,
      "reporting": 7316,
      "##hl": 7317,
      "wire": 7318,
      "advisory": 7319,
      "endemic": 7320,
      "origins": 7321,
      "settlers": 7322,
      "pursue": 7323,
      "knock": 7324,
      "consumer": 7325,
      "1876": 7326,
      "eu": 7327,
      "compound": 7328,
      "creatures": 7329,
      "mansion": 7330,
      "sentenced": 7331,
      "ivan": 7332,
      "deployed": 7333,
      "guitars": 7334,
      "frowned": 7335,
      "involves": 7336,
      "mechanism": 7337,
      "kilometers": 7338,
      "perspective": 7339,
      "shops": 7340,
      "maps": 7341,
      "terminus": 7342,
      "duncan": 7343,
      "alien": 7344,
      "fist": 7345,
      "bridges": 7346,
      "##pers": 7347,
      "heroes": 7348,
      "fed": 7349,
      "derby": 7350,
      "swallowed": 7351,
      "##ros": 7352,
      "patent": 7353,
      "sara": 7354,
      "illness": 7355,
      "characterized": 7356,
      "adventures": 7357,
      "slide": 7358,
      "hawaii": 7359,
      "jurisdiction": 7360,
      "##op": 7361,
      "organised": 7362,
      "##side": 7363,
      "adelaide": 7364,
      "walks": 7365,
      "biology": 7366,
      "se": 7367,
      "##ties": 7368,
      "rogers": 7369,
      "swing": 7370,
      "tightly": 7371,
      "boundaries": 7372,
      "##rie": 7373,
      "prepare": 7374,
      "implementation": 7375,
      "stolen": 7376,
      "##sha": 7377,
      "certified": 7378,
      "colombia": 7379,
      "edwards": 7380,
      "garage": 7381,
      "##mm": 7382,
      "recalled": 7383,
      "##ball": 7384,
      "rage": 7385,
      "harm": 7386,
      "nigeria": 7387,
      "breast": 7388,
      "##ren": 7389,
      "furniture": 7390,
      "pupils": 7391,
      "settle": 7392,
      "##lus": 7393,
      "cuba": 7394,
      "balls": 7395,
      "client": 7396,
      "alaska": 7397,
      "21st": 7398,
      "linear": 7399,
      "thrust": 7400,
      "celebration": 7401,
      "latino": 7402,
      "genetic": 7403,
      "terror": 7404,
      "##cia": 7405,
      "##ening": 7406,
      "lightning": 7407,
      "fee": 7408,
      "witness": 7409,
      "lodge": 7410,
      "establishing": 7411,
      "skull": 7412,
      "##ique": 7413,
      "earning": 7414,
      "hood": 7415,
      "##ei": 7416,
      "rebellion": 7417,
      "wang": 7418,
      "sporting": 7419,
      "warned": 7420,
      "missile": 7421,
      "devoted": 7422,
      "activist": 7423,
      "porch": 7424,
      "worship": 7425,
      "fourteen": 7426,
      "package": 7427,
      "1871": 7428,
      "decorated": 7429,
      "##shire": 7430,
      "housed": 7431,
      "##ock": 7432,
      "chess": 7433,
      "sailed": 7434,
      "doctors": 7435,
      "oscar": 7436,
      "joan": 7437,
      "treat": 7438,
      "garcia": 7439,
      "harbour": 7440,
      "jeremy": 7441,
      "##ire": 7442,
      "traditions": 7443,
      "dominant": 7444,
      "jacques": 7445,
      "##gon": 7446,
      "##wan": 7447,
      "relocated": 7448,
      "1879": 7449,
      "amendment": 7450,
      "sized": 7451,
      "companion": 7452,
      "simultaneously": 7453,
      "volleyball": 7454,
      "spun": 7455,
      "acre": 7456,
      "increases": 7457,
      "stopping": 7458,
      "loves": 7459,
      "belongs": 7460,
      "affect": 7461,
      "drafted": 7462,
      "tossed": 7463,
      "scout": 7464,
      "battles": 7465,
      "1875": 7466,
      "filming": 7467,
      "shoved": 7468,
      "munich": 7469,
      "tenure": 7470,
      "vertical": 7471,
      "romance": 7472,
      "pc": 7473,
      "##cher": 7474,
      "argue": 7475,
      "##ical": 7476,
      "craft": 7477,
      "ranging": 7478,
      "www": 7479,
      "opens": 7480,
      "honest": 7481,
      "tyler": 7482,
      "yesterday": 7483,
      "virtual": 7484,
      "##let": 7485,
      "muslims": 7486,
      "reveal": 7487,
      "snake": 7488,
      "immigrants": 7489,
      "radical": 7490,
      "screaming": 7491,
      "speakers": 7492,
      "firing": 7493,
      "saving": 7494,
      "belonging": 7495,
      "ease": 7496,
      "lighting": 7497,
      "prefecture": 7498,
      "blame": 7499,
      "farmer": 7500,
      "hungry": 7501,
      "grows": 7502,
      "rubbed": 7503,
      "beam": 7504,
      "sur": 7505,
      "subsidiary": 7506,
      "##cha": 7507,
      "armenian": 7508,
      "sao": 7509,
      "dropping": 7510,
      "conventional": 7511,
      "##fer": 7512,
      "microsoft": 7513,
      "reply": 7514,
      "qualify": 7515,
      "spots": 7516,
      "1867": 7517,
      "sweat": 7518,
      "festivals": 7519,
      "##ken": 7520,
      "immigration": 7521,
      "physician": 7522,
      "discover": 7523,
      "exposure": 7524,
      "sandy": 7525,
      "explanation": 7526,
      "isaac": 7527,
      "implemented": 7528,
      "##fish": 7529,
      "hart": 7530,
      "initiated": 7531,
      "connect": 7532,
      "stakes": 7533,
      "presents": 7534,
      "heights": 7535,
      "householder": 7536,
      "pleased": 7537,
      "tourist": 7538,
      "regardless": 7539,
      "slip": 7540,
      "closest": 7541,
      "##ction": 7542,
      "surely": 7543,
      "sultan": 7544,
      "brings": 7545,
      "riley": 7546,
      "preparation": 7547,
      "aboard": 7548,
      "slammed": 7549,
      "baptist": 7550,
      "experiment": 7551,
      "ongoing": 7552,
      "interstate": 7553,
      "organic": 7554,
      "playoffs": 7555,
      "##ika": 7556,
      "1877": 7557,
      "130": 7558,
      "##tar": 7559,
      "hindu": 7560,
      "error": 7561,
      "tours": 7562,
      "tier": 7563,
      "plenty": 7564,
      "arrangements": 7565,
      "talks": 7566,
      "trapped": 7567,
      "excited": 7568,
      "sank": 7569,
      "ho": 7570,
      "athens": 7571,
      "1872": 7572,
      "denver": 7573,
      "welfare": 7574,
      "suburb": 7575,
      "athletes": 7576,
      "trick": 7577,
      "diverse": 7578,
      "belly": 7579,
      "exclusively": 7580,
      "yelled": 7581,
      "1868": 7582,
      "##med": 7583,
      "conversion": 7584,
      "##ette": 7585,
      "1874": 7586,
      "internationally": 7587,
      "computers": 7588,
      "conductor": 7589,
      "abilities": 7590,
      "sensitive": 7591,
      "hello": 7592,
      "dispute": 7593,
      "measured": 7594,
      "globe": 7595,
      "rocket": 7596,
      "prices": 7597,
      "amsterdam": 7598,
      "flights": 7599,
      "tigers": 7600,
      "inn": 7601,
      "municipalities": 7602,
      "emotion": 7603,
      "references": 7604,
      "3d": 7605,
      "##mus": 7606,
      "explains": 7607,
      "airlines": 7608,
      "manufactured": 7609,
      "pm": 7610,
      "archaeological": 7611,
      "1873": 7612,
      "interpretation": 7613,
      "devon": 7614,
      "comment": 7615,
      "##ites": 7616,
      "settlements": 7617,
      "kissing": 7618,
      "absolute": 7619,
      "improvement": 7620,
      "suite": 7621,
      "impressed": 7622,
      "barcelona": 7623,
      "sullivan": 7624,
      "jefferson": 7625,
      "towers": 7626,
      "jesse": 7627,
      "julie": 7628,
      "##tin": 7629,
      "##lu": 7630,
      "grandson": 7631,
      "hi": 7632,
      "gauge": 7633,
      "regard": 7634,
      "rings": 7635,
      "interviews": 7636,
      "trace": 7637,
      "raymond": 7638,
      "thumb": 7639,
      "departments": 7640,
      "burns": 7641,
      "serial": 7642,
      "bulgarian": 7643,
      "scores": 7644,
      "demonstrated": 7645,
      "##ix": 7646,
      "1866": 7647,
      "kyle": 7648,
      "alberta": 7649,
      "underneath": 7650,
      "romanized": 7651,
      "##ward": 7652,
      "relieved": 7653,
      "acquisition": 7654,
      "phrase": 7655,
      "cliff": 7656,
      "reveals": 7657,
      "han": 7658,
      "cuts": 7659,
      "merger": 7660,
      "custom": 7661,
      "##dar": 7662,
      "nee": 7663,
      "gilbert": 7664,
      "graduation": 7665,
      "##nts": 7666,
      "assessment": 7667,
      "cafe": 7668,
      "difficulty": 7669,
      "demands": 7670,
      "swung": 7671,
      "democrat": 7672,
      "jennifer": 7673,
      "commons": 7674,
      "1940s": 7675,
      "grove": 7676,
      "##yo": 7677,
      "completing": 7678,
      "focuses": 7679,
      "sum": 7680,
      "substitute": 7681,
      "bearing": 7682,
      "stretch": 7683,
      "reception": 7684,
      "##py": 7685,
      "reflected": 7686,
      "essentially": 7687,
      "destination": 7688,
      "pairs": 7689,
      "##ched": 7690,
      "survival": 7691,
      "resource": 7692,
      "##bach": 7693,
      "promoting": 7694,
      "doubles": 7695,
      "messages": 7696,
      "tear": 7697,
      "##down": 7698,
      "##fully": 7699,
      "parade": 7700,
      "florence": 7701,
      "harvey": 7702,
      "incumbent": 7703,
      "partial": 7704,
      "framework": 7705,
      "900": 7706,
      "pedro": 7707,
      "frozen": 7708,
      "procedure": 7709,
      "olivia": 7710,
      "controls": 7711,
      "##mic": 7712,
      "shelter": 7713,
      "personally": 7714,
      "temperatures": 7715,
      "##od": 7716,
      "brisbane": 7717,
      "tested": 7718,
      "sits": 7719,
      "marble": 7720,
      "comprehensive": 7721,
      "oxygen": 7722,
      "leonard": 7723,
      "##kov": 7724,
      "inaugural": 7725,
      "iranian": 7726,
      "referring": 7727,
      "quarters": 7728,
      "attitude": 7729,
      "##ivity": 7730,
      "mainstream": 7731,
      "lined": 7732,
      "mars": 7733,
      "dakota": 7734,
      "norfolk": 7735,
      "unsuccessful": 7736,
      "##°": 7737,
      "explosion": 7738,
      "helicopter": 7739,
      "congressional": 7740,
      "##sing": 7741,
      "inspector": 7742,
      "bitch": 7743,
      "seal": 7744,
      "departed": 7745,
      "divine": 7746,
      "##ters": 7747,
      "coaching": 7748,
      "examination": 7749,
      "punishment": 7750,
      "manufacturer": 7751,
      "sink": 7752,
      "columns": 7753,
      "unincorporated": 7754,
      "signals": 7755,
      "nevada": 7756,
      "squeezed": 7757,
      "dylan": 7758,
      "dining": 7759,
      "photos": 7760,
      "martial": 7761,
      "manuel": 7762,
      "eighteen": 7763,
      "elevator": 7764,
      "brushed": 7765,
      "plates": 7766,
      "ministers": 7767,
      "ivy": 7768,
      "congregation": 7769,
      "##len": 7770,
      "slept": 7771,
      "specialized": 7772,
      "taxes": 7773,
      "curve": 7774,
      "restricted": 7775,
      "negotiations": 7776,
      "likes": 7777,
      "statistical": 7778,
      "arnold": 7779,
      "inspiration": 7780,
      "execution": 7781,
      "bold": 7782,
      "intermediate": 7783,
      "significance": 7784,
      "margin": 7785,
      "ruler": 7786,
      "wheels": 7787,
      "gothic": 7788,
      "intellectual": 7789,
      "dependent": 7790,
      "listened": 7791,
      "eligible": 7792,
      "buses": 7793,
      "widow": 7794,
      "syria": 7795,
      "earn": 7796,
      "cincinnati": 7797,
      "collapsed": 7798,
      "recipient": 7799,
      "secrets": 7800,
      "accessible": 7801,
      "philippine": 7802,
      "maritime": 7803,
      "goddess": 7804,
      "clerk": 7805,
      "surrender": 7806,
      "breaks": 7807,
      "playoff": 7808,
      "database": 7809,
      "##ified": 7810,
      "##lon": 7811,
      "ideal": 7812,
      "beetle": 7813,
      "aspect": 7814,
      "soap": 7815,
      "regulation": 7816,
      "strings": 7817,
      "expand": 7818,
      "anglo": 7819,
      "shorter": 7820,
      "crosses": 7821,
      "retreat": 7822,
      "tough": 7823,
      "coins": 7824,
      "wallace": 7825,
      "directions": 7826,
      "pressing": 7827,
      "##oon": 7828,
      "shipping": 7829,
      "locomotives": 7830,
      "comparison": 7831,
      "topics": 7832,
      "nephew": 7833,
      "##mes": 7834,
      "distinction": 7835,
      "honors": 7836,
      "travelled": 7837,
      "sierra": 7838,
      "ibn": 7839,
      "##over": 7840,
      "fortress": 7841,
      "sa": 7842,
      "recognised": 7843,
      "carved": 7844,
      "1869": 7845,
      "clients": 7846,
      "##dan": 7847,
      "intent": 7848,
      "##mar": 7849,
      "coaches": 7850,
      "describing": 7851,
      "bread": 7852,
      "##ington": 7853,
      "beaten": 7854,
      "northwestern": 7855,
      "##ona": 7856,
      "merit": 7857,
      "youtube": 7858,
      "collapse": 7859,
      "challenges": 7860,
      "em": 7861,
      "historians": 7862,
      "objective": 7863,
      "submitted": 7864,
      "virus": 7865,
      "attacking": 7866,
      "drake": 7867,
      "assume": 7868,
      "##ere": 7869,
      "diseases": 7870,
      "marc": 7871,
      "stem": 7872,
      "leeds": 7873,
      "##cus": 7874,
      "##ab": 7875,
      "farming": 7876,
      "glasses": 7877,
      "##lock": 7878,
      "visits": 7879,
      "nowhere": 7880,
      "fellowship": 7881,
      "relevant": 7882,
      "carries": 7883,
      "restaurants": 7884,
      "experiments": 7885,
      "101": 7886,
      "constantly": 7887,
      "bases": 7888,
      "targets": 7889,
      "shah": 7890,
      "tenth": 7891,
      "opponents": 7892,
      "verse": 7893,
      "territorial": 7894,
      "##ira": 7895,
      "writings": 7896,
      "corruption": 7897,
      "##hs": 7898,
      "instruction": 7899,
      "inherited": 7900,
      "reverse": 7901,
      "emphasis": 7902,
      "##vic": 7903,
      "employee": 7904,
      "arch": 7905,
      "keeps": 7906,
      "rabbi": 7907,
      "watson": 7908,
      "payment": 7909,
      "uh": 7910,
      "##ala": 7911,
      "nancy": 7912,
      "##tre": 7913,
      "venice": 7914,
      "fastest": 7915,
      "sexy": 7916,
      "banned": 7917,
      "adrian": 7918,
      "properly": 7919,
      "ruth": 7920,
      "touchdown": 7921,
      "dollar": 7922,
      "boards": 7923,
      "metre": 7924,
      "circles": 7925,
      "edges": 7926,
      "favour": 7927,
      "comments": 7928,
      "ok": 7929,
      "travels": 7930,
      "liberation": 7931,
      "scattered": 7932,
      "firmly": 7933,
      "##ular": 7934,
      "holland": 7935,
      "permitted": 7936,
      "diesel": 7937,
      "kenya": 7938,
      "den": 7939,
      "originated": 7940,
      "##ral": 7941,
      "demons": 7942,
      "resumed": 7943,
      "dragged": 7944,
      "rider": 7945,
      "##rus": 7946,
      "servant": 7947,
      "blinked": 7948,
      "extend": 7949,
      "torn": 7950,
      "##ias": 7951,
      "##sey": 7952,
      "input": 7953,
      "meal": 7954,
      "everybody": 7955,
      "cylinder": 7956,
      "kinds": 7957,
      "camps": 7958,
      "##fe": 7959,
      "bullet": 7960,
      "logic": 7961,
      "##wn": 7962,
      "croatian": 7963,
      "evolved": 7964,
      "healthy": 7965,
      "fool": 7966,
      "chocolate": 7967,
      "wise": 7968,
      "preserve": 7969,
      "pradesh": 7970,
      "##ess": 7971,
      "respective": 7972,
      "1850": 7973,
      "##ew": 7974,
      "chicken": 7975,
      "artificial": 7976,
      "gross": 7977,
      "corresponding": 7978,
      "convicted": 7979,
      "cage": 7980,
      "caroline": 7981,
      "dialogue": 7982,
      "##dor": 7983,
      "narrative": 7984,
      "stranger": 7985,
      "mario": 7986,
      "br": 7987,
      "christianity": 7988,
      "failing": 7989,
      "trent": 7990,
      "commanding": 7991,
      "buddhist": 7992,
      "1848": 7993,
      "maurice": 7994,
      "focusing": 7995,
      "yale": 7996,
      "bike": 7997,
      "altitude": 7998,
      "##ering": 7999,
      "mouse": 8000,
      "revised": 8001,
      "##sley": 8002,
      "veteran": 8003,
      "##ig": 8004,
      "pulls": 8005,
      "theology": 8006,
      "crashed": 8007,
      "campaigns": 8008,
      "legion": 8009,
      "##ability": 8010,
      "drag": 8011,
      "excellence": 8012,
      "customer": 8013,
      "cancelled": 8014,
      "intensity": 8015,
      "excuse": 8016,
      "##lar": 8017,
      "liga": 8018,
      "participating": 8019,
      "contributing": 8020,
      "printing": 8021,
      "##burn": 8022,
      "variable": 8023,
      "##rk": 8024,
      "curious": 8025,
      "bin": 8026,
      "legacy": 8027,
      "renaissance": 8028,
      "##my": 8029,
      "symptoms": 8030,
      "binding": 8031,
      "vocalist": 8032,
      "dancer": 8033,
      "##nie": 8034,
      "grammar": 8035,
      "gospel": 8036,
      "democrats": 8037,
      "ya": 8038,
      "enters": 8039,
      "sc": 8040,
      "diplomatic": 8041,
      "hitler": 8042,
      "##ser": 8043,
      "clouds": 8044,
      "mathematical": 8045,
      "quit": 8046,
      "defended": 8047,
      "oriented": 8048,
      "##heim": 8049,
      "fundamental": 8050,
      "hardware": 8051,
      "impressive": 8052,
      "equally": 8053,
      "convince": 8054,
      "confederate": 8055,
      "guilt": 8056,
      "chuck": 8057,
      "sliding": 8058,
      "##ware": 8059,
      "magnetic": 8060,
      "narrowed": 8061,
      "petersburg": 8062,
      "bulgaria": 8063,
      "otto": 8064,
      "phd": 8065,
      "skill": 8066,
      "##ama": 8067,
      "reader": 8068,
      "hopes": 8069,
      "pitcher": 8070,
      "reservoir": 8071,
      "hearts": 8072,
      "automatically": 8073,
      "expecting": 8074,
      "mysterious": 8075,
      "bennett": 8076,
      "extensively": 8077,
      "imagined": 8078,
      "seeds": 8079,
      "monitor": 8080,
      "fix": 8081,
      "##ative": 8082,
      "journalism": 8083,
      "struggling": 8084,
      "signature": 8085,
      "ranch": 8086,
      "encounter": 8087,
      "photographer": 8088,
      "observation": 8089,
      "protests": 8090,
      "##pin": 8091,
      "influences": 8092,
      "##hr": 8093,
      "calendar": 8094,
      "##all": 8095,
      "cruz": 8096,
      "croatia": 8097,
      "locomotive": 8098,
      "hughes": 8099,
      "naturally": 8100,
      "shakespeare": 8101,
      "basement": 8102,
      "hook": 8103,
      "uncredited": 8104,
      "faded": 8105,
      "theories": 8106,
      "approaches": 8107,
      "dare": 8108,
      "phillips": 8109,
      "filling": 8110,
      "fury": 8111,
      "obama": 8112,
      "##ain": 8113,
      "efficient": 8114,
      "arc": 8115,
      "deliver": 8116,
      "min": 8117,
      "raid": 8118,
      "breeding": 8119,
      "inducted": 8120,
      "leagues": 8121,
      "efficiency": 8122,
      "axis": 8123,
      "montana": 8124,
      "eagles": 8125,
      "##ked": 8126,
      "supplied": 8127,
      "instructions": 8128,
      "karen": 8129,
      "picking": 8130,
      "indicating": 8131,
      "trap": 8132,
      "anchor": 8133,
      "practically": 8134,
      "christians": 8135,
      "tomb": 8136,
      "vary": 8137,
      "occasional": 8138,
      "electronics": 8139,
      "lords": 8140,
      "readers": 8141,
      "newcastle": 8142,
      "faint": 8143,
      "innovation": 8144,
      "collect": 8145,
      "situations": 8146,
      "engagement": 8147,
      "160": 8148,
      "claude": 8149,
      "mixture": 8150,
      "##feld": 8151,
      "peer": 8152,
      "tissue": 8153,
      "logo": 8154,
      "lean": 8155,
      "##ration": 8156,
      "°f": 8157,
      "floors": 8158,
      "##ven": 8159,
      "architects": 8160,
      "reducing": 8161,
      "##our": 8162,
      "##ments": 8163,
      "rope": 8164,
      "1859": 8165,
      "ottawa": 8166,
      "##har": 8167,
      "samples": 8168,
      "banking": 8169,
      "declaration": 8170,
      "proteins": 8171,
      "resignation": 8172,
      "francois": 8173,
      "saudi": 8174,
      "advocate": 8175,
      "exhibited": 8176,
      "armor": 8177,
      "twins": 8178,
      "divorce": 8179,
      "##ras": 8180,
      "abraham": 8181,
      "reviewed": 8182,
      "jo": 8183,
      "temporarily": 8184,
      "matrix": 8185,
      "physically": 8186,
      "pulse": 8187,
      "curled": 8188,
      "##ena": 8189,
      "difficulties": 8190,
      "bengal": 8191,
      "usage": 8192,
      "##ban": 8193,
      "annie": 8194,
      "riders": 8195,
      "certificate": 8196,
      "##pi": 8197,
      "holes": 8198,
      "warsaw": 8199,
      "distinctive": 8200,
      "jessica": 8201,
      "##mon": 8202,
      "mutual": 8203,
      "1857": 8204,
      "customs": 8205,
      "circular": 8206,
      "eugene": 8207,
      "removal": 8208,
      "loaded": 8209,
      "mere": 8210,
      "vulnerable": 8211,
      "depicted": 8212,
      "generations": 8213,
      "dame": 8214,
      "heir": 8215,
      "enormous": 8216,
      "lightly": 8217,
      "climbing": 8218,
      "pitched": 8219,
      "lessons": 8220,
      "pilots": 8221,
      "nepal": 8222,
      "ram": 8223,
      "google": 8224,
      "preparing": 8225,
      "brad": 8226,
      "louise": 8227,
      "renowned": 8228,
      "##₂": 8229,
      "liam": 8230,
      "##ably": 8231,
      "plaza": 8232,
      "shaw": 8233,
      "sophie": 8234,
      "brilliant": 8235,
      "bills": 8236,
      "##bar": 8237,
      "##nik": 8238,
      "fucking": 8239,
      "mainland": 8240,
      "server": 8241,
      "pleasant": 8242,
      "seized": 8243,
      "veterans": 8244,
      "jerked": 8245,
      "fail": 8246,
      "beta": 8247,
      "brush": 8248,
      "radiation": 8249,
      "stored": 8250,
      "warmth": 8251,
      "southeastern": 8252,
      "nate": 8253,
      "sin": 8254,
      "raced": 8255,
      "berkeley": 8256,
      "joke": 8257,
      "athlete": 8258,
      "designation": 8259,
      "trunk": 8260,
      "##low": 8261,
      "roland": 8262,
      "qualification": 8263,
      "archives": 8264,
      "heels": 8265,
      "artwork": 8266,
      "receives": 8267,
      "judicial": 8268,
      "reserves": 8269,
      "##bed": 8270,
      "woke": 8271,
      "installation": 8272,
      "abu": 8273,
      "floating": 8274,
      "fake": 8275,
      "lesser": 8276,
      "excitement": 8277,
      "interface": 8278,
      "concentrated": 8279,
      "addressed": 8280,
      "characteristic": 8281,
      "amanda": 8282,
      "saxophone": 8283,
      "monk": 8284,
      "auto": 8285,
      "##bus": 8286,
      "releasing": 8287,
      "egg": 8288,
      "dies": 8289,
      "interaction": 8290,
      "defender": 8291,
      "ce": 8292,
      "outbreak": 8293,
      "glory": 8294,
      "loving": 8295,
      "##bert": 8296,
      "sequel": 8297,
      "consciousness": 8298,
      "http": 8299,
      "awake": 8300,
      "ski": 8301,
      "enrolled": 8302,
      "##ress": 8303,
      "handling": 8304,
      "rookie": 8305,
      "brow": 8306,
      "somebody": 8307,
      "biography": 8308,
      "warfare": 8309,
      "amounts": 8310,
      "contracts": 8311,
      "presentation": 8312,
      "fabric": 8313,
      "dissolved": 8314,
      "challenged": 8315,
      "meter": 8316,
      "psychological": 8317,
      "lt": 8318,
      "elevated": 8319,
      "rally": 8320,
      "accurate": 8321,
      "##tha": 8322,
      "hospitals": 8323,
      "undergraduate": 8324,
      "specialist": 8325,
      "venezuela": 8326,
      "exhibit": 8327,
      "shed": 8328,
      "nursing": 8329,
      "protestant": 8330,
      "fluid": 8331,
      "structural": 8332,
      "footage": 8333,
      "jared": 8334,
      "consistent": 8335,
      "prey": 8336,
      "##ska": 8337,
      "succession": 8338,
      "reflect": 8339,
      "exile": 8340,
      "lebanon": 8341,
      "wiped": 8342,
      "suspect": 8343,
      "shanghai": 8344,
      "resting": 8345,
      "integration": 8346,
      "preservation": 8347,
      "marvel": 8348,
      "variant": 8349,
      "pirates": 8350,
      "sheep": 8351,
      "rounded": 8352,
      "capita": 8353,
      "sailing": 8354,
      "colonies": 8355,
      "manuscript": 8356,
      "deemed": 8357,
      "variations": 8358,
      "clarke": 8359,
      "functional": 8360,
      "emerging": 8361,
      "boxing": 8362,
      "relaxed": 8363,
      "curse": 8364,
      "azerbaijan": 8365,
      "heavyweight": 8366,
      "nickname": 8367,
      "editorial": 8368,
      "rang": 8369,
      "grid": 8370,
      "tightened": 8371,
      "earthquake": 8372,
      "flashed": 8373,
      "miguel": 8374,
      "rushing": 8375,
      "##ches": 8376,
      "improvements": 8377,
      "boxes": 8378,
      "brooks": 8379,
      "180": 8380,
      "consumption": 8381,
      "molecular": 8382,
      "felix": 8383,
      "societies": 8384,
      "repeatedly": 8385,
      "variation": 8386,
      "aids": 8387,
      "civic": 8388,
      "graphics": 8389,
      "professionals": 8390,
      "realm": 8391,
      "autonomous": 8392,
      "receiver": 8393,
      "delayed": 8394,
      "workshop": 8395,
      "militia": 8396,
      "chairs": 8397,
      "trump": 8398,
      "canyon": 8399,
      "##point": 8400,
      "harsh": 8401,
      "extending": 8402,
      "lovely": 8403,
      "happiness": 8404,
      "##jan": 8405,
      "stake": 8406,
      "eyebrows": 8407,
      "embassy": 8408,
      "wellington": 8409,
      "hannah": 8410,
      "##ella": 8411,
      "sony": 8412,
      "corners": 8413,
      "bishops": 8414,
      "swear": 8415,
      "cloth": 8416,
      "contents": 8417,
      "xi": 8418,
      "namely": 8419,
      "commenced": 8420,
      "1854": 8421,
      "stanford": 8422,
      "nashville": 8423,
      "courage": 8424,
      "graphic": 8425,
      "commitment": 8426,
      "garrison": 8427,
      "##bin": 8428,
      "hamlet": 8429,
      "clearing": 8430,
      "rebels": 8431,
      "attraction": 8432,
      "literacy": 8433,
      "cooking": 8434,
      "ruins": 8435,
      "temples": 8436,
      "jenny": 8437,
      "humanity": 8438,
      "celebrate": 8439,
      "hasn": 8440,
      "freight": 8441,
      "sixty": 8442,
      "rebel": 8443,
      "bastard": 8444,
      "##art": 8445,
      "newton": 8446,
      "##ada": 8447,
      "deer": 8448,
      "##ges": 8449,
      "##ching": 8450,
      "smiles": 8451,
      "delaware": 8452,
      "singers": 8453,
      "##ets": 8454,
      "approaching": 8455,
      "assists": 8456,
      "flame": 8457,
      "##ph": 8458,
      "boulevard": 8459,
      "barrel": 8460,
      "planted": 8461,
      "##ome": 8462,
      "pursuit": 8463,
      "##sia": 8464,
      "consequences": 8465,
      "posts": 8466,
      "shallow": 8467,
      "invitation": 8468,
      "rode": 8469,
      "depot": 8470,
      "ernest": 8471,
      "kane": 8472,
      "rod": 8473,
      "concepts": 8474,
      "preston": 8475,
      "topic": 8476,
      "chambers": 8477,
      "striking": 8478,
      "blast": 8479,
      "arrives": 8480,
      "descendants": 8481,
      "montgomery": 8482,
      "ranges": 8483,
      "worlds": 8484,
      "##lay": 8485,
      "##ari": 8486,
      "span": 8487,
      "chaos": 8488,
      "praise": 8489,
      "##ag": 8490,
      "fewer": 8491,
      "1855": 8492,
      "sanctuary": 8493,
      "mud": 8494,
      "fbi": 8495,
      "##ions": 8496,
      "programmes": 8497,
      "maintaining": 8498,
      "unity": 8499,
      "harper": 8500,
      "bore": 8501,
      "handsome": 8502,
      "closure": 8503,
      "tournaments": 8504,
      "thunder": 8505,
      "nebraska": 8506,
      "linda": 8507,
      "facade": 8508,
      "puts": 8509,
      "satisfied": 8510,
      "argentine": 8511,
      "dale": 8512,
      "cork": 8513,
      "dome": 8514,
      "panama": 8515,
      "##yl": 8516,
      "1858": 8517,
      "tasks": 8518,
      "experts": 8519,
      "##ates": 8520,
      "feeding": 8521,
      "equation": 8522,
      "##las": 8523,
      "##ida": 8524,
      "##tu": 8525,
      "engage": 8526,
      "bryan": 8527,
      "##ax": 8528,
      "um": 8529,
      "quartet": 8530,
      "melody": 8531,
      "disbanded": 8532,
      "sheffield": 8533,
      "blocked": 8534,
      "gasped": 8535,
      "delay": 8536,
      "kisses": 8537,
      "maggie": 8538,
      "connects": 8539,
      "##non": 8540,
      "sts": 8541,
      "poured": 8542,
      "creator": 8543,
      "publishers": 8544,
      "##we": 8545,
      "guided": 8546,
      "ellis": 8547,
      "extinct": 8548,
      "hug": 8549,
      "gaining": 8550,
      "##ord": 8551,
      "complicated": 8552,
      "##bility": 8553,
      "poll": 8554,
      "clenched": 8555,
      "investigate": 8556,
      "##use": 8557,
      "thereby": 8558,
      "quantum": 8559,
      "spine": 8560,
      "cdp": 8561,
      "humor": 8562,
      "kills": 8563,
      "administered": 8564,
      "semifinals": 8565,
      "##du": 8566,
      "encountered": 8567,
      "ignore": 8568,
      "##bu": 8569,
      "commentary": 8570,
      "##maker": 8571,
      "bother": 8572,
      "roosevelt": 8573,
      "140": 8574,
      "plains": 8575,
      "halfway": 8576,
      "flowing": 8577,
      "cultures": 8578,
      "crack": 8579,
      "imprisoned": 8580,
      "neighboring": 8581,
      "airline": 8582,
      "##ses": 8583,
      "##view": 8584,
      "##mate": 8585,
      "##ec": 8586,
      "gather": 8587,
      "wolves": 8588,
      "marathon": 8589,
      "transformed": 8590,
      "##ill": 8591,
      "cruise": 8592,
      "organisations": 8593,
      "carol": 8594,
      "punch": 8595,
      "exhibitions": 8596,
      "numbered": 8597,
      "alarm": 8598,
      "ratings": 8599,
      "daddy": 8600,
      "silently": 8601,
      "##stein": 8602,
      "queens": 8603,
      "colours": 8604,
      "impression": 8605,
      "guidance": 8606,
      "liu": 8607,
      "tactical": 8608,
      "##rat": 8609,
      "marshal": 8610,
      "della": 8611,
      "arrow": 8612,
      "##ings": 8613,
      "rested": 8614,
      "feared": 8615,
      "tender": 8616,
      "owns": 8617,
      "bitter": 8618,
      "advisor": 8619,
      "escort": 8620,
      "##ides": 8621,
      "spare": 8622,
      "farms": 8623,
      "grants": 8624,
      "##ene": 8625,
      "dragons": 8626,
      "encourage": 8627,
      "colleagues": 8628,
      "cameras": 8629,
      "##und": 8630,
      "sucked": 8631,
      "pile": 8632,
      "spirits": 8633,
      "prague": 8634,
      "statements": 8635,
      "suspension": 8636,
      "landmark": 8637,
      "fence": 8638,
      "torture": 8639,
      "recreation": 8640,
      "bags": 8641,
      "permanently": 8642,
      "survivors": 8643,
      "pond": 8644,
      "spy": 8645,
      "predecessor": 8646,
      "bombing": 8647,
      "coup": 8648,
      "##og": 8649,
      "protecting": 8650,
      "transformation": 8651,
      "glow": 8652,
      "##lands": 8653,
      "##book": 8654,
      "dug": 8655,
      "priests": 8656,
      "andrea": 8657,
      "feat": 8658,
      "barn": 8659,
      "jumping": 8660,
      "##chen": 8661,
      "##ologist": 8662,
      "##con": 8663,
      "casualties": 8664,
      "stern": 8665,
      "auckland": 8666,
      "pipe": 8667,
      "serie": 8668,
      "revealing": 8669,
      "ba": 8670,
      "##bel": 8671,
      "trevor": 8672,
      "mercy": 8673,
      "spectrum": 8674,
      "yang": 8675,
      "consist": 8676,
      "governing": 8677,
      "collaborated": 8678,
      "possessed": 8679,
      "epic": 8680,
      "comprises": 8681,
      "blew": 8682,
      "shane": 8683,
      "##ack": 8684,
      "lopez": 8685,
      "honored": 8686,
      "magical": 8687,
      "sacrifice": 8688,
      "judgment": 8689,
      "perceived": 8690,
      "hammer": 8691,
      "mtv": 8692,
      "baronet": 8693,
      "tune": 8694,
      "das": 8695,
      "missionary": 8696,
      "sheets": 8697,
      "350": 8698,
      "neutral": 8699,
      "oral": 8700,
      "threatening": 8701,
      "attractive": 8702,
      "shade": 8703,
      "aims": 8704,
      "seminary": 8705,
      "##master": 8706,
      "estates": 8707,
      "1856": 8708,
      "michel": 8709,
      "wounds": 8710,
      "refugees": 8711,
      "manufacturers": 8712,
      "##nic": 8713,
      "mercury": 8714,
      "syndrome": 8715,
      "porter": 8716,
      "##iya": 8717,
      "##din": 8718,
      "hamburg": 8719,
      "identification": 8720,
      "upstairs": 8721,
      "purse": 8722,
      "widened": 8723,
      "pause": 8724,
      "cared": 8725,
      "breathed": 8726,
      "affiliate": 8727,
      "santiago": 8728,
      "prevented": 8729,
      "celtic": 8730,
      "fisher": 8731,
      "125": 8732,
      "recruited": 8733,
      "byzantine": 8734,
      "reconstruction": 8735,
      "farther": 8736,
      "##mp": 8737,
      "diet": 8738,
      "sake": 8739,
      "au": 8740,
      "spite": 8741,
      "sensation": 8742,
      "##ert": 8743,
      "blank": 8744,
      "separation": 8745,
      "105": 8746,
      "##hon": 8747,
      "vladimir": 8748,
      "armies": 8749,
      "anime": 8750,
      "##lie": 8751,
      "accommodate": 8752,
      "orbit": 8753,
      "cult": 8754,
      "sofia": 8755,
      "archive": 8756,
      "##ify": 8757,
      "##box": 8758,
      "founders": 8759,
      "sustained": 8760,
      "disorder": 8761,
      "honours": 8762,
      "northeastern": 8763,
      "mia": 8764,
      "crops": 8765,
      "violet": 8766,
      "threats": 8767,
      "blanket": 8768,
      "fires": 8769,
      "canton": 8770,
      "followers": 8771,
      "southwestern": 8772,
      "prototype": 8773,
      "voyage": 8774,
      "assignment": 8775,
      "altered": 8776,
      "moderate": 8777,
      "protocol": 8778,
      "pistol": 8779,
      "##eo": 8780,
      "questioned": 8781,
      "brass": 8782,
      "lifting": 8783,
      "1852": 8784,
      "math": 8785,
      "authored": 8786,
      "##ual": 8787,
      "doug": 8788,
      "dimensional": 8789,
      "dynamic": 8790,
      "##san": 8791,
      "1851": 8792,
      "pronounced": 8793,
      "grateful": 8794,
      "quest": 8795,
      "uncomfortable": 8796,
      "boom": 8797,
      "presidency": 8798,
      "stevens": 8799,
      "relating": 8800,
      "politicians": 8801,
      "chen": 8802,
      "barrier": 8803,
      "quinn": 8804,
      "diana": 8805,
      "mosque": 8806,
      "tribal": 8807,
      "cheese": 8808,
      "palmer": 8809,
      "portions": 8810,
      "sometime": 8811,
      "chester": 8812,
      "treasure": 8813,
      "wu": 8814,
      "bend": 8815,
      "download": 8816,
      "millions": 8817,
      "reforms": 8818,
      "registration": 8819,
      "##osa": 8820,
      "consequently": 8821,
      "monitoring": 8822,
      "ate": 8823,
      "preliminary": 8824,
      "brandon": 8825,
      "invented": 8826,
      "ps": 8827,
      "eaten": 8828,
      "exterior": 8829,
      "intervention": 8830,
      "ports": 8831,
      "documented": 8832,
      "log": 8833,
      "displays": 8834,
      "lecture": 8835,
      "sally": 8836,
      "favourite": 8837,
      "##itz": 8838,
      "vermont": 8839,
      "lo": 8840,
      "invisible": 8841,
      "isle": 8842,
      "breed": 8843,
      "##ator": 8844,
      "journalists": 8845,
      "relay": 8846,
      "speaks": 8847,
      "backward": 8848,
      "explore": 8849,
      "midfielder": 8850,
      "actively": 8851,
      "stefan": 8852,
      "procedures": 8853,
      "cannon": 8854,
      "blond": 8855,
      "kenneth": 8856,
      "centered": 8857,
      "servants": 8858,
      "chains": 8859,
      "libraries": 8860,
      "malcolm": 8861,
      "essex": 8862,
      "henri": 8863,
      "slavery": 8864,
      "##hal": 8865,
      "facts": 8866,
      "fairy": 8867,
      "coached": 8868,
      "cassie": 8869,
      "cats": 8870,
      "washed": 8871,
      "cop": 8872,
      "##fi": 8873,
      "announcement": 8874,
      "item": 8875,
      "2000s": 8876,
      "vinyl": 8877,
      "activated": 8878,
      "marco": 8879,
      "frontier": 8880,
      "growled": 8881,
      "curriculum": 8882,
      "##das": 8883,
      "loyal": 8884,
      "accomplished": 8885,
      "leslie": 8886,
      "ritual": 8887,
      "kenny": 8888,
      "##00": 8889,
      "vii": 8890,
      "napoleon": 8891,
      "hollow": 8892,
      "hybrid": 8893,
      "jungle": 8894,
      "stationed": 8895,
      "friedrich": 8896,
      "counted": 8897,
      "##ulated": 8898,
      "platinum": 8899,
      "theatrical": 8900,
      "seated": 8901,
      "col": 8902,
      "rubber": 8903,
      "glen": 8904,
      "1840": 8905,
      "diversity": 8906,
      "healing": 8907,
      "extends": 8908,
      "id": 8909,
      "provisions": 8910,
      "administrator": 8911,
      "columbus": 8912,
      "##oe": 8913,
      "tributary": 8914,
      "te": 8915,
      "assured": 8916,
      "org": 8917,
      "##uous": 8918,
      "prestigious": 8919,
      "examined": 8920,
      "lectures": 8921,
      "grammy": 8922,
      "ronald": 8923,
      "associations": 8924,
      "bailey": 8925,
      "allan": 8926,
      "essays": 8927,
      "flute": 8928,
      "believing": 8929,
      "consultant": 8930,
      "proceedings": 8931,
      "travelling": 8932,
      "1853": 8933,
      "kit": 8934,
      "kerala": 8935,
      "yugoslavia": 8936,
      "buddy": 8937,
      "methodist": 8938,
      "##ith": 8939,
      "burial": 8940,
      "centres": 8941,
      "batman": 8942,
      "##nda": 8943,
      "discontinued": 8944,
      "bo": 8945,
      "dock": 8946,
      "stockholm": 8947,
      "lungs": 8948,
      "severely": 8949,
      "##nk": 8950,
      "citing": 8951,
      "manga": 8952,
      "##ugh": 8953,
      "steal": 8954,
      "mumbai": 8955,
      "iraqi": 8956,
      "robot": 8957,
      "celebrity": 8958,
      "bride": 8959,
      "broadcasts": 8960,
      "abolished": 8961,
      "pot": 8962,
      "joel": 8963,
      "overhead": 8964,
      "franz": 8965,
      "packed": 8966,
      "reconnaissance": 8967,
      "johann": 8968,
      "acknowledged": 8969,
      "introduce": 8970,
      "handled": 8971,
      "doctorate": 8972,
      "developments": 8973,
      "drinks": 8974,
      "alley": 8975,
      "palestine": 8976,
      "##nis": 8977,
      "##aki": 8978,
      "proceeded": 8979,
      "recover": 8980,
      "bradley": 8981,
      "grain": 8982,
      "patch": 8983,
      "afford": 8984,
      "infection": 8985,
      "nationalist": 8986,
      "legendary": 8987,
      "##ath": 8988,
      "interchange": 8989,
      "virtually": 8990,
      "gen": 8991,
      "gravity": 8992,
      "exploration": 8993,
      "amber": 8994,
      "vital": 8995,
      "wishes": 8996,
      "powell": 8997,
      "doctrine": 8998,
      "elbow": 8999,
      "screenplay": 9000,
      "##bird": 9001,
      "contribute": 9002,
      "indonesian": 9003,
      "pet": 9004,
      "creates": 9005,
      "##com": 9006,
      "enzyme": 9007,
      "kylie": 9008,
      "discipline": 9009,
      "drops": 9010,
      "manila": 9011,
      "hunger": 9012,
      "##ien": 9013,
      "layers": 9014,
      "suffer": 9015,
      "fever": 9016,
      "bits": 9017,
      "monica": 9018,
      "keyboard": 9019,
      "manages": 9020,
      "##hood": 9021,
      "searched": 9022,
      "appeals": 9023,
      "##bad": 9024,
      "testament": 9025,
      "grande": 9026,
      "reid": 9027,
      "##war": 9028,
      "beliefs": 9029,
      "congo": 9030,
      "##ification": 9031,
      "##dia": 9032,
      "si": 9033,
      "requiring": 9034,
      "##via": 9035,
      "casey": 9036,
      "1849": 9037,
      "regret": 9038,
      "streak": 9039,
      "rape": 9040,
      "depends": 9041,
      "syrian": 9042,
      "sprint": 9043,
      "pound": 9044,
      "tourists": 9045,
      "upcoming": 9046,
      "pub": 9047,
      "##xi": 9048,
      "tense": 9049,
      "##els": 9050,
      "practiced": 9051,
      "echo": 9052,
      "nationwide": 9053,
      "guild": 9054,
      "motorcycle": 9055,
      "liz": 9056,
      "##zar": 9057,
      "chiefs": 9058,
      "desired": 9059,
      "elena": 9060,
      "bye": 9061,
      "precious": 9062,
      "absorbed": 9063,
      "relatives": 9064,
      "booth": 9065,
      "pianist": 9066,
      "##mal": 9067,
      "citizenship": 9068,
      "exhausted": 9069,
      "wilhelm": 9070,
      "##ceae": 9071,
      "##hed": 9072,
      "noting": 9073,
      "quarterback": 9074,
      "urge": 9075,
      "hectares": 9076,
      "##gue": 9077,
      "ace": 9078,
      "holly": 9079,
      "##tal": 9080,
      "blonde": 9081,
      "davies": 9082,
      "parked": 9083,
      "sustainable": 9084,
      "stepping": 9085,
      "twentieth": 9086,
      "airfield": 9087,
      "galaxy": 9088,
      "nest": 9089,
      "chip": 9090,
      "##nell": 9091,
      "tan": 9092,
      "shaft": 9093,
      "paulo": 9094,
      "requirement": 9095,
      "##zy": 9096,
      "paradise": 9097,
      "tobacco": 9098,
      "trans": 9099,
      "renewed": 9100,
      "vietnamese": 9101,
      "##cker": 9102,
      "##ju": 9103,
      "suggesting": 9104,
      "catching": 9105,
      "holmes": 9106,
      "enjoying": 9107,
      "md": 9108,
      "trips": 9109,
      "colt": 9110,
      "holder": 9111,
      "butterfly": 9112,
      "nerve": 9113,
      "reformed": 9114,
      "cherry": 9115,
      "bowling": 9116,
      "trailer": 9117,
      "carriage": 9118,
      "goodbye": 9119,
      "appreciate": 9120,
      "toy": 9121,
      "joshua": 9122,
      "interactive": 9123,
      "enabled": 9124,
      "involve": 9125,
      "##kan": 9126,
      "collar": 9127,
      "determination": 9128,
      "bunch": 9129,
      "facebook": 9130,
      "recall": 9131,
      "shorts": 9132,
      "superintendent": 9133,
      "episcopal": 9134,
      "frustration": 9135,
      "giovanni": 9136,
      "nineteenth": 9137,
      "laser": 9138,
      "privately": 9139,
      "array": 9140,
      "circulation": 9141,
      "##ovic": 9142,
      "armstrong": 9143,
      "deals": 9144,
      "painful": 9145,
      "permit": 9146,
      "discrimination": 9147,
      "##wi": 9148,
      "aires": 9149,
      "retiring": 9150,
      "cottage": 9151,
      "ni": 9152,
      "##sta": 9153,
      "horizon": 9154,
      "ellen": 9155,
      "jamaica": 9156,
      "ripped": 9157,
      "fernando": 9158,
      "chapters": 9159,
      "playstation": 9160,
      "patron": 9161,
      "lecturer": 9162,
      "navigation": 9163,
      "behaviour": 9164,
      "genes": 9165,
      "georgian": 9166,
      "export": 9167,
      "solomon": 9168,
      "rivals": 9169,
      "swift": 9170,
      "seventeen": 9171,
      "rodriguez": 9172,
      "princeton": 9173,
      "independently": 9174,
      "sox": 9175,
      "1847": 9176,
      "arguing": 9177,
      "entity": 9178,
      "casting": 9179,
      "hank": 9180,
      "criteria": 9181,
      "oakland": 9182,
      "geographic": 9183,
      "milwaukee": 9184,
      "reflection": 9185,
      "expanding": 9186,
      "conquest": 9187,
      "dubbed": 9188,
      "##tv": 9189,
      "halt": 9190,
      "brave": 9191,
      "brunswick": 9192,
      "doi": 9193,
      "arched": 9194,
      "curtis": 9195,
      "divorced": 9196,
      "predominantly": 9197,
      "somerset": 9198,
      "streams": 9199,
      "ugly": 9200,
      "zoo": 9201,
      "horrible": 9202,
      "curved": 9203,
      "buenos": 9204,
      "fierce": 9205,
      "dictionary": 9206,
      "vector": 9207,
      "theological": 9208,
      "unions": 9209,
      "handful": 9210,
      "stability": 9211,
      "chan": 9212,
      "punjab": 9213,
      "segments": 9214,
      "##lly": 9215,
      "altar": 9216,
      "ignoring": 9217,
      "gesture": 9218,
      "monsters": 9219,
      "pastor": 9220,
      "##stone": 9221,
      "thighs": 9222,
      "unexpected": 9223,
      "operators": 9224,
      "abruptly": 9225,
      "coin": 9226,
      "compiled": 9227,
      "associates": 9228,
      "improving": 9229,
      "migration": 9230,
      "pin": 9231,
      "##ose": 9232,
      "compact": 9233,
      "collegiate": 9234,
      "reserved": 9235,
      "##urs": 9236,
      "quarterfinals": 9237,
      "roster": 9238,
      "restore": 9239,
      "assembled": 9240,
      "hurry": 9241,
      "oval": 9242,
      "##cies": 9243,
      "1846": 9244,
      "flags": 9245,
      "martha": 9246,
      "##del": 9247,
      "victories": 9248,
      "sharply": 9249,
      "##rated": 9250,
      "argues": 9251,
      "deadly": 9252,
      "neo": 9253,
      "drawings": 9254,
      "symbols": 9255,
      "performer": 9256,
      "##iel": 9257,
      "griffin": 9258,
      "restrictions": 9259,
      "editing": 9260,
      "andrews": 9261,
      "java": 9262,
      "journals": 9263,
      "arabia": 9264,
      "compositions": 9265,
      "dee": 9266,
      "pierce": 9267,
      "removing": 9268,
      "hindi": 9269,
      "casino": 9270,
      "runway": 9271,
      "civilians": 9272,
      "minds": 9273,
      "nasa": 9274,
      "hotels": 9275,
      "##zation": 9276,
      "refuge": 9277,
      "rent": 9278,
      "retain": 9279,
      "potentially": 9280,
      "conferences": 9281,
      "suburban": 9282,
      "conducting": 9283,
      "##tto": 9284,
      "##tions": 9285,
      "##tle": 9286,
      "descended": 9287,
      "massacre": 9288,
      "##cal": 9289,
      "ammunition": 9290,
      "terrain": 9291,
      "fork": 9292,
      "souls": 9293,
      "counts": 9294,
      "chelsea": 9295,
      "durham": 9296,
      "drives": 9297,
      "cab": 9298,
      "##bank": 9299,
      "perth": 9300,
      "realizing": 9301,
      "palestinian": 9302,
      "finn": 9303,
      "simpson": 9304,
      "##dal": 9305,
      "betty": 9306,
      "##ule": 9307,
      "moreover": 9308,
      "particles": 9309,
      "cardinals": 9310,
      "tent": 9311,
      "evaluation": 9312,
      "extraordinary": 9313,
      "##oid": 9314,
      "inscription": 9315,
      "##works": 9316,
      "wednesday": 9317,
      "chloe": 9318,
      "maintains": 9319,
      "panels": 9320,
      "ashley": 9321,
      "trucks": 9322,
      "##nation": 9323,
      "cluster": 9324,
      "sunlight": 9325,
      "strikes": 9326,
      "zhang": 9327,
      "##wing": 9328,
      "dialect": 9329,
      "canon": 9330,
      "##ap": 9331,
      "tucked": 9332,
      "##ws": 9333,
      "collecting": 9334,
      "##mas": 9335,
      "##can": 9336,
      "##sville": 9337,
      "maker": 9338,
      "quoted": 9339,
      "evan": 9340,
      "franco": 9341,
      "aria": 9342,
      "buying": 9343,
      "cleaning": 9344,
      "eva": 9345,
      "closet": 9346,
      "provision": 9347,
      "apollo": 9348,
      "clinic": 9349,
      "rat": 9350,
      "##ez": 9351,
      "necessarily": 9352,
      "ac": 9353,
      "##gle": 9354,
      "##ising": 9355,
      "venues": 9356,
      "flipped": 9357,
      "cent": 9358,
      "spreading": 9359,
      "trustees": 9360,
      "checking": 9361,
      "authorized": 9362,
      "##sco": 9363,
      "disappointed": 9364,
      "##ado": 9365,
      "notion": 9366,
      "duration": 9367,
      "trumpet": 9368,
      "hesitated": 9369,
      "topped": 9370,
      "brussels": 9371,
      "rolls": 9372,
      "theoretical": 9373,
      "hint": 9374,
      "define": 9375,
      "aggressive": 9376,
      "repeat": 9377,
      "wash": 9378,
      "peaceful": 9379,
      "optical": 9380,
      "width": 9381,
      "allegedly": 9382,
      "mcdonald": 9383,
      "strict": 9384,
      "copyright": 9385,
      "##illa": 9386,
      "investors": 9387,
      "mar": 9388,
      "jam": 9389,
      "witnesses": 9390,
      "sounding": 9391,
      "miranda": 9392,
      "michelle": 9393,
      "privacy": 9394,
      "hugo": 9395,
      "harmony": 9396,
      "##pp": 9397,
      "valid": 9398,
      "lynn": 9399,
      "glared": 9400,
      "nina": 9401,
      "102": 9402,
      "headquartered": 9403,
      "diving": 9404,
      "boarding": 9405,
      "gibson": 9406,
      "##ncy": 9407,
      "albanian": 9408,
      "marsh": 9409,
      "routine": 9410,
      "dealt": 9411,
      "enhanced": 9412,
      "er": 9413,
      "intelligent": 9414,
      "substance": 9415,
      "targeted": 9416,
      "enlisted": 9417,
      "discovers": 9418,
      "spinning": 9419,
      "observations": 9420,
      "pissed": 9421,
      "smoking": 9422,
      "rebecca": 9423,
      "capitol": 9424,
      "visa": 9425,
      "varied": 9426,
      "costume": 9427,
      "seemingly": 9428,
      "indies": 9429,
      "compensation": 9430,
      "surgeon": 9431,
      "thursday": 9432,
      "arsenal": 9433,
      "westminster": 9434,
      "suburbs": 9435,
      "rid": 9436,
      "anglican": 9437,
      "##ridge": 9438,
      "knots": 9439,
      "foods": 9440,
      "alumni": 9441,
      "lighter": 9442,
      "fraser": 9443,
      "whoever": 9444,
      "portal": 9445,
      "scandal": 9446,
      "##ray": 9447,
      "gavin": 9448,
      "advised": 9449,
      "instructor": 9450,
      "flooding": 9451,
      "terrorist": 9452,
      "##ale": 9453,
      "teenage": 9454,
      "interim": 9455,
      "senses": 9456,
      "duck": 9457,
      "teen": 9458,
      "thesis": 9459,
      "abby": 9460,
      "eager": 9461,
      "overcome": 9462,
      "##ile": 9463,
      "newport": 9464,
      "glenn": 9465,
      "rises": 9466,
      "shame": 9467,
      "##cc": 9468,
      "prompted": 9469,
      "priority": 9470,
      "forgot": 9471,
      "bomber": 9472,
      "nicolas": 9473,
      "protective": 9474,
      "360": 9475,
      "cartoon": 9476,
      "katherine": 9477,
      "breeze": 9478,
      "lonely": 9479,
      "trusted": 9480,
      "henderson": 9481,
      "richardson": 9482,
      "relax": 9483,
      "banner": 9484,
      "candy": 9485,
      "palms": 9486,
      "remarkable": 9487,
      "##rio": 9488,
      "legends": 9489,
      "cricketer": 9490,
      "essay": 9491,
      "ordained": 9492,
      "edmund": 9493,
      "rifles": 9494,
      "trigger": 9495,
      "##uri": 9496,
      "##away": 9497,
      "sail": 9498,
      "alert": 9499,
      "1830": 9500,
      "audiences": 9501,
      "penn": 9502,
      "sussex": 9503,
      "siblings": 9504,
      "pursued": 9505,
      "indianapolis": 9506,
      "resist": 9507,
      "rosa": 9508,
      "consequence": 9509,
      "succeed": 9510,
      "avoided": 9511,
      "1845": 9512,
      "##ulation": 9513,
      "inland": 9514,
      "##tie": 9515,
      "##nna": 9516,
      "counsel": 9517,
      "profession": 9518,
      "chronicle": 9519,
      "hurried": 9520,
      "##una": 9521,
      "eyebrow": 9522,
      "eventual": 9523,
      "bleeding": 9524,
      "innovative": 9525,
      "cure": 9526,
      "##dom": 9527,
      "committees": 9528,
      "accounting": 9529,
      "con": 9530,
      "scope": 9531,
      "hardy": 9532,
      "heather": 9533,
      "tenor": 9534,
      "gut": 9535,
      "herald": 9536,
      "codes": 9537,
      "tore": 9538,
      "scales": 9539,
      "wagon": 9540,
      "##oo": 9541,
      "luxury": 9542,
      "tin": 9543,
      "prefer": 9544,
      "fountain": 9545,
      "triangle": 9546,
      "bonds": 9547,
      "darling": 9548,
      "convoy": 9549,
      "dried": 9550,
      "traced": 9551,
      "beings": 9552,
      "troy": 9553,
      "accidentally": 9554,
      "slam": 9555,
      "findings": 9556,
      "smelled": 9557,
      "joey": 9558,
      "lawyers": 9559,
      "outcome": 9560,
      "steep": 9561,
      "bosnia": 9562,
      "configuration": 9563,
      "shifting": 9564,
      "toll": 9565,
      "brook": 9566,
      "performers": 9567,
      "lobby": 9568,
      "philosophical": 9569,
      "construct": 9570,
      "shrine": 9571,
      "aggregate": 9572,
      "boot": 9573,
      "cox": 9574,
      "phenomenon": 9575,
      "savage": 9576,
      "insane": 9577,
      "solely": 9578,
      "reynolds": 9579,
      "lifestyle": 9580,
      "##ima": 9581,
      "nationally": 9582,
      "holdings": 9583,
      "consideration": 9584,
      "enable": 9585,
      "edgar": 9586,
      "mo": 9587,
      "mama": 9588,
      "##tein": 9589,
      "fights": 9590,
      "relegation": 9591,
      "chances": 9592,
      "atomic": 9593,
      "hub": 9594,
      "conjunction": 9595,
      "awkward": 9596,
      "reactions": 9597,
      "currency": 9598,
      "finale": 9599,
      "kumar": 9600,
      "underwent": 9601,
      "steering": 9602,
      "elaborate": 9603,
      "gifts": 9604,
      "comprising": 9605,
      "melissa": 9606,
      "veins": 9607,
      "reasonable": 9608,
      "sunshine": 9609,
      "chi": 9610,
      "solve": 9611,
      "trails": 9612,
      "inhabited": 9613,
      "elimination": 9614,
      "ethics": 9615,
      "huh": 9616,
      "ana": 9617,
      "molly": 9618,
      "consent": 9619,
      "apartments": 9620,
      "layout": 9621,
      "marines": 9622,
      "##ces": 9623,
      "hunters": 9624,
      "bulk": 9625,
      "##oma": 9626,
      "hometown": 9627,
      "##wall": 9628,
      "##mont": 9629,
      "cracked": 9630,
      "reads": 9631,
      "neighbouring": 9632,
      "withdrawn": 9633,
      "admission": 9634,
      "wingspan": 9635,
      "damned": 9636,
      "anthology": 9637,
      "lancashire": 9638,
      "brands": 9639,
      "batting": 9640,
      "forgive": 9641,
      "cuban": 9642,
      "awful": 9643,
      "##lyn": 9644,
      "104": 9645,
      "dimensions": 9646,
      "imagination": 9647,
      "##ade": 9648,
      "dante": 9649,
      "##ship": 9650,
      "tracking": 9651,
      "desperately": 9652,
      "goalkeeper": 9653,
      "##yne": 9654,
      "groaned": 9655,
      "workshops": 9656,
      "confident": 9657,
      "burton": 9658,
      "gerald": 9659,
      "milton": 9660,
      "circus": 9661,
      "uncertain": 9662,
      "slope": 9663,
      "copenhagen": 9664,
      "sophia": 9665,
      "fog": 9666,
      "philosopher": 9667,
      "portraits": 9668,
      "accent": 9669,
      "cycling": 9670,
      "varying": 9671,
      "gripped": 9672,
      "larvae": 9673,
      "garrett": 9674,
      "specified": 9675,
      "scotia": 9676,
      "mature": 9677,
      "luther": 9678,
      "kurt": 9679,
      "rap": 9680,
      "##kes": 9681,
      "aerial": 9682,
      "750": 9683,
      "ferdinand": 9684,
      "heated": 9685,
      "es": 9686,
      "transported": 9687,
      "##shan": 9688,
      "safely": 9689,
      "nonetheless": 9690,
      "##orn": 9691,
      "##gal": 9692,
      "motors": 9693,
      "demanding": 9694,
      "##sburg": 9695,
      "startled": 9696,
      "##brook": 9697,
      "ally": 9698,
      "generate": 9699,
      "caps": 9700,
      "ghana": 9701,
      "stained": 9702,
      "demo": 9703,
      "mentions": 9704,
      "beds": 9705,
      "ap": 9706,
      "afterward": 9707,
      "diary": 9708,
      "##bling": 9709,
      "utility": 9710,
      "##iro": 9711,
      "richards": 9712,
      "1837": 9713,
      "conspiracy": 9714,
      "conscious": 9715,
      "shining": 9716,
      "footsteps": 9717,
      "observer": 9718,
      "cyprus": 9719,
      "urged": 9720,
      "loyalty": 9721,
      "developer": 9722,
      "probability": 9723,
      "olive": 9724,
      "upgraded": 9725,
      "gym": 9726,
      "miracle": 9727,
      "insects": 9728,
      "graves": 9729,
      "1844": 9730,
      "ourselves": 9731,
      "hydrogen": 9732,
      "amazon": 9733,
      "katie": 9734,
      "tickets": 9735,
      "poets": 9736,
      "##pm": 9737,
      "planes": 9738,
      "##pan": 9739,
      "prevention": 9740,
      "witnessed": 9741,
      "dense": 9742,
      "jin": 9743,
      "randy": 9744,
      "tang": 9745,
      "warehouse": 9746,
      "monroe": 9747,
      "bang": 9748,
      "archived": 9749,
      "elderly": 9750,
      "investigations": 9751,
      "alec": 9752,
      "granite": 9753,
      "mineral": 9754,
      "conflicts": 9755,
      "controlling": 9756,
      "aboriginal": 9757,
      "carlo": 9758,
      "##zu": 9759,
      "mechanics": 9760,
      "stan": 9761,
      "stark": 9762,
      "rhode": 9763,
      "skirt": 9764,
      "est": 9765,
      "##berry": 9766,
      "bombs": 9767,
      "respected": 9768,
      "##horn": 9769,
      "imposed": 9770,
      "limestone": 9771,
      "deny": 9772,
      "nominee": 9773,
      "memphis": 9774,
      "grabbing": 9775,
      "disabled": 9776,
      "##als": 9777,
      "amusement": 9778,
      "aa": 9779,
      "frankfurt": 9780,
      "corn": 9781,
      "referendum": 9782,
      "varies": 9783,
      "slowed": 9784,
      "disk": 9785,
      "firms": 9786,
      "unconscious": 9787,
      "incredible": 9788,
      "clue": 9789,
      "sue": 9790,
      "##zhou": 9791,
      "twist": 9792,
      "##cio": 9793,
      "joins": 9794,
      "idaho": 9795,
      "chad": 9796,
      "developers": 9797,
      "computing": 9798,
      "destroyer": 9799,
      "103": 9800,
      "mortal": 9801,
      "tucker": 9802,
      "kingston": 9803,
      "choices": 9804,
      "yu": 9805,
      "carson": 9806,
      "1800": 9807,
      "os": 9808,
      "whitney": 9809,
      "geneva": 9810,
      "pretend": 9811,
      "dimension": 9812,
      "staged": 9813,
      "plateau": 9814,
      "maya": 9815,
      "##une": 9816,
      "freestyle": 9817,
      "##bc": 9818,
      "rovers": 9819,
      "hiv": 9820,
      "##ids": 9821,
      "tristan": 9822,
      "classroom": 9823,
      "prospect": 9824,
      "##hus": 9825,
      "honestly": 9826,
      "diploma": 9827,
      "lied": 9828,
      "thermal": 9829,
      "auxiliary": 9830,
      "feast": 9831,
      "unlikely": 9832,
      "iata": 9833,
      "##tel": 9834,
      "morocco": 9835,
      "pounding": 9836,
      "treasury": 9837,
      "lithuania": 9838,
      "considerably": 9839,
      "1841": 9840,
      "dish": 9841,
      "1812": 9842,
      "geological": 9843,
      "matching": 9844,
      "stumbled": 9845,
      "destroying": 9846,
      "marched": 9847,
      "brien": 9848,
      "advances": 9849,
      "cake": 9850,
      "nicole": 9851,
      "belle": 9852,
      "settling": 9853,
      "measuring": 9854,
      "directing": 9855,
      "##mie": 9856,
      "tuesday": 9857,
      "bassist": 9858,
      "capabilities": 9859,
      "stunned": 9860,
      "fraud": 9861,
      "torpedo": 9862,
      "##list": 9863,
      "##phone": 9864,
      "anton": 9865,
      "wisdom": 9866,
      "surveillance": 9867,
      "ruined": 9868,
      "##ulate": 9869,
      "lawsuit": 9870,
      "healthcare": 9871,
      "theorem": 9872,
      "halls": 9873,
      "trend": 9874,
      "aka": 9875,
      "horizontal": 9876,
      "dozens": 9877,
      "acquire": 9878,
      "lasting": 9879,
      "swim": 9880,
      "hawk": 9881,
      "gorgeous": 9882,
      "fees": 9883,
      "vicinity": 9884,
      "decrease": 9885,
      "adoption": 9886,
      "tactics": 9887,
      "##ography": 9888,
      "pakistani": 9889,
      "##ole": 9890,
      "draws": 9891,
      "##hall": 9892,
      "willie": 9893,
      "burke": 9894,
      "heath": 9895,
      "algorithm": 9896,
      "integral": 9897,
      "powder": 9898,
      "elliott": 9899,
      "brigadier": 9900,
      "jackie": 9901,
      "tate": 9902,
      "varieties": 9903,
      "darker": 9904,
      "##cho": 9905,
      "lately": 9906,
      "cigarette": 9907,
      "specimens": 9908,
      "adds": 9909,
      "##ree": 9910,
      "##ensis": 9911,
      "##inger": 9912,
      "exploded": 9913,
      "finalist": 9914,
      "cia": 9915,
      "murders": 9916,
      "wilderness": 9917,
      "arguments": 9918,
      "nicknamed": 9919,
      "acceptance": 9920,
      "onwards": 9921,
      "manufacture": 9922,
      "robertson": 9923,
      "jets": 9924,
      "tampa": 9925,
      "enterprises": 9926,
      "blog": 9927,
      "loudly": 9928,
      "composers": 9929,
      "nominations": 9930,
      "1838": 9931,
      "ai": 9932,
      "malta": 9933,
      "inquiry": 9934,
      "automobile": 9935,
      "hosting": 9936,
      "viii": 9937,
      "rays": 9938,
      "tilted": 9939,
      "grief": 9940,
      "museums": 9941,
      "strategies": 9942,
      "furious": 9943,
      "euro": 9944,
      "equality": 9945,
      "cohen": 9946,
      "poison": 9947,
      "surrey": 9948,
      "wireless": 9949,
      "governed": 9950,
      "ridiculous": 9951,
      "moses": 9952,
      "##esh": 9953,
      "##room": 9954,
      "vanished": 9955,
      "##ito": 9956,
      "barnes": 9957,
      "attract": 9958,
      "morrison": 9959,
      "istanbul": 9960,
      "##iness": 9961,
      "absent": 9962,
      "rotation": 9963,
      "petition": 9964,
      "janet": 9965,
      "##logical": 9966,
      "satisfaction": 9967,
      "custody": 9968,
      "deliberately": 9969,
      "observatory": 9970,
      "comedian": 9971,
      "surfaces": 9972,
      "pinyin": 9973,
      "novelist": 9974,
      "strictly": 9975,
      "canterbury": 9976,
      "oslo": 9977,
      "monks": 9978,
      "embrace": 9979,
      "ibm": 9980,
      "jealous": 9981,
      "photograph": 9982,
      "continent": 9983,
      "dorothy": 9984,
      "marina": 9985,
      "doc": 9986,
      "excess": 9987,
      "holden": 9988,
      "allegations": 9989,
      "explaining": 9990,
      "stack": 9991,
      "avoiding": 9992,
      "lance": 9993,
      "storyline": 9994,
      "majesty": 9995,
      "poorly": 9996,
      "spike": 9997,
      "dos": 9998,
      "bradford": 9999,
      "raven": 10000,
      "travis": 10001,
      "classics": 10002,
      "proven": 10003,
      "voltage": 10004,
      "pillow": 10005,
      "fists": 10006,
      "butt": 10007,
      "1842": 10008,
      "interpreted": 10009,
      "##car": 10010,
      "1839": 10011,
      "gage": 10012,
      "telegraph": 10013,
      "lens": 10014,
      "promising": 10015,
      "expelled": 10016,
      "casual": 10017,
      "collector": 10018,
      "zones": 10019,
      "##min": 10020,
      "silly": 10021,
      "nintendo": 10022,
      "##kh": 10023,
      "##bra": 10024,
      "downstairs": 10025,
      "chef": 10026,
      "suspicious": 10027,
      "afl": 10028,
      "flies": 10029,
      "vacant": 10030,
      "uganda": 10031,
      "pregnancy": 10032,
      "condemned": 10033,
      "lutheran": 10034,
      "estimates": 10035,
      "cheap": 10036,
      "decree": 10037,
      "saxon": 10038,
      "proximity": 10039,
      "stripped": 10040,
      "idiot": 10041,
      "deposits": 10042,
      "contrary": 10043,
      "presenter": 10044,
      "magnus": 10045,
      "glacier": 10046,
      "im": 10047,
      "offense": 10048,
      "edwin": 10049,
      "##ori": 10050,
      "upright": 10051,
      "##long": 10052,
      "bolt": 10053,
      "##ois": 10054,
      "toss": 10055,
      "geographical": 10056,
      "##izes": 10057,
      "environments": 10058,
      "delicate": 10059,
      "marking": 10060,
      "abstract": 10061,
      "xavier": 10062,
      "nails": 10063,
      "windsor": 10064,
      "plantation": 10065,
      "occurring": 10066,
      "equity": 10067,
      "saskatchewan": 10068,
      "fears": 10069,
      "drifted": 10070,
      "sequences": 10071,
      "vegetation": 10072,
      "revolt": 10073,
      "##stic": 10074,
      "1843": 10075,
      "sooner": 10076,
      "fusion": 10077,
      "opposing": 10078,
      "nato": 10079,
      "skating": 10080,
      "1836": 10081,
      "secretly": 10082,
      "ruin": 10083,
      "lease": 10084,
      "##oc": 10085,
      "edit": 10086,
      "##nne": 10087,
      "flora": 10088,
      "anxiety": 10089,
      "ruby": 10090,
      "##ological": 10091,
      "##mia": 10092,
      "tel": 10093,
      "bout": 10094,
      "taxi": 10095,
      "emmy": 10096,
      "frost": 10097,
      "rainbow": 10098,
      "compounds": 10099,
      "foundations": 10100,
      "rainfall": 10101,
      "assassination": 10102,
      "nightmare": 10103,
      "dominican": 10104,
      "##win": 10105,
      "achievements": 10106,
      "deserve": 10107,
      "orlando": 10108,
      "intact": 10109,
      "armenia": 10110,
      "##nte": 10111,
      "calgary": 10112,
      "valentine": 10113,
      "106": 10114,
      "marion": 10115,
      "proclaimed": 10116,
      "theodore": 10117,
      "bells": 10118,
      "courtyard": 10119,
      "thigh": 10120,
      "gonzalez": 10121,
      "console": 10122,
      "troop": 10123,
      "minimal": 10124,
      "monte": 10125,
      "everyday": 10126,
      "##ence": 10127,
      "##if": 10128,
      "supporter": 10129,
      "terrorism": 10130,
      "buck": 10131,
      "openly": 10132,
      "presbyterian": 10133,
      "activists": 10134,
      "carpet": 10135,
      "##iers": 10136,
      "rubbing": 10137,
      "uprising": 10138,
      "##yi": 10139,
      "cute": 10140,
      "conceived": 10141,
      "legally": 10142,
      "##cht": 10143,
      "millennium": 10144,
      "cello": 10145,
      "velocity": 10146,
      "ji": 10147,
      "rescued": 10148,
      "cardiff": 10149,
      "1835": 10150,
      "rex": 10151,
      "concentrate": 10152,
      "senators": 10153,
      "beard": 10154,
      "rendered": 10155,
      "glowing": 10156,
      "battalions": 10157,
      "scouts": 10158,
      "competitors": 10159,
      "sculptor": 10160,
      "catalogue": 10161,
      "arctic": 10162,
      "ion": 10163,
      "raja": 10164,
      "bicycle": 10165,
      "wow": 10166,
      "glancing": 10167,
      "lawn": 10168,
      "##woman": 10169,
      "gentleman": 10170,
      "lighthouse": 10171,
      "publish": 10172,
      "predicted": 10173,
      "calculated": 10174,
      "##val": 10175,
      "variants": 10176,
      "##gne": 10177,
      "strain": 10178,
      "##ui": 10179,
      "winston": 10180,
      "deceased": 10181,
      "##nus": 10182,
      "touchdowns": 10183,
      "brady": 10184,
      "caleb": 10185,
      "sinking": 10186,
      "echoed": 10187,
      "crush": 10188,
      "hon": 10189,
      "blessed": 10190,
      "protagonist": 10191,
      "hayes": 10192,
      "endangered": 10193,
      "magnitude": 10194,
      "editors": 10195,
      "##tine": 10196,
      "estimate": 10197,
      "responsibilities": 10198,
      "##mel": 10199,
      "backup": 10200,
      "laying": 10201,
      "consumed": 10202,
      "sealed": 10203,
      "zurich": 10204,
      "lovers": 10205,
      "frustrated": 10206,
      "##eau": 10207,
      "ahmed": 10208,
      "kicking": 10209,
      "mit": 10210,
      "treasurer": 10211,
      "1832": 10212,
      "biblical": 10213,
      "refuse": 10214,
      "terrified": 10215,
      "pump": 10216,
      "agrees": 10217,
      "genuine": 10218,
      "imprisonment": 10219,
      "refuses": 10220,
      "plymouth": 10221,
      "##hen": 10222,
      "lou": 10223,
      "##nen": 10224,
      "tara": 10225,
      "trembling": 10226,
      "antarctic": 10227,
      "ton": 10228,
      "learns": 10229,
      "##tas": 10230,
      "crap": 10231,
      "crucial": 10232,
      "faction": 10233,
      "atop": 10234,
      "##borough": 10235,
      "wrap": 10236,
      "lancaster": 10237,
      "odds": 10238,
      "hopkins": 10239,
      "erik": 10240,
      "lyon": 10241,
      "##eon": 10242,
      "bros": 10243,
      "##ode": 10244,
      "snap": 10245,
      "locality": 10246,
      "tips": 10247,
      "empress": 10248,
      "crowned": 10249,
      "cal": 10250,
      "acclaimed": 10251,
      "chuckled": 10252,
      "##ory": 10253,
      "clara": 10254,
      "sends": 10255,
      "mild": 10256,
      "towel": 10257,
      "##fl": 10258,
      "##day": 10259,
      "##а": 10260,
      "wishing": 10261,
      "assuming": 10262,
      "interviewed": 10263,
      "##bal": 10264,
      "##die": 10265,
      "interactions": 10266,
      "eden": 10267,
      "cups": 10268,
      "helena": 10269,
      "##lf": 10270,
      "indie": 10271,
      "beck": 10272,
      "##fire": 10273,
      "batteries": 10274,
      "filipino": 10275,
      "wizard": 10276,
      "parted": 10277,
      "##lam": 10278,
      "traces": 10279,
      "##born": 10280,
      "rows": 10281,
      "idol": 10282,
      "albany": 10283,
      "delegates": 10284,
      "##ees": 10285,
      "##sar": 10286,
      "discussions": 10287,
      "##ex": 10288,
      "notre": 10289,
      "instructed": 10290,
      "belgrade": 10291,
      "highways": 10292,
      "suggestion": 10293,
      "lauren": 10294,
      "possess": 10295,
      "orientation": 10296,
      "alexandria": 10297,
      "abdul": 10298,
      "beats": 10299,
      "salary": 10300,
      "reunion": 10301,
      "ludwig": 10302,
      "alright": 10303,
      "wagner": 10304,
      "intimate": 10305,
      "pockets": 10306,
      "slovenia": 10307,
      "hugged": 10308,
      "brighton": 10309,
      "merchants": 10310,
      "cruel": 10311,
      "stole": 10312,
      "trek": 10313,
      "slopes": 10314,
      "repairs": 10315,
      "enrollment": 10316,
      "politically": 10317,
      "underlying": 10318,
      "promotional": 10319,
      "counting": 10320,
      "boeing": 10321,
      "##bb": 10322,
      "isabella": 10323,
      "naming": 10324,
      "##и": 10325,
      "keen": 10326,
      "bacteria": 10327,
      "listing": 10328,
      "separately": 10329,
      "belfast": 10330,
      "ussr": 10331,
      "450": 10332,
      "lithuanian": 10333,
      "anybody": 10334,
      "ribs": 10335,
      "sphere": 10336,
      "martinez": 10337,
      "cock": 10338,
      "embarrassed": 10339,
      "proposals": 10340,
      "fragments": 10341,
      "nationals": 10342,
      "##fs": 10343,
      "##wski": 10344,
      "premises": 10345,
      "fin": 10346,
      "1500": 10347,
      "alpine": 10348,
      "matched": 10349,
      "freely": 10350,
      "bounded": 10351,
      "jace": 10352,
      "sleeve": 10353,
      "##af": 10354,
      "gaming": 10355,
      "pier": 10356,
      "populated": 10357,
      "evident": 10358,
      "##like": 10359,
      "frances": 10360,
      "flooded": 10361,
      "##dle": 10362,
      "frightened": 10363,
      "pour": 10364,
      "trainer": 10365,
      "framed": 10366,
      "visitor": 10367,
      "challenging": 10368,
      "pig": 10369,
      "wickets": 10370,
      "##fold": 10371,
      "infected": 10372,
      "email": 10373,
      "##pes": 10374,
      "arose": 10375,
      "##aw": 10376,
      "reward": 10377,
      "ecuador": 10378,
      "oblast": 10379,
      "vale": 10380,
      "ch": 10381,
      "shuttle": 10382,
      "##usa": 10383,
      "bach": 10384,
      "rankings": 10385,
      "forbidden": 10386,
      "cornwall": 10387,
      "accordance": 10388,
      "salem": 10389,
      "consumers": 10390,
      "bruno": 10391,
      "fantastic": 10392,
      "toes": 10393,
      "machinery": 10394,
      "resolved": 10395,
      "julius": 10396,
      "remembering": 10397,
      "propaganda": 10398,
      "iceland": 10399,
      "bombardment": 10400,
      "tide": 10401,
      "contacts": 10402,
      "wives": 10403,
      "##rah": 10404,
      "concerto": 10405,
      "macdonald": 10406,
      "albania": 10407,
      "implement": 10408,
      "daisy": 10409,
      "tapped": 10410,
      "sudan": 10411,
      "helmet": 10412,
      "angela": 10413,
      "mistress": 10414,
      "##lic": 10415,
      "crop": 10416,
      "sunk": 10417,
      "finest": 10418,
      "##craft": 10419,
      "hostile": 10420,
      "##ute": 10421,
      "##tsu": 10422,
      "boxer": 10423,
      "fr": 10424,
      "paths": 10425,
      "adjusted": 10426,
      "habit": 10427,
      "ballot": 10428,
      "supervision": 10429,
      "soprano": 10430,
      "##zen": 10431,
      "bullets": 10432,
      "wicked": 10433,
      "sunset": 10434,
      "regiments": 10435,
      "disappear": 10436,
      "lamp": 10437,
      "performs": 10438,
      "app": 10439,
      "##gia": 10440,
      "##oa": 10441,
      "rabbit": 10442,
      "digging": 10443,
      "incidents": 10444,
      "entries": 10445,
      "##cion": 10446,
      "dishes": 10447,
      "##oi": 10448,
      "introducing": 10449,
      "##ati": 10450,
      "##fied": 10451,
      "freshman": 10452,
      "slot": 10453,
      "jill": 10454,
      "tackles": 10455,
      "baroque": 10456,
      "backs": 10457,
      "##iest": 10458,
      "lone": 10459,
      "sponsor": 10460,
      "destiny": 10461,
      "altogether": 10462,
      "convert": 10463,
      "##aro": 10464,
      "consensus": 10465,
      "shapes": 10466,
      "demonstration": 10467,
      "basically": 10468,
      "feminist": 10469,
      "auction": 10470,
      "artifacts": 10471,
      "##bing": 10472,
      "strongest": 10473,
      "twitter": 10474,
      "halifax": 10475,
      "2019": 10476,
      "allmusic": 10477,
      "mighty": 10478,
      "smallest": 10479,
      "precise": 10480,
      "alexandra": 10481,
      "viola": 10482,
      "##los": 10483,
      "##ille": 10484,
      "manuscripts": 10485,
      "##illo": 10486,
      "dancers": 10487,
      "ari": 10488,
      "managers": 10489,
      "monuments": 10490,
      "blades": 10491,
      "barracks": 10492,
      "springfield": 10493,
      "maiden": 10494,
      "consolidated": 10495,
      "electron": 10496,
      "##end": 10497,
      "berry": 10498,
      "airing": 10499,
      "wheat": 10500,
      "nobel": 10501,
      "inclusion": 10502,
      "blair": 10503,
      "payments": 10504,
      "geography": 10505,
      "bee": 10506,
      "cc": 10507,
      "eleanor": 10508,
      "react": 10509,
      "##hurst": 10510,
      "afc": 10511,
      "manitoba": 10512,
      "##yu": 10513,
      "su": 10514,
      "lineup": 10515,
      "fitness": 10516,
      "recreational": 10517,
      "investments": 10518,
      "airborne": 10519,
      "disappointment": 10520,
      "##dis": 10521,
      "edmonton": 10522,
      "viewing": 10523,
      "##row": 10524,
      "renovation": 10525,
      "##cast": 10526,
      "infant": 10527,
      "bankruptcy": 10528,
      "roses": 10529,
      "aftermath": 10530,
      "pavilion": 10531,
      "##yer": 10532,
      "carpenter": 10533,
      "withdrawal": 10534,
      "ladder": 10535,
      "##hy": 10536,
      "discussing": 10537,
      "popped": 10538,
      "reliable": 10539,
      "agreements": 10540,
      "rochester": 10541,
      "##abad": 10542,
      "curves": 10543,
      "bombers": 10544,
      "220": 10545,
      "rao": 10546,
      "reverend": 10547,
      "decreased": 10548,
      "choosing": 10549,
      "107": 10550,
      "stiff": 10551,
      "consulting": 10552,
      "naples": 10553,
      "crawford": 10554,
      "tracy": 10555,
      "ka": 10556,
      "ribbon": 10557,
      "cops": 10558,
      "##lee": 10559,
      "crushed": 10560,
      "deciding": 10561,
      "unified": 10562,
      "teenager": 10563,
      "accepting": 10564,
      "flagship": 10565,
      "explorer": 10566,
      "poles": 10567,
      "sanchez": 10568,
      "inspection": 10569,
      "revived": 10570,
      "skilled": 10571,
      "induced": 10572,
      "exchanged": 10573,
      "flee": 10574,
      "locals": 10575,
      "tragedy": 10576,
      "swallow": 10577,
      "loading": 10578,
      "hanna": 10579,
      "demonstrate": 10580,
      "##ela": 10581,
      "salvador": 10582,
      "flown": 10583,
      "contestants": 10584,
      "civilization": 10585,
      "##ines": 10586,
      "wanna": 10587,
      "rhodes": 10588,
      "fletcher": 10589,
      "hector": 10590,
      "knocking": 10591,
      "considers": 10592,
      "##ough": 10593,
      "nash": 10594,
      "mechanisms": 10595,
      "sensed": 10596,
      "mentally": 10597,
      "walt": 10598,
      "unclear": 10599,
      "##eus": 10600,
      "renovated": 10601,
      "madame": 10602,
      "##cks": 10603,
      "crews": 10604,
      "governmental": 10605,
      "##hin": 10606,
      "undertaken": 10607,
      "monkey": 10608,
      "##ben": 10609,
      "##ato": 10610,
      "fatal": 10611,
      "armored": 10612,
      "copa": 10613,
      "caves": 10614,
      "governance": 10615,
      "grasp": 10616,
      "perception": 10617,
      "certification": 10618,
      "froze": 10619,
      "damp": 10620,
      "tugged": 10621,
      "wyoming": 10622,
      "##rg": 10623,
      "##ero": 10624,
      "newman": 10625,
      "##lor": 10626,
      "nerves": 10627,
      "curiosity": 10628,
      "graph": 10629,
      "115": 10630,
      "##ami": 10631,
      "withdraw": 10632,
      "tunnels": 10633,
      "dull": 10634,
      "meredith": 10635,
      "moss": 10636,
      "exhibits": 10637,
      "neighbors": 10638,
      "communicate": 10639,
      "accuracy": 10640,
      "explored": 10641,
      "raiders": 10642,
      "republicans": 10643,
      "secular": 10644,
      "kat": 10645,
      "superman": 10646,
      "penny": 10647,
      "criticised": 10648,
      "##tch": 10649,
      "freed": 10650,
      "update": 10651,
      "conviction": 10652,
      "wade": 10653,
      "ham": 10654,
      "likewise": 10655,
      "delegation": 10656,
      "gotta": 10657,
      "doll": 10658,
      "promises": 10659,
      "technological": 10660,
      "myth": 10661,
      "nationality": 10662,
      "resolve": 10663,
      "convent": 10664,
      "##mark": 10665,
      "sharon": 10666,
      "dig": 10667,
      "sip": 10668,
      "coordinator": 10669,
      "entrepreneur": 10670,
      "fold": 10671,
      "##dine": 10672,
      "capability": 10673,
      "councillor": 10674,
      "synonym": 10675,
      "blown": 10676,
      "swan": 10677,
      "cursed": 10678,
      "1815": 10679,
      "jonas": 10680,
      "haired": 10681,
      "sofa": 10682,
      "canvas": 10683,
      "keeper": 10684,
      "rivalry": 10685,
      "##hart": 10686,
      "rapper": 10687,
      "speedway": 10688,
      "swords": 10689,
      "postal": 10690,
      "maxwell": 10691,
      "estonia": 10692,
      "potter": 10693,
      "recurring": 10694,
      "##nn": 10695,
      "##ave": 10696,
      "errors": 10697,
      "##oni": 10698,
      "cognitive": 10699,
      "1834": 10700,
      "##²": 10701,
      "claws": 10702,
      "nadu": 10703,
      "roberto": 10704,
      "bce": 10705,
      "wrestler": 10706,
      "ellie": 10707,
      "##ations": 10708,
      "infinite": 10709,
      "ink": 10710,
      "##tia": 10711,
      "presumably": 10712,
      "finite": 10713,
      "staircase": 10714,
      "108": 10715,
      "noel": 10716,
      "patricia": 10717,
      "nacional": 10718,
      "##cation": 10719,
      "chill": 10720,
      "eternal": 10721,
      "tu": 10722,
      "preventing": 10723,
      "prussia": 10724,
      "fossil": 10725,
      "limbs": 10726,
      "##logist": 10727,
      "ernst": 10728,
      "frog": 10729,
      "perez": 10730,
      "rene": 10731,
      "##ace": 10732,
      "pizza": 10733,
      "prussian": 10734,
      "##ios": 10735,
      "##vy": 10736,
      "molecules": 10737,
      "regulatory": 10738,
      "answering": 10739,
      "opinions": 10740,
      "sworn": 10741,
      "lengths": 10742,
      "supposedly": 10743,
      "hypothesis": 10744,
      "upward": 10745,
      "habitats": 10746,
      "seating": 10747,
      "ancestors": 10748,
      "drank": 10749,
      "yield": 10750,
      "hd": 10751,
      "synthesis": 10752,
      "researcher": 10753,
      "modest": 10754,
      "##var": 10755,
      "mothers": 10756,
      "peered": 10757,
      "voluntary": 10758,
      "homeland": 10759,
      "##the": 10760,
      "acclaim": 10761,
      "##igan": 10762,
      "static": 10763,
      "valve": 10764,
      "luxembourg": 10765,
      "alto": 10766,
      "carroll": 10767,
      "fe": 10768,
      "receptor": 10769,
      "norton": 10770,
      "ambulance": 10771,
      "##tian": 10772,
      "johnston": 10773,
      "catholics": 10774,
      "depicting": 10775,
      "jointly": 10776,
      "elephant": 10777,
      "gloria": 10778,
      "mentor": 10779,
      "badge": 10780,
      "ahmad": 10781,
      "distinguish": 10782,
      "remarked": 10783,
      "councils": 10784,
      "precisely": 10785,
      "allison": 10786,
      "advancing": 10787,
      "detection": 10788,
      "crowded": 10789,
      "##10": 10790,
      "cooperative": 10791,
      "ankle": 10792,
      "mercedes": 10793,
      "dagger": 10794,
      "surrendered": 10795,
      "pollution": 10796,
      "commit": 10797,
      "subway": 10798,
      "jeffrey": 10799,
      "lesson": 10800,
      "sculptures": 10801,
      "provider": 10802,
      "##fication": 10803,
      "membrane": 10804,
      "timothy": 10805,
      "rectangular": 10806,
      "fiscal": 10807,
      "heating": 10808,
      "teammate": 10809,
      "basket": 10810,
      "particle": 10811,
      "anonymous": 10812,
      "deployment": 10813,
      "##ple": 10814,
      "missiles": 10815,
      "courthouse": 10816,
      "proportion": 10817,
      "shoe": 10818,
      "sec": 10819,
      "##ller": 10820,
      "complaints": 10821,
      "forbes": 10822,
      "blacks": 10823,
      "abandon": 10824,
      "remind": 10825,
      "sizes": 10826,
      "overwhelming": 10827,
      "autobiography": 10828,
      "natalie": 10829,
      "##awa": 10830,
      "risks": 10831,
      "contestant": 10832,
      "countryside": 10833,
      "babies": 10834,
      "scorer": 10835,
      "invaded": 10836,
      "enclosed": 10837,
      "proceed": 10838,
      "hurling": 10839,
      "disorders": 10840,
      "##cu": 10841,
      "reflecting": 10842,
      "continuously": 10843,
      "cruiser": 10844,
      "graduates": 10845,
      "freeway": 10846,
      "investigated": 10847,
      "ore": 10848,
      "deserved": 10849,
      "maid": 10850,
      "blocking": 10851,
      "phillip": 10852,
      "jorge": 10853,
      "shakes": 10854,
      "dove": 10855,
      "mann": 10856,
      "variables": 10857,
      "lacked": 10858,
      "burden": 10859,
      "accompanying": 10860,
      "que": 10861,
      "consistently": 10862,
      "organizing": 10863,
      "provisional": 10864,
      "complained": 10865,
      "endless": 10866,
      "##rm": 10867,
      "tubes": 10868,
      "juice": 10869,
      "georges": 10870,
      "krishna": 10871,
      "mick": 10872,
      "labels": 10873,
      "thriller": 10874,
      "##uch": 10875,
      "laps": 10876,
      "arcade": 10877,
      "sage": 10878,
      "snail": 10879,
      "##table": 10880,
      "shannon": 10881,
      "fi": 10882,
      "laurence": 10883,
      "seoul": 10884,
      "vacation": 10885,
      "presenting": 10886,
      "hire": 10887,
      "churchill": 10888,
      "surprisingly": 10889,
      "prohibited": 10890,
      "savannah": 10891,
      "technically": 10892,
      "##oli": 10893,
      "170": 10894,
      "##lessly": 10895,
      "testimony": 10896,
      "suited": 10897,
      "speeds": 10898,
      "toys": 10899,
      "romans": 10900,
      "mlb": 10901,
      "flowering": 10902,
      "measurement": 10903,
      "talented": 10904,
      "kay": 10905,
      "settings": 10906,
      "charleston": 10907,
      "expectations": 10908,
      "shattered": 10909,
      "achieving": 10910,
      "triumph": 10911,
      "ceremonies": 10912,
      "portsmouth": 10913,
      "lanes": 10914,
      "mandatory": 10915,
      "loser": 10916,
      "stretching": 10917,
      "cologne": 10918,
      "realizes": 10919,
      "seventy": 10920,
      "cornell": 10921,
      "careers": 10922,
      "webb": 10923,
      "##ulating": 10924,
      "americas": 10925,
      "budapest": 10926,
      "ava": 10927,
      "suspicion": 10928,
      "##ison": 10929,
      "yo": 10930,
      "conrad": 10931,
      "##hai": 10932,
      "sterling": 10933,
      "jessie": 10934,
      "rector": 10935,
      "##az": 10936,
      "1831": 10937,
      "transform": 10938,
      "organize": 10939,
      "loans": 10940,
      "christine": 10941,
      "volcanic": 10942,
      "warrant": 10943,
      "slender": 10944,
      "summers": 10945,
      "subfamily": 10946,
      "newer": 10947,
      "danced": 10948,
      "dynamics": 10949,
      "rhine": 10950,
      "proceeds": 10951,
      "heinrich": 10952,
      "gastropod": 10953,
      "commands": 10954,
      "sings": 10955,
      "facilitate": 10956,
      "easter": 10957,
      "ra": 10958,
      "positioned": 10959,
      "responses": 10960,
      "expense": 10961,
      "fruits": 10962,
      "yanked": 10963,
      "imported": 10964,
      "25th": 10965,
      "velvet": 10966,
      "vic": 10967,
      "primitive": 10968,
      "tribune": 10969,
      "baldwin": 10970,
      "neighbourhood": 10971,
      "donna": 10972,
      "rip": 10973,
      "hay": 10974,
      "pr": 10975,
      "##uro": 10976,
      "1814": 10977,
      "espn": 10978,
      "welcomed": 10979,
      "##aria": 10980,
      "qualifier": 10981,
      "glare": 10982,
      "highland": 10983,
      "timing": 10984,
      "##cted": 10985,
      "shells": 10986,
      "eased": 10987,
      "geometry": 10988,
      "louder": 10989,
      "exciting": 10990,
      "slovakia": 10991,
      "##sion": 10992,
      "##iz": 10993,
      "##lot": 10994,
      "savings": 10995,
      "prairie": 10996,
      "##ques": 10997,
      "marching": 10998,
      "rafael": 10999,
      "tonnes": 11000,
      "##lled": 11001,
      "curtain": 11002,
      "preceding": 11003,
      "shy": 11004,
      "heal": 11005,
      "greene": 11006,
      "worthy": 11007,
      "##pot": 11008,
      "detachment": 11009,
      "bury": 11010,
      "sherman": 11011,
      "##eck": 11012,
      "reinforced": 11013,
      "seeks": 11014,
      "bottles": 11015,
      "contracted": 11016,
      "duchess": 11017,
      "outfit": 11018,
      "walsh": 11019,
      "##sc": 11020,
      "mickey": 11021,
      "##ase": 11022,
      "geoffrey": 11023,
      "archer": 11024,
      "squeeze": 11025,
      "dawson": 11026,
      "eliminate": 11027,
      "invention": 11028,
      "##enberg": 11029,
      "neal": 11030,
      "##eth": 11031,
      "stance": 11032,
      "dealer": 11033,
      "coral": 11034,
      "maple": 11035,
      "retire": 11036,
      "polo": 11037,
      "simplified": 11038,
      "##ht": 11039,
      "1833": 11040,
      "hid": 11041,
      "watts": 11042,
      "backwards": 11043,
      "jules": 11044,
      "##oke": 11045,
      "genesis": 11046,
      "mt": 11047,
      "frames": 11048,
      "rebounds": 11049,
      "burma": 11050,
      "woodland": 11051,
      "moist": 11052,
      "santos": 11053,
      "whispers": 11054,
      "drained": 11055,
      "subspecies": 11056,
      "##aa": 11057,
      "streaming": 11058,
      "ulster": 11059,
      "burnt": 11060,
      "correspondence": 11061,
      "maternal": 11062,
      "gerard": 11063,
      "denis": 11064,
      "stealing": 11065,
      "##load": 11066,
      "genius": 11067,
      "duchy": 11068,
      "##oria": 11069,
      "inaugurated": 11070,
      "momentum": 11071,
      "suits": 11072,
      "placement": 11073,
      "sovereign": 11074,
      "clause": 11075,
      "thames": 11076,
      "##hara": 11077,
      "confederation": 11078,
      "reservation": 11079,
      "sketch": 11080,
      "yankees": 11081,
      "lets": 11082,
      "rotten": 11083,
      "charm": 11084,
      "hal": 11085,
      "verses": 11086,
      "ultra": 11087,
      "commercially": 11088,
      "dot": 11089,
      "salon": 11090,
      "citation": 11091,
      "adopt": 11092,
      "winnipeg": 11093,
      "mist": 11094,
      "allocated": 11095,
      "cairo": 11096,
      "##boy": 11097,
      "jenkins": 11098,
      "interference": 11099,
      "objectives": 11100,
      "##wind": 11101,
      "1820": 11102,
      "portfolio": 11103,
      "armoured": 11104,
      "sectors": 11105,
      "##eh": 11106,
      "initiatives": 11107,
      "##world": 11108,
      "integrity": 11109,
      "exercises": 11110,
      "robe": 11111,
      "tap": 11112,
      "ab": 11113,
      "gazed": 11114,
      "##tones": 11115,
      "distracted": 11116,
      "rulers": 11117,
      "111": 11118,
      "favorable": 11119,
      "jerome": 11120,
      "tended": 11121,
      "cart": 11122,
      "factories": 11123,
      "##eri": 11124,
      "diplomat": 11125,
      "valued": 11126,
      "gravel": 11127,
      "charitable": 11128,
      "##try": 11129,
      "calvin": 11130,
      "exploring": 11131,
      "chang": 11132,
      "shepherd": 11133,
      "terrace": 11134,
      "pdf": 11135,
      "pupil": 11136,
      "##ural": 11137,
      "reflects": 11138,
      "ups": 11139,
      "##rch": 11140,
      "governors": 11141,
      "shelf": 11142,
      "depths": 11143,
      "##nberg": 11144,
      "trailed": 11145,
      "crest": 11146,
      "tackle": 11147,
      "##nian": 11148,
      "##ats": 11149,
      "hatred": 11150,
      "##kai": 11151,
      "clare": 11152,
      "makers": 11153,
      "ethiopia": 11154,
      "longtime": 11155,
      "detected": 11156,
      "embedded": 11157,
      "lacking": 11158,
      "slapped": 11159,
      "rely": 11160,
      "thomson": 11161,
      "anticipation": 11162,
      "iso": 11163,
      "morton": 11164,
      "successive": 11165,
      "agnes": 11166,
      "screenwriter": 11167,
      "straightened": 11168,
      "philippe": 11169,
      "playwright": 11170,
      "haunted": 11171,
      "licence": 11172,
      "iris": 11173,
      "intentions": 11174,
      "sutton": 11175,
      "112": 11176,
      "logical": 11177,
      "correctly": 11178,
      "##weight": 11179,
      "branded": 11180,
      "licked": 11181,
      "tipped": 11182,
      "silva": 11183,
      "ricky": 11184,
      "narrator": 11185,
      "requests": 11186,
      "##ents": 11187,
      "greeted": 11188,
      "supernatural": 11189,
      "cow": 11190,
      "##wald": 11191,
      "lung": 11192,
      "refusing": 11193,
      "employer": 11194,
      "strait": 11195,
      "gaelic": 11196,
      "liner": 11197,
      "##piece": 11198,
      "zoe": 11199,
      "sabha": 11200,
      "##mba": 11201,
      "driveway": 11202,
      "harvest": 11203,
      "prints": 11204,
      "bates": 11205,
      "reluctantly": 11206,
      "threshold": 11207,
      "algebra": 11208,
      "ira": 11209,
      "wherever": 11210,
      "coupled": 11211,
      "240": 11212,
      "assumption": 11213,
      "picks": 11214,
      "##air": 11215,
      "designers": 11216,
      "raids": 11217,
      "gentlemen": 11218,
      "##ean": 11219,
      "roller": 11220,
      "blowing": 11221,
      "leipzig": 11222,
      "locks": 11223,
      "screw": 11224,
      "dressing": 11225,
      "strand": 11226,
      "##lings": 11227,
      "scar": 11228,
      "dwarf": 11229,
      "depicts": 11230,
      "##nu": 11231,
      "nods": 11232,
      "##mine": 11233,
      "differ": 11234,
      "boris": 11235,
      "##eur": 11236,
      "yuan": 11237,
      "flip": 11238,
      "##gie": 11239,
      "mob": 11240,
      "invested": 11241,
      "questioning": 11242,
      "applying": 11243,
      "##ture": 11244,
      "shout": 11245,
      "##sel": 11246,
      "gameplay": 11247,
      "blamed": 11248,
      "illustrations": 11249,
      "bothered": 11250,
      "weakness": 11251,
      "rehabilitation": 11252,
      "##of": 11253,
      "##zes": 11254,
      "envelope": 11255,
      "rumors": 11256,
      "miners": 11257,
      "leicester": 11258,
      "subtle": 11259,
      "kerry": 11260,
      "##ico": 11261,
      "ferguson": 11262,
      "##fu": 11263,
      "premiership": 11264,
      "ne": 11265,
      "##cat": 11266,
      "bengali": 11267,
      "prof": 11268,
      "catches": 11269,
      "remnants": 11270,
      "dana": 11271,
      "##rily": 11272,
      "shouting": 11273,
      "presidents": 11274,
      "baltic": 11275,
      "ought": 11276,
      "ghosts": 11277,
      "dances": 11278,
      "sailors": 11279,
      "shirley": 11280,
      "fancy": 11281,
      "dominic": 11282,
      "##bie": 11283,
      "madonna": 11284,
      "##rick": 11285,
      "bark": 11286,
      "buttons": 11287,
      "gymnasium": 11288,
      "ashes": 11289,
      "liver": 11290,
      "toby": 11291,
      "oath": 11292,
      "providence": 11293,
      "doyle": 11294,
      "evangelical": 11295,
      "nixon": 11296,
      "cement": 11297,
      "carnegie": 11298,
      "embarked": 11299,
      "hatch": 11300,
      "surroundings": 11301,
      "guarantee": 11302,
      "needing": 11303,
      "pirate": 11304,
      "essence": 11305,
      "##bee": 11306,
      "filter": 11307,
      "crane": 11308,
      "hammond": 11309,
      "projected": 11310,
      "immune": 11311,
      "percy": 11312,
      "twelfth": 11313,
      "##ult": 11314,
      "regent": 11315,
      "doctoral": 11316,
      "damon": 11317,
      "mikhail": 11318,
      "##ichi": 11319,
      "lu": 11320,
      "critically": 11321,
      "elect": 11322,
      "realised": 11323,
      "abortion": 11324,
      "acute": 11325,
      "screening": 11326,
      "mythology": 11327,
      "steadily": 11328,
      "##fc": 11329,
      "frown": 11330,
      "nottingham": 11331,
      "kirk": 11332,
      "wa": 11333,
      "minneapolis": 11334,
      "##rra": 11335,
      "module": 11336,
      "algeria": 11337,
      "mc": 11338,
      "nautical": 11339,
      "encounters": 11340,
      "surprising": 11341,
      "statues": 11342,
      "availability": 11343,
      "shirts": 11344,
      "pie": 11345,
      "alma": 11346,
      "brows": 11347,
      "munster": 11348,
      "mack": 11349,
      "soup": 11350,
      "crater": 11351,
      "tornado": 11352,
      "sanskrit": 11353,
      "cedar": 11354,
      "explosive": 11355,
      "bordered": 11356,
      "dixon": 11357,
      "planets": 11358,
      "stamp": 11359,
      "exam": 11360,
      "happily": 11361,
      "##bble": 11362,
      "carriers": 11363,
      "kidnapped": 11364,
      "##vis": 11365,
      "accommodation": 11366,
      "emigrated": 11367,
      "##met": 11368,
      "knockout": 11369,
      "correspondent": 11370,
      "violation": 11371,
      "profits": 11372,
      "peaks": 11373,
      "lang": 11374,
      "specimen": 11375,
      "agenda": 11376,
      "ancestry": 11377,
      "pottery": 11378,
      "spelling": 11379,
      "equations": 11380,
      "obtaining": 11381,
      "ki": 11382,
      "linking": 11383,
      "1825": 11384,
      "debris": 11385,
      "asylum": 11386,
      "##20": 11387,
      "buddhism": 11388,
      "teddy": 11389,
      "##ants": 11390,
      "gazette": 11391,
      "##nger": 11392,
      "##sse": 11393,
      "dental": 11394,
      "eligibility": 11395,
      "utc": 11396,
      "fathers": 11397,
      "averaged": 11398,
      "zimbabwe": 11399,
      "francesco": 11400,
      "coloured": 11401,
      "hissed": 11402,
      "translator": 11403,
      "lynch": 11404,
      "mandate": 11405,
      "humanities": 11406,
      "mackenzie": 11407,
      "uniforms": 11408,
      "lin": 11409,
      "##iana": 11410,
      "##gio": 11411,
      "asset": 11412,
      "mhz": 11413,
      "fitting": 11414,
      "samantha": 11415,
      "genera": 11416,
      "wei": 11417,
      "rim": 11418,
      "beloved": 11419,
      "shark": 11420,
      "riot": 11421,
      "entities": 11422,
      "expressions": 11423,
      "indo": 11424,
      "carmen": 11425,
      "slipping": 11426,
      "owing": 11427,
      "abbot": 11428,
      "neighbor": 11429,
      "sidney": 11430,
      "##av": 11431,
      "rats": 11432,
      "recommendations": 11433,
      "encouraging": 11434,
      "squadrons": 11435,
      "anticipated": 11436,
      "commanders": 11437,
      "conquered": 11438,
      "##oto": 11439,
      "donations": 11440,
      "diagnosed": 11441,
      "##mond": 11442,
      "divide": 11443,
      "##iva": 11444,
      "guessed": 11445,
      "decoration": 11446,
      "vernon": 11447,
      "auditorium": 11448,
      "revelation": 11449,
      "conversations": 11450,
      "##kers": 11451,
      "##power": 11452,
      "herzegovina": 11453,
      "dash": 11454,
      "alike": 11455,
      "protested": 11456,
      "lateral": 11457,
      "herman": 11458,
      "accredited": 11459,
      "mg": 11460,
      "##gent": 11461,
      "freeman": 11462,
      "mel": 11463,
      "fiji": 11464,
      "crow": 11465,
      "crimson": 11466,
      "##rine": 11467,
      "livestock": 11468,
      "##pped": 11469,
      "humanitarian": 11470,
      "bored": 11471,
      "oz": 11472,
      "whip": 11473,
      "##lene": 11474,
      "##ali": 11475,
      "legitimate": 11476,
      "alter": 11477,
      "grinning": 11478,
      "spelled": 11479,
      "anxious": 11480,
      "oriental": 11481,
      "wesley": 11482,
      "##nin": 11483,
      "##hole": 11484,
      "carnival": 11485,
      "controller": 11486,
      "detect": 11487,
      "##ssa": 11488,
      "bowed": 11489,
      "educator": 11490,
      "kosovo": 11491,
      "macedonia": 11492,
      "##sin": 11493,
      "occupy": 11494,
      "mastering": 11495,
      "stephanie": 11496,
      "janeiro": 11497,
      "para": 11498,
      "unaware": 11499,
      "nurses": 11500,
      "noon": 11501,
      "135": 11502,
      "cam": 11503,
      "hopefully": 11504,
      "ranger": 11505,
      "combine": 11506,
      "sociology": 11507,
      "polar": 11508,
      "rica": 11509,
      "##eer": 11510,
      "neill": 11511,
      "##sman": 11512,
      "holocaust": 11513,
      "##ip": 11514,
      "doubled": 11515,
      "lust": 11516,
      "1828": 11517,
      "109": 11518,
      "decent": 11519,
      "cooling": 11520,
      "unveiled": 11521,
      "##card": 11522,
      "1829": 11523,
      "nsw": 11524,
      "homer": 11525,
      "chapman": 11526,
      "meyer": 11527,
      "##gin": 11528,
      "dive": 11529,
      "mae": 11530,
      "reagan": 11531,
      "expertise": 11532,
      "##gled": 11533,
      "darwin": 11534,
      "brooke": 11535,
      "sided": 11536,
      "prosecution": 11537,
      "investigating": 11538,
      "comprised": 11539,
      "petroleum": 11540,
      "genres": 11541,
      "reluctant": 11542,
      "differently": 11543,
      "trilogy": 11544,
      "johns": 11545,
      "vegetables": 11546,
      "corpse": 11547,
      "highlighted": 11548,
      "lounge": 11549,
      "pension": 11550,
      "unsuccessfully": 11551,
      "elegant": 11552,
      "aided": 11553,
      "ivory": 11554,
      "beatles": 11555,
      "amelia": 11556,
      "cain": 11557,
      "dubai": 11558,
      "sunny": 11559,
      "immigrant": 11560,
      "babe": 11561,
      "click": 11562,
      "##nder": 11563,
      "underwater": 11564,
      "pepper": 11565,
      "combining": 11566,
      "mumbled": 11567,
      "atlas": 11568,
      "horns": 11569,
      "accessed": 11570,
      "ballad": 11571,
      "physicians": 11572,
      "homeless": 11573,
      "gestured": 11574,
      "rpm": 11575,
      "freak": 11576,
      "louisville": 11577,
      "corporations": 11578,
      "patriots": 11579,
      "prizes": 11580,
      "rational": 11581,
      "warn": 11582,
      "modes": 11583,
      "decorative": 11584,
      "overnight": 11585,
      "din": 11586,
      "troubled": 11587,
      "phantom": 11588,
      "##ort": 11589,
      "monarch": 11590,
      "sheer": 11591,
      "##dorf": 11592,
      "generals": 11593,
      "guidelines": 11594,
      "organs": 11595,
      "addresses": 11596,
      "##zon": 11597,
      "enhance": 11598,
      "curling": 11599,
      "parishes": 11600,
      "cord": 11601,
      "##kie": 11602,
      "linux": 11603,
      "caesar": 11604,
      "deutsche": 11605,
      "bavaria": 11606,
      "##bia": 11607,
      "coleman": 11608,
      "cyclone": 11609,
      "##eria": 11610,
      "bacon": 11611,
      "petty": 11612,
      "##yama": 11613,
      "##old": 11614,
      "hampton": 11615,
      "diagnosis": 11616,
      "1824": 11617,
      "throws": 11618,
      "complexity": 11619,
      "rita": 11620,
      "disputed": 11621,
      "##₃": 11622,
      "pablo": 11623,
      "##sch": 11624,
      "marketed": 11625,
      "trafficking": 11626,
      "##ulus": 11627,
      "examine": 11628,
      "plague": 11629,
      "formats": 11630,
      "##oh": 11631,
      "vault": 11632,
      "faithful": 11633,
      "##bourne": 11634,
      "webster": 11635,
      "##ox": 11636,
      "highlights": 11637,
      "##ient": 11638,
      "##ann": 11639,
      "phones": 11640,
      "vacuum": 11641,
      "sandwich": 11642,
      "modeling": 11643,
      "##gated": 11644,
      "bolivia": 11645,
      "clergy": 11646,
      "qualities": 11647,
      "isabel": 11648,
      "##nas": 11649,
      "##ars": 11650,
      "wears": 11651,
      "screams": 11652,
      "reunited": 11653,
      "annoyed": 11654,
      "bra": 11655,
      "##ancy": 11656,
      "##rate": 11657,
      "differential": 11658,
      "transmitter": 11659,
      "tattoo": 11660,
      "container": 11661,
      "poker": 11662,
      "##och": 11663,
      "excessive": 11664,
      "resides": 11665,
      "cowboys": 11666,
      "##tum": 11667,
      "augustus": 11668,
      "trash": 11669,
      "providers": 11670,
      "statute": 11671,
      "retreated": 11672,
      "balcony": 11673,
      "reversed": 11674,
      "void": 11675,
      "storey": 11676,
      "preceded": 11677,
      "masses": 11678,
      "leap": 11679,
      "laughs": 11680,
      "neighborhoods": 11681,
      "wards": 11682,
      "schemes": 11683,
      "falcon": 11684,
      "santo": 11685,
      "battlefield": 11686,
      "pad": 11687,
      "ronnie": 11688,
      "thread": 11689,
      "lesbian": 11690,
      "venus": 11691,
      "##dian": 11692,
      "beg": 11693,
      "sandstone": 11694,
      "daylight": 11695,
      "punched": 11696,
      "gwen": 11697,
      "analog": 11698,
      "stroked": 11699,
      "wwe": 11700,
      "acceptable": 11701,
      "measurements": 11702,
      "dec": 11703,
      "toxic": 11704,
      "##kel": 11705,
      "adequate": 11706,
      "surgical": 11707,
      "economist": 11708,
      "parameters": 11709,
      "varsity": 11710,
      "##sberg": 11711,
      "quantity": 11712,
      "ella": 11713,
      "##chy": 11714,
      "##rton": 11715,
      "countess": 11716,
      "generating": 11717,
      "precision": 11718,
      "diamonds": 11719,
      "expressway": 11720,
      "ga": 11721,
      "##ı": 11722,
      "1821": 11723,
      "uruguay": 11724,
      "talents": 11725,
      "galleries": 11726,
      "expenses": 11727,
      "scanned": 11728,
      "colleague": 11729,
      "outlets": 11730,
      "ryder": 11731,
      "lucien": 11732,
      "##ila": 11733,
      "paramount": 11734,
      "##bon": 11735,
      "syracuse": 11736,
      "dim": 11737,
      "fangs": 11738,
      "gown": 11739,
      "sweep": 11740,
      "##sie": 11741,
      "toyota": 11742,
      "missionaries": 11743,
      "websites": 11744,
      "##nsis": 11745,
      "sentences": 11746,
      "adviser": 11747,
      "val": 11748,
      "trademark": 11749,
      "spells": 11750,
      "##plane": 11751,
      "patience": 11752,
      "starter": 11753,
      "slim": 11754,
      "##borg": 11755,
      "toe": 11756,
      "incredibly": 11757,
      "shoots": 11758,
      "elliot": 11759,
      "nobility": 11760,
      "##wyn": 11761,
      "cowboy": 11762,
      "endorsed": 11763,
      "gardner": 11764,
      "tendency": 11765,
      "persuaded": 11766,
      "organisms": 11767,
      "emissions": 11768,
      "kazakhstan": 11769,
      "amused": 11770,
      "boring": 11771,
      "chips": 11772,
      "themed": 11773,
      "##hand": 11774,
      "llc": 11775,
      "constantinople": 11776,
      "chasing": 11777,
      "systematic": 11778,
      "guatemala": 11779,
      "borrowed": 11780,
      "erin": 11781,
      "carey": 11782,
      "##hard": 11783,
      "highlands": 11784,
      "struggles": 11785,
      "1810": 11786,
      "##ifying": 11787,
      "##ced": 11788,
      "wong": 11789,
      "exceptions": 11790,
      "develops": 11791,
      "enlarged": 11792,
      "kindergarten": 11793,
      "castro": 11794,
      "##ern": 11795,
      "##rina": 11796,
      "leigh": 11797,
      "zombie": 11798,
      "juvenile": 11799,
      "##most": 11800,
      "consul": 11801,
      "##nar": 11802,
      "sailor": 11803,
      "hyde": 11804,
      "clarence": 11805,
      "intensive": 11806,
      "pinned": 11807,
      "nasty": 11808,
      "useless": 11809,
      "jung": 11810,
      "clayton": 11811,
      "stuffed": 11812,
      "exceptional": 11813,
      "ix": 11814,
      "apostolic": 11815,
      "230": 11816,
      "transactions": 11817,
      "##dge": 11818,
      "exempt": 11819,
      "swinging": 11820,
      "cove": 11821,
      "religions": 11822,
      "##ash": 11823,
      "shields": 11824,
      "dairy": 11825,
      "bypass": 11826,
      "190": 11827,
      "pursuing": 11828,
      "bug": 11829,
      "joyce": 11830,
      "bombay": 11831,
      "chassis": 11832,
      "southampton": 11833,
      "chat": 11834,
      "interact": 11835,
      "redesignated": 11836,
      "##pen": 11837,
      "nascar": 11838,
      "pray": 11839,
      "salmon": 11840,
      "rigid": 11841,
      "regained": 11842,
      "malaysian": 11843,
      "grim": 11844,
      "publicity": 11845,
      "constituted": 11846,
      "capturing": 11847,
      "toilet": 11848,
      "delegate": 11849,
      "purely": 11850,
      "tray": 11851,
      "drift": 11852,
      "loosely": 11853,
      "striker": 11854,
      "weakened": 11855,
      "trinidad": 11856,
      "mitch": 11857,
      "itv": 11858,
      "defines": 11859,
      "transmitted": 11860,
      "ming": 11861,
      "scarlet": 11862,
      "nodding": 11863,
      "fitzgerald": 11864,
      "fu": 11865,
      "narrowly": 11866,
      "sp": 11867,
      "tooth": 11868,
      "standings": 11869,
      "virtue": 11870,
      "##₁": 11871,
      "##wara": 11872,
      "##cting": 11873,
      "chateau": 11874,
      "gloves": 11875,
      "lid": 11876,
      "##nel": 11877,
      "hurting": 11878,
      "conservatory": 11879,
      "##pel": 11880,
      "sinclair": 11881,
      "reopened": 11882,
      "sympathy": 11883,
      "nigerian": 11884,
      "strode": 11885,
      "advocated": 11886,
      "optional": 11887,
      "chronic": 11888,
      "discharge": 11889,
      "##rc": 11890,
      "suck": 11891,
      "compatible": 11892,
      "laurel": 11893,
      "stella": 11894,
      "shi": 11895,
      "fails": 11896,
      "wage": 11897,
      "dodge": 11898,
      "128": 11899,
      "informal": 11900,
      "sorts": 11901,
      "levi": 11902,
      "buddha": 11903,
      "villagers": 11904,
      "##aka": 11905,
      "chronicles": 11906,
      "heavier": 11907,
      "summoned": 11908,
      "gateway": 11909,
      "3000": 11910,
      "eleventh": 11911,
      "jewelry": 11912,
      "translations": 11913,
      "accordingly": 11914,
      "seas": 11915,
      "##ency": 11916,
      "fiber": 11917,
      "pyramid": 11918,
      "cubic": 11919,
      "dragging": 11920,
      "##ista": 11921,
      "caring": 11922,
      "##ops": 11923,
      "android": 11924,
      "contacted": 11925,
      "lunar": 11926,
      "##dt": 11927,
      "kai": 11928,
      "lisbon": 11929,
      "patted": 11930,
      "1826": 11931,
      "sacramento": 11932,
      "theft": 11933,
      "madagascar": 11934,
      "subtropical": 11935,
      "disputes": 11936,
      "ta": 11937,
      "holidays": 11938,
      "piper": 11939,
      "willow": 11940,
      "mare": 11941,
      "cane": 11942,
      "itunes": 11943,
      "newfoundland": 11944,
      "benny": 11945,
      "companions": 11946,
      "dong": 11947,
      "raj": 11948,
      "observe": 11949,
      "roar": 11950,
      "charming": 11951,
      "plaque": 11952,
      "tibetan": 11953,
      "fossils": 11954,
      "enacted": 11955,
      "manning": 11956,
      "bubble": 11957,
      "tina": 11958,
      "tanzania": 11959,
      "##eda": 11960,
      "##hir": 11961,
      "funk": 11962,
      "swamp": 11963,
      "deputies": 11964,
      "cloak": 11965,
      "ufc": 11966,
      "scenario": 11967,
      "par": 11968,
      "scratch": 11969,
      "metals": 11970,
      "anthem": 11971,
      "guru": 11972,
      "engaging": 11973,
      "specially": 11974,
      "##boat": 11975,
      "dialects": 11976,
      "nineteen": 11977,
      "cecil": 11978,
      "duet": 11979,
      "disability": 11980,
      "messenger": 11981,
      "unofficial": 11982,
      "##lies": 11983,
      "defunct": 11984,
      "eds": 11985,
      "moonlight": 11986,
      "drainage": 11987,
      "surname": 11988,
      "puzzle": 11989,
      "honda": 11990,
      "switching": 11991,
      "conservatives": 11992,
      "mammals": 11993,
      "knox": 11994,
      "broadcaster": 11995,
      "sidewalk": 11996,
      "cope": 11997,
      "##ried": 11998,
      "benson": 11999,
      "princes": 12000,
      "peterson": 12001,
      "##sal": 12002,
      "bedford": 12003,
      "sharks": 12004,
      "eli": 12005,
      "wreck": 12006,
      "alberto": 12007,
      "gasp": 12008,
      "archaeology": 12009,
      "lgbt": 12010,
      "teaches": 12011,
      "securities": 12012,
      "madness": 12013,
      "compromise": 12014,
      "waving": 12015,
      "coordination": 12016,
      "davidson": 12017,
      "visions": 12018,
      "leased": 12019,
      "possibilities": 12020,
      "eighty": 12021,
      "jun": 12022,
      "fernandez": 12023,
      "enthusiasm": 12024,
      "assassin": 12025,
      "sponsorship": 12026,
      "reviewer": 12027,
      "kingdoms": 12028,
      "estonian": 12029,
      "laboratories": 12030,
      "##fy": 12031,
      "##nal": 12032,
      "applies": 12033,
      "verb": 12034,
      "celebrations": 12035,
      "##zzo": 12036,
      "rowing": 12037,
      "lightweight": 12038,
      "sadness": 12039,
      "submit": 12040,
      "mvp": 12041,
      "balanced": 12042,
      "dude": 12043,
      "##vas": 12044,
      "explicitly": 12045,
      "metric": 12046,
      "magnificent": 12047,
      "mound": 12048,
      "brett": 12049,
      "mohammad": 12050,
      "mistakes": 12051,
      "irregular": 12052,
      "##hing": 12053,
      "##ass": 12054,
      "sanders": 12055,
      "betrayed": 12056,
      "shipped": 12057,
      "surge": 12058,
      "##enburg": 12059,
      "reporters": 12060,
      "termed": 12061,
      "georg": 12062,
      "pity": 12063,
      "verbal": 12064,
      "bulls": 12065,
      "abbreviated": 12066,
      "enabling": 12067,
      "appealed": 12068,
      "##are": 12069,
      "##atic": 12070,
      "sicily": 12071,
      "sting": 12072,
      "heel": 12073,
      "sweetheart": 12074,
      "bart": 12075,
      "spacecraft": 12076,
      "brutal": 12077,
      "monarchy": 12078,
      "##tter": 12079,
      "aberdeen": 12080,
      "cameo": 12081,
      "diane": 12082,
      "##ub": 12083,
      "survivor": 12084,
      "clyde": 12085,
      "##aries": 12086,
      "complaint": 12087,
      "##makers": 12088,
      "clarinet": 12089,
      "delicious": 12090,
      "chilean": 12091,
      "karnataka": 12092,
      "coordinates": 12093,
      "1818": 12094,
      "panties": 12095,
      "##rst": 12096,
      "pretending": 12097,
      "ar": 12098,
      "dramatically": 12099,
      "kiev": 12100,
      "bella": 12101,
      "tends": 12102,
      "distances": 12103,
      "113": 12104,
      "catalog": 12105,
      "launching": 12106,
      "instances": 12107,
      "telecommunications": 12108,
      "portable": 12109,
      "lindsay": 12110,
      "vatican": 12111,
      "##eim": 12112,
      "angles": 12113,
      "aliens": 12114,
      "marker": 12115,
      "stint": 12116,
      "screens": 12117,
      "bolton": 12118,
      "##rne": 12119,
      "judy": 12120,
      "wool": 12121,
      "benedict": 12122,
      "plasma": 12123,
      "europa": 12124,
      "spark": 12125,
      "imaging": 12126,
      "filmmaker": 12127,
      "swiftly": 12128,
      "##een": 12129,
      "contributor": 12130,
      "##nor": 12131,
      "opted": 12132,
      "stamps": 12133,
      "apologize": 12134,
      "financing": 12135,
      "butter": 12136,
      "gideon": 12137,
      "sophisticated": 12138,
      "alignment": 12139,
      "avery": 12140,
      "chemicals": 12141,
      "yearly": 12142,
      "speculation": 12143,
      "prominence": 12144,
      "professionally": 12145,
      "##ils": 12146,
      "immortal": 12147,
      "institutional": 12148,
      "inception": 12149,
      "wrists": 12150,
      "identifying": 12151,
      "tribunal": 12152,
      "derives": 12153,
      "gains": 12154,
      "##wo": 12155,
      "papal": 12156,
      "preference": 12157,
      "linguistic": 12158,
      "vince": 12159,
      "operative": 12160,
      "brewery": 12161,
      "##ont": 12162,
      "unemployment": 12163,
      "boyd": 12164,
      "##ured": 12165,
      "##outs": 12166,
      "albeit": 12167,
      "prophet": 12168,
      "1813": 12169,
      "bi": 12170,
      "##rr": 12171,
      "##face": 12172,
      "##rad": 12173,
      "quarterly": 12174,
      "asteroid": 12175,
      "cleaned": 12176,
      "radius": 12177,
      "temper": 12178,
      "##llen": 12179,
      "telugu": 12180,
      "jerk": 12181,
      "viscount": 12182,
      "menu": 12183,
      "##ote": 12184,
      "glimpse": 12185,
      "##aya": 12186,
      "yacht": 12187,
      "hawaiian": 12188,
      "baden": 12189,
      "##rl": 12190,
      "laptop": 12191,
      "readily": 12192,
      "##gu": 12193,
      "monetary": 12194,
      "offshore": 12195,
      "scots": 12196,
      "watches": 12197,
      "##yang": 12198,
      "##arian": 12199,
      "upgrade": 12200,
      "needle": 12201,
      "xbox": 12202,
      "lea": 12203,
      "encyclopedia": 12204,
      "flank": 12205,
      "fingertips": 12206,
      "##pus": 12207,
      "delight": 12208,
      "teachings": 12209,
      "confirm": 12210,
      "roth": 12211,
      "beaches": 12212,
      "midway": 12213,
      "winters": 12214,
      "##iah": 12215,
      "teasing": 12216,
      "daytime": 12217,
      "beverly": 12218,
      "gambling": 12219,
      "bonnie": 12220,
      "##backs": 12221,
      "regulated": 12222,
      "clement": 12223,
      "hermann": 12224,
      "tricks": 12225,
      "knot": 12226,
      "##shing": 12227,
      "##uring": 12228,
      "##vre": 12229,
      "detached": 12230,
      "ecological": 12231,
      "owed": 12232,
      "specialty": 12233,
      "byron": 12234,
      "inventor": 12235,
      "bats": 12236,
      "stays": 12237,
      "screened": 12238,
      "unesco": 12239,
      "midland": 12240,
      "trim": 12241,
      "affection": 12242,
      "##ander": 12243,
      "##rry": 12244,
      "jess": 12245,
      "thoroughly": 12246,
      "feedback": 12247,
      "##uma": 12248,
      "chennai": 12249,
      "strained": 12250,
      "heartbeat": 12251,
      "wrapping": 12252,
      "overtime": 12253,
      "pleaded": 12254,
      "##sworth": 12255,
      "mon": 12256,
      "leisure": 12257,
      "oclc": 12258,
      "##tate": 12259,
      "##ele": 12260,
      "feathers": 12261,
      "angelo": 12262,
      "thirds": 12263,
      "nuts": 12264,
      "surveys": 12265,
      "clever": 12266,
      "gill": 12267,
      "commentator": 12268,
      "##dos": 12269,
      "darren": 12270,
      "rides": 12271,
      "gibraltar": 12272,
      "##nc": 12273,
      "##mu": 12274,
      "dissolution": 12275,
      "dedication": 12276,
      "shin": 12277,
      "meals": 12278,
      "saddle": 12279,
      "elvis": 12280,
      "reds": 12281,
      "chaired": 12282,
      "taller": 12283,
      "appreciation": 12284,
      "functioning": 12285,
      "niece": 12286,
      "favored": 12287,
      "advocacy": 12288,
      "robbie": 12289,
      "criminals": 12290,
      "suffolk": 12291,
      "yugoslav": 12292,
      "passport": 12293,
      "constable": 12294,
      "congressman": 12295,
      "hastings": 12296,
      "vera": 12297,
      "##rov": 12298,
      "consecrated": 12299,
      "sparks": 12300,
      "ecclesiastical": 12301,
      "confined": 12302,
      "##ovich": 12303,
      "muller": 12304,
      "floyd": 12305,
      "nora": 12306,
      "1822": 12307,
      "paved": 12308,
      "1827": 12309,
      "cumberland": 12310,
      "ned": 12311,
      "saga": 12312,
      "spiral": 12313,
      "##flow": 12314,
      "appreciated": 12315,
      "yi": 12316,
      "collaborative": 12317,
      "treating": 12318,
      "similarities": 12319,
      "feminine": 12320,
      "finishes": 12321,
      "##ib": 12322,
      "jade": 12323,
      "import": 12324,
      "##nse": 12325,
      "##hot": 12326,
      "champagne": 12327,
      "mice": 12328,
      "securing": 12329,
      "celebrities": 12330,
      "helsinki": 12331,
      "attributes": 12332,
      "##gos": 12333,
      "cousins": 12334,
      "phases": 12335,
      "ache": 12336,
      "lucia": 12337,
      "gandhi": 12338,
      "submission": 12339,
      "vicar": 12340,
      "spear": 12341,
      "shine": 12342,
      "tasmania": 12343,
      "biting": 12344,
      "detention": 12345,
      "constitute": 12346,
      "tighter": 12347,
      "seasonal": 12348,
      "##gus": 12349,
      "terrestrial": 12350,
      "matthews": 12351,
      "##oka": 12352,
      "effectiveness": 12353,
      "parody": 12354,
      "philharmonic": 12355,
      "##onic": 12356,
      "1816": 12357,
      "strangers": 12358,
      "encoded": 12359,
      "consortium": 12360,
      "guaranteed": 12361,
      "regards": 12362,
      "shifts": 12363,
      "tortured": 12364,
      "collision": 12365,
      "supervisor": 12366,
      "inform": 12367,
      "broader": 12368,
      "insight": 12369,
      "theaters": 12370,
      "armour": 12371,
      "emeritus": 12372,
      "blink": 12373,
      "incorporates": 12374,
      "mapping": 12375,
      "##50": 12376,
      "##ein": 12377,
      "handball": 12378,
      "flexible": 12379,
      "##nta": 12380,
      "substantially": 12381,
      "generous": 12382,
      "thief": 12383,
      "##own": 12384,
      "carr": 12385,
      "loses": 12386,
      "1793": 12387,
      "prose": 12388,
      "ucla": 12389,
      "romeo": 12390,
      "generic": 12391,
      "metallic": 12392,
      "realization": 12393,
      "damages": 12394,
      "mk": 12395,
      "commissioners": 12396,
      "zach": 12397,
      "default": 12398,
      "##ther": 12399,
      "helicopters": 12400,
      "lengthy": 12401,
      "stems": 12402,
      "spa": 12403,
      "partnered": 12404,
      "spectators": 12405,
      "rogue": 12406,
      "indication": 12407,
      "penalties": 12408,
      "teresa": 12409,
      "1801": 12410,
      "sen": 12411,
      "##tric": 12412,
      "dalton": 12413,
      "##wich": 12414,
      "irving": 12415,
      "photographic": 12416,
      "##vey": 12417,
      "dell": 12418,
      "deaf": 12419,
      "peters": 12420,
      "excluded": 12421,
      "unsure": 12422,
      "##vable": 12423,
      "patterson": 12424,
      "crawled": 12425,
      "##zio": 12426,
      "resided": 12427,
      "whipped": 12428,
      "latvia": 12429,
      "slower": 12430,
      "ecole": 12431,
      "pipes": 12432,
      "employers": 12433,
      "maharashtra": 12434,
      "comparable": 12435,
      "va": 12436,
      "textile": 12437,
      "pageant": 12438,
      "##gel": 12439,
      "alphabet": 12440,
      "binary": 12441,
      "irrigation": 12442,
      "chartered": 12443,
      "choked": 12444,
      "antoine": 12445,
      "offs": 12446,
      "waking": 12447,
      "supplement": 12448,
      "##wen": 12449,
      "quantities": 12450,
      "demolition": 12451,
      "regain": 12452,
      "locate": 12453,
      "urdu": 12454,
      "folks": 12455,
      "alt": 12456,
      "114": 12457,
      "##mc": 12458,
      "scary": 12459,
      "andreas": 12460,
      "whites": 12461,
      "##ava": 12462,
      "classrooms": 12463,
      "mw": 12464,
      "aesthetic": 12465,
      "publishes": 12466,
      "valleys": 12467,
      "guides": 12468,
      "cubs": 12469,
      "johannes": 12470,
      "bryant": 12471,
      "conventions": 12472,
      "affecting": 12473,
      "##itt": 12474,
      "drain": 12475,
      "awesome": 12476,
      "isolation": 12477,
      "prosecutor": 12478,
      "ambitious": 12479,
      "apology": 12480,
      "captive": 12481,
      "downs": 12482,
      "atmospheric": 12483,
      "lorenzo": 12484,
      "aisle": 12485,
      "beef": 12486,
      "foul": 12487,
      "##onia": 12488,
      "kidding": 12489,
      "composite": 12490,
      "disturbed": 12491,
      "illusion": 12492,
      "natives": 12493,
      "##ffer": 12494,
      "emi": 12495,
      "rockets": 12496,
      "riverside": 12497,
      "wartime": 12498,
      "painters": 12499,
      "adolf": 12500,
      "melted": 12501,
      "##ail": 12502,
      "uncertainty": 12503,
      "simulation": 12504,
      "hawks": 12505,
      "progressed": 12506,
      "meantime": 12507,
      "builder": 12508,
      "spray": 12509,
      "breach": 12510,
      "unhappy": 12511,
      "regina": 12512,
      "russians": 12513,
      "##urg": 12514,
      "determining": 12515,
      "##tation": 12516,
      "tram": 12517,
      "1806": 12518,
      "##quin": 12519,
      "aging": 12520,
      "##12": 12521,
      "1823": 12522,
      "garion": 12523,
      "rented": 12524,
      "mister": 12525,
      "diaz": 12526,
      "terminated": 12527,
      "clip": 12528,
      "1817": 12529,
      "depend": 12530,
      "nervously": 12531,
      "disco": 12532,
      "owe": 12533,
      "defenders": 12534,
      "shiva": 12535,
      "notorious": 12536,
      "disbelief": 12537,
      "shiny": 12538,
      "worcester": 12539,
      "##gation": 12540,
      "##yr": 12541,
      "trailing": 12542,
      "undertook": 12543,
      "islander": 12544,
      "belarus": 12545,
      "limitations": 12546,
      "watershed": 12547,
      "fuller": 12548,
      "overlooking": 12549,
      "utilized": 12550,
      "raphael": 12551,
      "1819": 12552,
      "synthetic": 12553,
      "breakdown": 12554,
      "klein": 12555,
      "##nate": 12556,
      "moaned": 12557,
      "memoir": 12558,
      "lamb": 12559,
      "practicing": 12560,
      "##erly": 12561,
      "cellular": 12562,
      "arrows": 12563,
      "exotic": 12564,
      "##graphy": 12565,
      "witches": 12566,
      "117": 12567,
      "charted": 12568,
      "rey": 12569,
      "hut": 12570,
      "hierarchy": 12571,
      "subdivision": 12572,
      "freshwater": 12573,
      "giuseppe": 12574,
      "aloud": 12575,
      "reyes": 12576,
      "qatar": 12577,
      "marty": 12578,
      "sideways": 12579,
      "utterly": 12580,
      "sexually": 12581,
      "jude": 12582,
      "prayers": 12583,
      "mccarthy": 12584,
      "softball": 12585,
      "blend": 12586,
      "damien": 12587,
      "##gging": 12588,
      "##metric": 12589,
      "wholly": 12590,
      "erupted": 12591,
      "lebanese": 12592,
      "negro": 12593,
      "revenues": 12594,
      "tasted": 12595,
      "comparative": 12596,
      "teamed": 12597,
      "transaction": 12598,
      "labeled": 12599,
      "maori": 12600,
      "sovereignty": 12601,
      "parkway": 12602,
      "trauma": 12603,
      "gran": 12604,
      "malay": 12605,
      "121": 12606,
      "advancement": 12607,
      "descendant": 12608,
      "2020": 12609,
      "buzz": 12610,
      "salvation": 12611,
      "inventory": 12612,
      "symbolic": 12613,
      "##making": 12614,
      "antarctica": 12615,
      "mps": 12616,
      "##gas": 12617,
      "##bro": 12618,
      "mohammed": 12619,
      "myanmar": 12620,
      "holt": 12621,
      "submarines": 12622,
      "tones": 12623,
      "##lman": 12624,
      "locker": 12625,
      "patriarch": 12626,
      "bangkok": 12627,
      "emerson": 12628,
      "remarks": 12629,
      "predators": 12630,
      "kin": 12631,
      "afghan": 12632,
      "confession": 12633,
      "norwich": 12634,
      "rental": 12635,
      "emerge": 12636,
      "advantages": 12637,
      "##zel": 12638,
      "rca": 12639,
      "##hold": 12640,
      "shortened": 12641,
      "storms": 12642,
      "aidan": 12643,
      "##matic": 12644,
      "autonomy": 12645,
      "compliance": 12646,
      "##quet": 12647,
      "dudley": 12648,
      "atp": 12649,
      "##osis": 12650,
      "1803": 12651,
      "motto": 12652,
      "documentation": 12653,
      "summary": 12654,
      "professors": 12655,
      "spectacular": 12656,
      "christina": 12657,
      "archdiocese": 12658,
      "flashing": 12659,
      "innocence": 12660,
      "remake": 12661,
      "##dell": 12662,
      "psychic": 12663,
      "reef": 12664,
      "scare": 12665,
      "employ": 12666,
      "rs": 12667,
      "sticks": 12668,
      "meg": 12669,
      "gus": 12670,
      "leans": 12671,
      "##ude": 12672,
      "accompany": 12673,
      "bergen": 12674,
      "tomas": 12675,
      "##iko": 12676,
      "doom": 12677,
      "wages": 12678,
      "pools": 12679,
      "##nch": 12680,
      "##bes": 12681,
      "breasts": 12682,
      "scholarly": 12683,
      "alison": 12684,
      "outline": 12685,
      "brittany": 12686,
      "breakthrough": 12687,
      "willis": 12688,
      "realistic": 12689,
      "##cut": 12690,
      "##boro": 12691,
      "competitor": 12692,
      "##stan": 12693,
      "pike": 12694,
      "picnic": 12695,
      "icon": 12696,
      "designing": 12697,
      "commercials": 12698,
      "washing": 12699,
      "villain": 12700,
      "skiing": 12701,
      "micro": 12702,
      "costumes": 12703,
      "auburn": 12704,
      "halted": 12705,
      "executives": 12706,
      "##hat": 12707,
      "logistics": 12708,
      "cycles": 12709,
      "vowel": 12710,
      "applicable": 12711,
      "barrett": 12712,
      "exclaimed": 12713,
      "eurovision": 12714,
      "eternity": 12715,
      "ramon": 12716,
      "##umi": 12717,
      "##lls": 12718,
      "modifications": 12719,
      "sweeping": 12720,
      "disgust": 12721,
      "##uck": 12722,
      "torch": 12723,
      "aviv": 12724,
      "ensuring": 12725,
      "rude": 12726,
      "dusty": 12727,
      "sonic": 12728,
      "donovan": 12729,
      "outskirts": 12730,
      "cu": 12731,
      "pathway": 12732,
      "##band": 12733,
      "##gun": 12734,
      "##lines": 12735,
      "disciplines": 12736,
      "acids": 12737,
      "cadet": 12738,
      "paired": 12739,
      "##40": 12740,
      "sketches": 12741,
      "##sive": 12742,
      "marriages": 12743,
      "##⁺": 12744,
      "folding": 12745,
      "peers": 12746,
      "slovak": 12747,
      "implies": 12748,
      "admired": 12749,
      "##beck": 12750,
      "1880s": 12751,
      "leopold": 12752,
      "instinct": 12753,
      "attained": 12754,
      "weston": 12755,
      "megan": 12756,
      "horace": 12757,
      "##ination": 12758,
      "dorsal": 12759,
      "ingredients": 12760,
      "evolutionary": 12761,
      "##its": 12762,
      "complications": 12763,
      "deity": 12764,
      "lethal": 12765,
      "brushing": 12766,
      "levy": 12767,
      "deserted": 12768,
      "institutes": 12769,
      "posthumously": 12770,
      "delivering": 12771,
      "telescope": 12772,
      "coronation": 12773,
      "motivated": 12774,
      "rapids": 12775,
      "luc": 12776,
      "flicked": 12777,
      "pays": 12778,
      "volcano": 12779,
      "tanner": 12780,
      "weighed": 12781,
      "##nica": 12782,
      "crowds": 12783,
      "frankie": 12784,
      "gifted": 12785,
      "addressing": 12786,
      "granddaughter": 12787,
      "winding": 12788,
      "##rna": 12789,
      "constantine": 12790,
      "gomez": 12791,
      "##front": 12792,
      "landscapes": 12793,
      "rudolf": 12794,
      "anthropology": 12795,
      "slate": 12796,
      "werewolf": 12797,
      "##lio": 12798,
      "astronomy": 12799,
      "circa": 12800,
      "rouge": 12801,
      "dreaming": 12802,
      "sack": 12803,
      "knelt": 12804,
      "drowned": 12805,
      "naomi": 12806,
      "prolific": 12807,
      "tracked": 12808,
      "freezing": 12809,
      "herb": 12810,
      "##dium": 12811,
      "agony": 12812,
      "randall": 12813,
      "twisting": 12814,
      "wendy": 12815,
      "deposit": 12816,
      "touches": 12817,
      "vein": 12818,
      "wheeler": 12819,
      "##bbled": 12820,
      "##bor": 12821,
      "batted": 12822,
      "retaining": 12823,
      "tire": 12824,
      "presently": 12825,
      "compare": 12826,
      "specification": 12827,
      "daemon": 12828,
      "nigel": 12829,
      "##grave": 12830,
      "merry": 12831,
      "recommendation": 12832,
      "czechoslovakia": 12833,
      "sandra": 12834,
      "ng": 12835,
      "roma": 12836,
      "##sts": 12837,
      "lambert": 12838,
      "inheritance": 12839,
      "sheikh": 12840,
      "winchester": 12841,
      "cries": 12842,
      "examining": 12843,
      "##yle": 12844,
      "comeback": 12845,
      "cuisine": 12846,
      "nave": 12847,
      "##iv": 12848,
      "ko": 12849,
      "retrieve": 12850,
      "tomatoes": 12851,
      "barker": 12852,
      "polished": 12853,
      "defining": 12854,
      "irene": 12855,
      "lantern": 12856,
      "personalities": 12857,
      "begging": 12858,
      "tract": 12859,
      "swore": 12860,
      "1809": 12861,
      "175": 12862,
      "##gic": 12863,
      "omaha": 12864,
      "brotherhood": 12865,
      "##rley": 12866,
      "haiti": 12867,
      "##ots": 12868,
      "exeter": 12869,
      "##ete": 12870,
      "##zia": 12871,
      "steele": 12872,
      "dumb": 12873,
      "pearson": 12874,
      "210": 12875,
      "surveyed": 12876,
      "elisabeth": 12877,
      "trends": 12878,
      "##ef": 12879,
      "fritz": 12880,
      "##rf": 12881,
      "premium": 12882,
      "bugs": 12883,
      "fraction": 12884,
      "calmly": 12885,
      "viking": 12886,
      "##birds": 12887,
      "tug": 12888,
      "inserted": 12889,
      "unusually": 12890,
      "##ield": 12891,
      "confronted": 12892,
      "distress": 12893,
      "crashing": 12894,
      "brent": 12895,
      "turks": 12896,
      "resign": 12897,
      "##olo": 12898,
      "cambodia": 12899,
      "gabe": 12900,
      "sauce": 12901,
      "##kal": 12902,
      "evelyn": 12903,
      "116": 12904,
      "extant": 12905,
      "clusters": 12906,
      "quarry": 12907,
      "teenagers": 12908,
      "luna": 12909,
      "##lers": 12910,
      "##ister": 12911,
      "affiliation": 12912,
      "drill": 12913,
      "##ashi": 12914,
      "panthers": 12915,
      "scenic": 12916,
      "libya": 12917,
      "anita": 12918,
      "strengthen": 12919,
      "inscriptions": 12920,
      "##cated": 12921,
      "lace": 12922,
      "sued": 12923,
      "judith": 12924,
      "riots": 12925,
      "##uted": 12926,
      "mint": 12927,
      "##eta": 12928,
      "preparations": 12929,
      "midst": 12930,
      "dub": 12931,
      "challenger": 12932,
      "##vich": 12933,
      "mock": 12934,
      "cf": 12935,
      "displaced": 12936,
      "wicket": 12937,
      "breaths": 12938,
      "enables": 12939,
      "schmidt": 12940,
      "analyst": 12941,
      "##lum": 12942,
      "ag": 12943,
      "highlight": 12944,
      "automotive": 12945,
      "axe": 12946,
      "josef": 12947,
      "newark": 12948,
      "sufficiently": 12949,
      "resembles": 12950,
      "50th": 12951,
      "##pal": 12952,
      "flushed": 12953,
      "mum": 12954,
      "traits": 12955,
      "##ante": 12956,
      "commodore": 12957,
      "incomplete": 12958,
      "warming": 12959,
      "titular": 12960,
      "ceremonial": 12961,
      "ethical": 12962,
      "118": 12963,
      "celebrating": 12964,
      "eighteenth": 12965,
      "cao": 12966,
      "lima": 12967,
      "medalist": 12968,
      "mobility": 12969,
      "strips": 12970,
      "snakes": 12971,
      "##city": 12972,
      "miniature": 12973,
      "zagreb": 12974,
      "barton": 12975,
      "escapes": 12976,
      "umbrella": 12977,
      "automated": 12978,
      "doubted": 12979,
      "differs": 12980,
      "cooled": 12981,
      "georgetown": 12982,
      "dresden": 12983,
      "cooked": 12984,
      "fade": 12985,
      "wyatt": 12986,
      "rna": 12987,
      "jacobs": 12988,
      "carlton": 12989,
      "abundant": 12990,
      "stereo": 12991,
      "boost": 12992,
      "madras": 12993,
      "inning": 12994,
      "##hia": 12995,
      "spur": 12996,
      "ip": 12997,
      "malayalam": 12998,
      "begged": 12999,
      "osaka": 13000,
      "groan": 13001,
      "escaping": 13002,
      "charging": 13003,
      "dose": 13004,
      "vista": 13005,
      "##aj": 13006,
      "bud": 13007,
      "papa": 13008,
      "communists": 13009,
      "advocates": 13010,
      "edged": 13011,
      "tri": 13012,
      "##cent": 13013,
      "resemble": 13014,
      "peaking": 13015,
      "necklace": 13016,
      "fried": 13017,
      "montenegro": 13018,
      "saxony": 13019,
      "goose": 13020,
      "glances": 13021,
      "stuttgart": 13022,
      "curator": 13023,
      "recruit": 13024,
      "grocery": 13025,
      "sympathetic": 13026,
      "##tting": 13027,
      "##fort": 13028,
      "127": 13029,
      "lotus": 13030,
      "randolph": 13031,
      "ancestor": 13032,
      "##rand": 13033,
      "succeeding": 13034,
      "jupiter": 13035,
      "1798": 13036,
      "macedonian": 13037,
      "##heads": 13038,
      "hiking": 13039,
      "1808": 13040,
      "handing": 13041,
      "fischer": 13042,
      "##itive": 13043,
      "garbage": 13044,
      "node": 13045,
      "##pies": 13046,
      "prone": 13047,
      "singular": 13048,
      "papua": 13049,
      "inclined": 13050,
      "attractions": 13051,
      "italia": 13052,
      "pouring": 13053,
      "motioned": 13054,
      "grandma": 13055,
      "garnered": 13056,
      "jacksonville": 13057,
      "corp": 13058,
      "ego": 13059,
      "ringing": 13060,
      "aluminum": 13061,
      "##hausen": 13062,
      "ordering": 13063,
      "##foot": 13064,
      "drawer": 13065,
      "traders": 13066,
      "synagogue": 13067,
      "##play": 13068,
      "##kawa": 13069,
      "resistant": 13070,
      "wandering": 13071,
      "fragile": 13072,
      "fiona": 13073,
      "teased": 13074,
      "var": 13075,
      "hardcore": 13076,
      "soaked": 13077,
      "jubilee": 13078,
      "decisive": 13079,
      "exposition": 13080,
      "mercer": 13081,
      "poster": 13082,
      "valencia": 13083,
      "hale": 13084,
      "kuwait": 13085,
      "1811": 13086,
      "##ises": 13087,
      "##wr": 13088,
      "##eed": 13089,
      "tavern": 13090,
      "gamma": 13091,
      "122": 13092,
      "johan": 13093,
      "##uer": 13094,
      "airways": 13095,
      "amino": 13096,
      "gil": 13097,
      "##ury": 13098,
      "vocational": 13099,
      "domains": 13100,
      "torres": 13101,
      "##sp": 13102,
      "generator": 13103,
      "folklore": 13104,
      "outcomes": 13105,
      "##keeper": 13106,
      "canberra": 13107,
      "shooter": 13108,
      "fl": 13109,
      "beams": 13110,
      "confrontation": 13111,
      "##lling": 13112,
      "##gram": 13113,
      "feb": 13114,
      "aligned": 13115,
      "forestry": 13116,
      "pipeline": 13117,
      "jax": 13118,
      "motorway": 13119,
      "conception": 13120,
      "decay": 13121,
      "##tos": 13122,
      "coffin": 13123,
      "##cott": 13124,
      "stalin": 13125,
      "1805": 13126,
      "escorted": 13127,
      "minded": 13128,
      "##nam": 13129,
      "sitcom": 13130,
      "purchasing": 13131,
      "twilight": 13132,
      "veronica": 13133,
      "additions": 13134,
      "passive": 13135,
      "tensions": 13136,
      "straw": 13137,
      "123": 13138,
      "frequencies": 13139,
      "1804": 13140,
      "refugee": 13141,
      "cultivation": 13142,
      "##iate": 13143,
      "christie": 13144,
      "clary": 13145,
      "bulletin": 13146,
      "crept": 13147,
      "disposal": 13148,
      "##rich": 13149,
      "##zong": 13150,
      "processor": 13151,
      "crescent": 13152,
      "##rol": 13153,
      "bmw": 13154,
      "emphasized": 13155,
      "whale": 13156,
      "nazis": 13157,
      "aurora": 13158,
      "##eng": 13159,
      "dwelling": 13160,
      "hauled": 13161,
      "sponsors": 13162,
      "toledo": 13163,
      "mega": 13164,
      "ideology": 13165,
      "theatres": 13166,
      "tessa": 13167,
      "cerambycidae": 13168,
      "saves": 13169,
      "turtle": 13170,
      "cone": 13171,
      "suspects": 13172,
      "kara": 13173,
      "rusty": 13174,
      "yelling": 13175,
      "greeks": 13176,
      "mozart": 13177,
      "shades": 13178,
      "cocked": 13179,
      "participant": 13180,
      "##tro": 13181,
      "shire": 13182,
      "spit": 13183,
      "freeze": 13184,
      "necessity": 13185,
      "##cos": 13186,
      "inmates": 13187,
      "nielsen": 13188,
      "councillors": 13189,
      "loaned": 13190,
      "uncommon": 13191,
      "omar": 13192,
      "peasants": 13193,
      "botanical": 13194,
      "offspring": 13195,
      "daniels": 13196,
      "formations": 13197,
      "jokes": 13198,
      "1794": 13199,
      "pioneers": 13200,
      "sigma": 13201,
      "licensing": 13202,
      "##sus": 13203,
      "wheelchair": 13204,
      "polite": 13205,
      "1807": 13206,
      "liquor": 13207,
      "pratt": 13208,
      "trustee": 13209,
      "##uta": 13210,
      "forewings": 13211,
      "balloon": 13212,
      "##zz": 13213,
      "kilometre": 13214,
      "camping": 13215,
      "explicit": 13216,
      "casually": 13217,
      "shawn": 13218,
      "foolish": 13219,
      "teammates": 13220,
      "nm": 13221,
      "hassan": 13222,
      "carrie": 13223,
      "judged": 13224,
      "satisfy": 13225,
      "vanessa": 13226,
      "knives": 13227,
      "selective": 13228,
      "cnn": 13229,
      "flowed": 13230,
      "##lice": 13231,
      "eclipse": 13232,
      "stressed": 13233,
      "eliza": 13234,
      "mathematician": 13235,
      "cease": 13236,
      "cultivated": 13237,
      "##roy": 13238,
      "commissions": 13239,
      "browns": 13240,
      "##ania": 13241,
      "destroyers": 13242,
      "sheridan": 13243,
      "meadow": 13244,
      "##rius": 13245,
      "minerals": 13246,
      "##cial": 13247,
      "downstream": 13248,
      "clash": 13249,
      "gram": 13250,
      "memoirs": 13251,
      "ventures": 13252,
      "baha": 13253,
      "seymour": 13254,
      "archie": 13255,
      "midlands": 13256,
      "edith": 13257,
      "fare": 13258,
      "flynn": 13259,
      "invite": 13260,
      "canceled": 13261,
      "tiles": 13262,
      "stabbed": 13263,
      "boulder": 13264,
      "incorporate": 13265,
      "amended": 13266,
      "camden": 13267,
      "facial": 13268,
      "mollusk": 13269,
      "unreleased": 13270,
      "descriptions": 13271,
      "yoga": 13272,
      "grabs": 13273,
      "550": 13274,
      "raises": 13275,
      "ramp": 13276,
      "shiver": 13277,
      "##rose": 13278,
      "coined": 13279,
      "pioneering": 13280,
      "tunes": 13281,
      "qing": 13282,
      "warwick": 13283,
      "tops": 13284,
      "119": 13285,
      "melanie": 13286,
      "giles": 13287,
      "##rous": 13288,
      "wandered": 13289,
      "##inal": 13290,
      "annexed": 13291,
      "nov": 13292,
      "30th": 13293,
      "unnamed": 13294,
      "##ished": 13295,
      "organizational": 13296,
      "airplane": 13297,
      "normandy": 13298,
      "stoke": 13299,
      "whistle": 13300,
      "blessing": 13301,
      "violations": 13302,
      "chased": 13303,
      "holders": 13304,
      "shotgun": 13305,
      "##ctic": 13306,
      "outlet": 13307,
      "reactor": 13308,
      "##vik": 13309,
      "tires": 13310,
      "tearing": 13311,
      "shores": 13312,
      "fortified": 13313,
      "mascot": 13314,
      "constituencies": 13315,
      "nc": 13316,
      "columnist": 13317,
      "productive": 13318,
      "tibet": 13319,
      "##rta": 13320,
      "lineage": 13321,
      "hooked": 13322,
      "oct": 13323,
      "tapes": 13324,
      "judging": 13325,
      "cody": 13326,
      "##gger": 13327,
      "hansen": 13328,
      "kashmir": 13329,
      "triggered": 13330,
      "##eva": 13331,
      "solved": 13332,
      "cliffs": 13333,
      "##tree": 13334,
      "resisted": 13335,
      "anatomy": 13336,
      "protesters": 13337,
      "transparent": 13338,
      "implied": 13339,
      "##iga": 13340,
      "injection": 13341,
      "mattress": 13342,
      "excluding": 13343,
      "##mbo": 13344,
      "defenses": 13345,
      "helpless": 13346,
      "devotion": 13347,
      "##elli": 13348,
      "growl": 13349,
      "liberals": 13350,
      "weber": 13351,
      "phenomena": 13352,
      "atoms": 13353,
      "plug": 13354,
      "##iff": 13355,
      "mortality": 13356,
      "apprentice": 13357,
      "howe": 13358,
      "convincing": 13359,
      "aaa": 13360,
      "swimmer": 13361,
      "barber": 13362,
      "leone": 13363,
      "promptly": 13364,
      "sodium": 13365,
      "def": 13366,
      "nowadays": 13367,
      "arise": 13368,
      "##oning": 13369,
      "gloucester": 13370,
      "corrected": 13371,
      "dignity": 13372,
      "norm": 13373,
      "erie": 13374,
      "##ders": 13375,
      "elders": 13376,
      "evacuated": 13377,
      "sylvia": 13378,
      "compression": 13379,
      "##yar": 13380,
      "hartford": 13381,
      "pose": 13382,
      "backpack": 13383,
      "reasoning": 13384,
      "accepts": 13385,
      "24th": 13386,
      "wipe": 13387,
      "millimetres": 13388,
      "marcel": 13389,
      "##oda": 13390,
      "dodgers": 13391,
      "albion": 13392,
      "1790": 13393,
      "overwhelmed": 13394,
      "aerospace": 13395,
      "oaks": 13396,
      "1795": 13397,
      "showcase": 13398,
      "acknowledge": 13399,
      "recovering": 13400,
      "nolan": 13401,
      "ashe": 13402,
      "hurts": 13403,
      "geology": 13404,
      "fashioned": 13405,
      "disappearance": 13406,
      "farewell": 13407,
      "swollen": 13408,
      "shrug": 13409,
      "marquis": 13410,
      "wimbledon": 13411,
      "124": 13412,
      "rue": 13413,
      "1792": 13414,
      "commemorate": 13415,
      "reduces": 13416,
      "experiencing": 13417,
      "inevitable": 13418,
      "calcutta": 13419,
      "intel": 13420,
      "##court": 13421,
      "murderer": 13422,
      "sticking": 13423,
      "fisheries": 13424,
      "imagery": 13425,
      "bloom": 13426,
      "280": 13427,
      "brake": 13428,
      "##inus": 13429,
      "gustav": 13430,
      "hesitation": 13431,
      "memorable": 13432,
      "po": 13433,
      "viral": 13434,
      "beans": 13435,
      "accidents": 13436,
      "tunisia": 13437,
      "antenna": 13438,
      "spilled": 13439,
      "consort": 13440,
      "treatments": 13441,
      "aye": 13442,
      "perimeter": 13443,
      "##gard": 13444,
      "donation": 13445,
      "hostage": 13446,
      "migrated": 13447,
      "banker": 13448,
      "addiction": 13449,
      "apex": 13450,
      "lil": 13451,
      "trout": 13452,
      "##ously": 13453,
      "conscience": 13454,
      "##nova": 13455,
      "rams": 13456,
      "sands": 13457,
      "genome": 13458,
      "passionate": 13459,
      "troubles": 13460,
      "##lets": 13461,
      "##set": 13462,
      "amid": 13463,
      "##ibility": 13464,
      "##ret": 13465,
      "higgins": 13466,
      "exceed": 13467,
      "vikings": 13468,
      "##vie": 13469,
      "payne": 13470,
      "##zan": 13471,
      "muscular": 13472,
      "##ste": 13473,
      "defendant": 13474,
      "sucking": 13475,
      "##wal": 13476,
      "ibrahim": 13477,
      "fuselage": 13478,
      "claudia": 13479,
      "vfl": 13480,
      "europeans": 13481,
      "snails": 13482,
      "interval": 13483,
      "##garh": 13484,
      "preparatory": 13485,
      "statewide": 13486,
      "tasked": 13487,
      "lacrosse": 13488,
      "viktor": 13489,
      "##lation": 13490,
      "angola": 13491,
      "##hra": 13492,
      "flint": 13493,
      "implications": 13494,
      "employs": 13495,
      "teens": 13496,
      "patrons": 13497,
      "stall": 13498,
      "weekends": 13499,
      "barriers": 13500,
      "scrambled": 13501,
      "nucleus": 13502,
      "tehran": 13503,
      "jenna": 13504,
      "parsons": 13505,
      "lifelong": 13506,
      "robots": 13507,
      "displacement": 13508,
      "5000": 13509,
      "##bles": 13510,
      "precipitation": 13511,
      "##gt": 13512,
      "knuckles": 13513,
      "clutched": 13514,
      "1802": 13515,
      "marrying": 13516,
      "ecology": 13517,
      "marx": 13518,
      "accusations": 13519,
      "declare": 13520,
      "scars": 13521,
      "kolkata": 13522,
      "mat": 13523,
      "meadows": 13524,
      "bermuda": 13525,
      "skeleton": 13526,
      "finalists": 13527,
      "vintage": 13528,
      "crawl": 13529,
      "coordinate": 13530,
      "affects": 13531,
      "subjected": 13532,
      "orchestral": 13533,
      "mistaken": 13534,
      "##tc": 13535,
      "mirrors": 13536,
      "dipped": 13537,
      "relied": 13538,
      "260": 13539,
      "arches": 13540,
      "candle": 13541,
      "##nick": 13542,
      "incorporating": 13543,
      "wildly": 13544,
      "fond": 13545,
      "basilica": 13546,
      "owl": 13547,
      "fringe": 13548,
      "rituals": 13549,
      "whispering": 13550,
      "stirred": 13551,
      "feud": 13552,
      "tertiary": 13553,
      "slick": 13554,
      "goat": 13555,
      "honorable": 13556,
      "whereby": 13557,
      "skip": 13558,
      "ricardo": 13559,
      "stripes": 13560,
      "parachute": 13561,
      "adjoining": 13562,
      "submerged": 13563,
      "synthesizer": 13564,
      "##gren": 13565,
      "intend": 13566,
      "positively": 13567,
      "ninety": 13568,
      "phi": 13569,
      "beaver": 13570,
      "partition": 13571,
      "fellows": 13572,
      "alexis": 13573,
      "prohibition": 13574,
      "carlisle": 13575,
      "bizarre": 13576,
      "fraternity": 13577,
      "##bre": 13578,
      "doubts": 13579,
      "icy": 13580,
      "cbc": 13581,
      "aquatic": 13582,
      "sneak": 13583,
      "sonny": 13584,
      "combines": 13585,
      "airports": 13586,
      "crude": 13587,
      "supervised": 13588,
      "spatial": 13589,
      "merge": 13590,
      "alfonso": 13591,
      "##bic": 13592,
      "corrupt": 13593,
      "scan": 13594,
      "undergo": 13595,
      "##ams": 13596,
      "disabilities": 13597,
      "colombian": 13598,
      "comparing": 13599,
      "dolphins": 13600,
      "perkins": 13601,
      "##lish": 13602,
      "reprinted": 13603,
      "unanimous": 13604,
      "bounced": 13605,
      "hairs": 13606,
      "underworld": 13607,
      "midwest": 13608,
      "semester": 13609,
      "bucket": 13610,
      "paperback": 13611,
      "miniseries": 13612,
      "coventry": 13613,
      "demise": 13614,
      "##leigh": 13615,
      "demonstrations": 13616,
      "sensor": 13617,
      "rotating": 13618,
      "yan": 13619,
      "##hler": 13620,
      "arrange": 13621,
      "soils": 13622,
      "##idge": 13623,
      "hyderabad": 13624,
      "labs": 13625,
      "##dr": 13626,
      "brakes": 13627,
      "grandchildren": 13628,
      "##nde": 13629,
      "negotiated": 13630,
      "rover": 13631,
      "ferrari": 13632,
      "continuation": 13633,
      "directorate": 13634,
      "augusta": 13635,
      "stevenson": 13636,
      "counterpart": 13637,
      "gore": 13638,
      "##rda": 13639,
      "nursery": 13640,
      "rican": 13641,
      "ave": 13642,
      "collectively": 13643,
      "broadly": 13644,
      "pastoral": 13645,
      "repertoire": 13646,
      "asserted": 13647,
      "discovering": 13648,
      "nordic": 13649,
      "styled": 13650,
      "fiba": 13651,
      "cunningham": 13652,
      "harley": 13653,
      "middlesex": 13654,
      "survives": 13655,
      "tumor": 13656,
      "tempo": 13657,
      "zack": 13658,
      "aiming": 13659,
      "lok": 13660,
      "urgent": 13661,
      "##rade": 13662,
      "##nto": 13663,
      "devils": 13664,
      "##ement": 13665,
      "contractor": 13666,
      "turin": 13667,
      "##wl": 13668,
      "##ool": 13669,
      "bliss": 13670,
      "repaired": 13671,
      "simmons": 13672,
      "moan": 13673,
      "astronomical": 13674,
      "cr": 13675,
      "negotiate": 13676,
      "lyric": 13677,
      "1890s": 13678,
      "lara": 13679,
      "bred": 13680,
      "clad": 13681,
      "angus": 13682,
      "pbs": 13683,
      "##ience": 13684,
      "engineered": 13685,
      "posed": 13686,
      "##lk": 13687,
      "hernandez": 13688,
      "possessions": 13689,
      "elbows": 13690,
      "psychiatric": 13691,
      "strokes": 13692,
      "confluence": 13693,
      "electorate": 13694,
      "lifts": 13695,
      "campuses": 13696,
      "lava": 13697,
      "alps": 13698,
      "##ep": 13699,
      "##ution": 13700,
      "##date": 13701,
      "physicist": 13702,
      "woody": 13703,
      "##page": 13704,
      "##ographic": 13705,
      "##itis": 13706,
      "juliet": 13707,
      "reformation": 13708,
      "sparhawk": 13709,
      "320": 13710,
      "complement": 13711,
      "suppressed": 13712,
      "jewel": 13713,
      "##½": 13714,
      "floated": 13715,
      "##kas": 13716,
      "continuity": 13717,
      "sadly": 13718,
      "##ische": 13719,
      "inability": 13720,
      "melting": 13721,
      "scanning": 13722,
      "paula": 13723,
      "flour": 13724,
      "judaism": 13725,
      "safer": 13726,
      "vague": 13727,
      "##lm": 13728,
      "solving": 13729,
      "curb": 13730,
      "##stown": 13731,
      "financially": 13732,
      "gable": 13733,
      "bees": 13734,
      "expired": 13735,
      "miserable": 13736,
      "cassidy": 13737,
      "dominion": 13738,
      "1789": 13739,
      "cupped": 13740,
      "145": 13741,
      "robbery": 13742,
      "facto": 13743,
      "amos": 13744,
      "warden": 13745,
      "resume": 13746,
      "tallest": 13747,
      "marvin": 13748,
      "ing": 13749,
      "pounded": 13750,
      "usd": 13751,
      "declaring": 13752,
      "gasoline": 13753,
      "##aux": 13754,
      "darkened": 13755,
      "270": 13756,
      "650": 13757,
      "sophomore": 13758,
      "##mere": 13759,
      "erection": 13760,
      "gossip": 13761,
      "televised": 13762,
      "risen": 13763,
      "dial": 13764,
      "##eu": 13765,
      "pillars": 13766,
      "##link": 13767,
      "passages": 13768,
      "profound": 13769,
      "##tina": 13770,
      "arabian": 13771,
      "ashton": 13772,
      "silicon": 13773,
      "nail": 13774,
      "##ead": 13775,
      "##lated": 13776,
      "##wer": 13777,
      "##hardt": 13778,
      "fleming": 13779,
      "firearms": 13780,
      "ducked": 13781,
      "circuits": 13782,
      "blows": 13783,
      "waterloo": 13784,
      "titans": 13785,
      "##lina": 13786,
      "atom": 13787,
      "fireplace": 13788,
      "cheshire": 13789,
      "financed": 13790,
      "activation": 13791,
      "algorithms": 13792,
      "##zzi": 13793,
      "constituent": 13794,
      "catcher": 13795,
      "cherokee": 13796,
      "partnerships": 13797,
      "sexuality": 13798,
      "platoon": 13799,
      "tragic": 13800,
      "vivian": 13801,
      "guarded": 13802,
      "whiskey": 13803,
      "meditation": 13804,
      "poetic": 13805,
      "##late": 13806,
      "##nga": 13807,
      "##ake": 13808,
      "porto": 13809,
      "listeners": 13810,
      "dominance": 13811,
      "kendra": 13812,
      "mona": 13813,
      "chandler": 13814,
      "factions": 13815,
      "22nd": 13816,
      "salisbury": 13817,
      "attitudes": 13818,
      "derivative": 13819,
      "##ido": 13820,
      "##haus": 13821,
      "intake": 13822,
      "paced": 13823,
      "javier": 13824,
      "illustrator": 13825,
      "barrels": 13826,
      "bias": 13827,
      "cockpit": 13828,
      "burnett": 13829,
      "dreamed": 13830,
      "ensuing": 13831,
      "##anda": 13832,
      "receptors": 13833,
      "someday": 13834,
      "hawkins": 13835,
      "mattered": 13836,
      "##lal": 13837,
      "slavic": 13838,
      "1799": 13839,
      "jesuit": 13840,
      "cameroon": 13841,
      "wasted": 13842,
      "tai": 13843,
      "wax": 13844,
      "lowering": 13845,
      "victorious": 13846,
      "freaking": 13847,
      "outright": 13848,
      "hancock": 13849,
      "librarian": 13850,
      "sensing": 13851,
      "bald": 13852,
      "calcium": 13853,
      "myers": 13854,
      "tablet": 13855,
      "announcing": 13856,
      "barack": 13857,
      "shipyard": 13858,
      "pharmaceutical": 13859,
      "##uan": 13860,
      "greenwich": 13861,
      "flush": 13862,
      "medley": 13863,
      "patches": 13864,
      "wolfgang": 13865,
      "pt": 13866,
      "speeches": 13867,
      "acquiring": 13868,
      "exams": 13869,
      "nikolai": 13870,
      "##gg": 13871,
      "hayden": 13872,
      "kannada": 13873,
      "##type": 13874,
      "reilly": 13875,
      "##pt": 13876,
      "waitress": 13877,
      "abdomen": 13878,
      "devastated": 13879,
      "capped": 13880,
      "pseudonym": 13881,
      "pharmacy": 13882,
      "fulfill": 13883,
      "paraguay": 13884,
      "1796": 13885,
      "clicked": 13886,
      "##trom": 13887,
      "archipelago": 13888,
      "syndicated": 13889,
      "##hman": 13890,
      "lumber": 13891,
      "orgasm": 13892,
      "rejection": 13893,
      "clifford": 13894,
      "lorraine": 13895,
      "advent": 13896,
      "mafia": 13897,
      "rodney": 13898,
      "brock": 13899,
      "##ght": 13900,
      "##used": 13901,
      "##elia": 13902,
      "cassette": 13903,
      "chamberlain": 13904,
      "despair": 13905,
      "mongolia": 13906,
      "sensors": 13907,
      "developmental": 13908,
      "upstream": 13909,
      "##eg": 13910,
      "##alis": 13911,
      "spanning": 13912,
      "165": 13913,
      "trombone": 13914,
      "basque": 13915,
      "seeded": 13916,
      "interred": 13917,
      "renewable": 13918,
      "rhys": 13919,
      "leapt": 13920,
      "revision": 13921,
      "molecule": 13922,
      "##ages": 13923,
      "chord": 13924,
      "vicious": 13925,
      "nord": 13926,
      "shivered": 13927,
      "23rd": 13928,
      "arlington": 13929,
      "debts": 13930,
      "corpus": 13931,
      "sunrise": 13932,
      "bays": 13933,
      "blackburn": 13934,
      "centimetres": 13935,
      "##uded": 13936,
      "shuddered": 13937,
      "gm": 13938,
      "strangely": 13939,
      "gripping": 13940,
      "cartoons": 13941,
      "isabelle": 13942,
      "orbital": 13943,
      "##ppa": 13944,
      "seals": 13945,
      "proving": 13946,
      "##lton": 13947,
      "refusal": 13948,
      "strengthened": 13949,
      "bust": 13950,
      "assisting": 13951,
      "baghdad": 13952,
      "batsman": 13953,
      "portrayal": 13954,
      "mara": 13955,
      "pushes": 13956,
      "spears": 13957,
      "og": 13958,
      "##cock": 13959,
      "reside": 13960,
      "nathaniel": 13961,
      "brennan": 13962,
      "1776": 13963,
      "confirmation": 13964,
      "caucus": 13965,
      "##worthy": 13966,
      "markings": 13967,
      "yemen": 13968,
      "nobles": 13969,
      "ku": 13970,
      "lazy": 13971,
      "viewer": 13972,
      "catalan": 13973,
      "encompasses": 13974,
      "sawyer": 13975,
      "##fall": 13976,
      "sparked": 13977,
      "substances": 13978,
      "patents": 13979,
      "braves": 13980,
      "arranger": 13981,
      "evacuation": 13982,
      "sergio": 13983,
      "persuade": 13984,
      "dover": 13985,
      "tolerance": 13986,
      "penguin": 13987,
      "cum": 13988,
      "jockey": 13989,
      "insufficient": 13990,
      "townships": 13991,
      "occupying": 13992,
      "declining": 13993,
      "plural": 13994,
      "processed": 13995,
      "projection": 13996,
      "puppet": 13997,
      "flanders": 13998,
      "introduces": 13999,
      "liability": 14000,
      "##yon": 14001,
      "gymnastics": 14002,
      "antwerp": 14003,
      "taipei": 14004,
      "hobart": 14005,
      "candles": 14006,
      "jeep": 14007,
      "wes": 14008,
      "observers": 14009,
      "126": 14010,
      "chaplain": 14011,
      "bundle": 14012,
      "glorious": 14013,
      "##hine": 14014,
      "hazel": 14015,
      "flung": 14016,
      "sol": 14017,
      "excavations": 14018,
      "dumped": 14019,
      "stares": 14020,
      "sh": 14021,
      "bangalore": 14022,
      "triangular": 14023,
      "icelandic": 14024,
      "intervals": 14025,
      "expressing": 14026,
      "turbine": 14027,
      "##vers": 14028,
      "songwriting": 14029,
      "crafts": 14030,
      "##igo": 14031,
      "jasmine": 14032,
      "ditch": 14033,
      "rite": 14034,
      "##ways": 14035,
      "entertaining": 14036,
      "comply": 14037,
      "sorrow": 14038,
      "wrestlers": 14039,
      "basel": 14040,
      "emirates": 14041,
      "marian": 14042,
      "rivera": 14043,
      "helpful": 14044,
      "##some": 14045,
      "caution": 14046,
      "downward": 14047,
      "networking": 14048,
      "##atory": 14049,
      "##tered": 14050,
      "darted": 14051,
      "genocide": 14052,
      "emergence": 14053,
      "replies": 14054,
      "specializing": 14055,
      "spokesman": 14056,
      "convenient": 14057,
      "unlocked": 14058,
      "fading": 14059,
      "augustine": 14060,
      "concentrations": 14061,
      "resemblance": 14062,
      "elijah": 14063,
      "investigator": 14064,
      "andhra": 14065,
      "##uda": 14066,
      "promotes": 14067,
      "bean": 14068,
      "##rrell": 14069,
      "fleeing": 14070,
      "wan": 14071,
      "simone": 14072,
      "announcer": 14073,
      "##ame": 14074,
      "##bby": 14075,
      "lydia": 14076,
      "weaver": 14077,
      "132": 14078,
      "residency": 14079,
      "modification": 14080,
      "##fest": 14081,
      "stretches": 14082,
      "##ast": 14083,
      "alternatively": 14084,
      "nat": 14085,
      "lowe": 14086,
      "lacks": 14087,
      "##ented": 14088,
      "pam": 14089,
      "tile": 14090,
      "concealed": 14091,
      "inferior": 14092,
      "abdullah": 14093,
      "residences": 14094,
      "tissues": 14095,
      "vengeance": 14096,
      "##ided": 14097,
      "moisture": 14098,
      "peculiar": 14099,
      "groove": 14100,
      "zip": 14101,
      "bologna": 14102,
      "jennings": 14103,
      "ninja": 14104,
      "oversaw": 14105,
      "zombies": 14106,
      "pumping": 14107,
      "batch": 14108,
      "livingston": 14109,
      "emerald": 14110,
      "installations": 14111,
      "1797": 14112,
      "peel": 14113,
      "nitrogen": 14114,
      "rama": 14115,
      "##fying": 14116,
      "##star": 14117,
      "schooling": 14118,
      "strands": 14119,
      "responding": 14120,
      "werner": 14121,
      "##ost": 14122,
      "lime": 14123,
      "casa": 14124,
      "accurately": 14125,
      "targeting": 14126,
      "##rod": 14127,
      "underway": 14128,
      "##uru": 14129,
      "hemisphere": 14130,
      "lester": 14131,
      "##yard": 14132,
      "occupies": 14133,
      "2d": 14134,
      "griffith": 14135,
      "angrily": 14136,
      "reorganized": 14137,
      "##owing": 14138,
      "courtney": 14139,
      "deposited": 14140,
      "##dd": 14141,
      "##30": 14142,
      "estadio": 14143,
      "##ifies": 14144,
      "dunn": 14145,
      "exiled": 14146,
      "##ying": 14147,
      "checks": 14148,
      "##combe": 14149,
      "##о": 14150,
      "##fly": 14151,
      "successes": 14152,
      "unexpectedly": 14153,
      "blu": 14154,
      "assessed": 14155,
      "##flower": 14156,
      "##ه": 14157,
      "observing": 14158,
      "sacked": 14159,
      "spiders": 14160,
      "kn": 14161,
      "##tail": 14162,
      "mu": 14163,
      "nodes": 14164,
      "prosperity": 14165,
      "audrey": 14166,
      "divisional": 14167,
      "155": 14168,
      "broncos": 14169,
      "tangled": 14170,
      "adjust": 14171,
      "feeds": 14172,
      "erosion": 14173,
      "paolo": 14174,
      "surf": 14175,
      "directory": 14176,
      "snatched": 14177,
      "humid": 14178,
      "admiralty": 14179,
      "screwed": 14180,
      "gt": 14181,
      "reddish": 14182,
      "##nese": 14183,
      "modules": 14184,
      "trench": 14185,
      "lamps": 14186,
      "bind": 14187,
      "leah": 14188,
      "bucks": 14189,
      "competes": 14190,
      "##nz": 14191,
      "##form": 14192,
      "transcription": 14193,
      "##uc": 14194,
      "isles": 14195,
      "violently": 14196,
      "clutching": 14197,
      "pga": 14198,
      "cyclist": 14199,
      "inflation": 14200,
      "flats": 14201,
      "ragged": 14202,
      "unnecessary": 14203,
      "##hian": 14204,
      "stubborn": 14205,
      "coordinated": 14206,
      "harriet": 14207,
      "baba": 14208,
      "disqualified": 14209,
      "330": 14210,
      "insect": 14211,
      "wolfe": 14212,
      "##fies": 14213,
      "reinforcements": 14214,
      "rocked": 14215,
      "duel": 14216,
      "winked": 14217,
      "embraced": 14218,
      "bricks": 14219,
      "##raj": 14220,
      "hiatus": 14221,
      "defeats": 14222,
      "pending": 14223,
      "brightly": 14224,
      "jealousy": 14225,
      "##xton": 14226,
      "##hm": 14227,
      "##uki": 14228,
      "lena": 14229,
      "gdp": 14230,
      "colorful": 14231,
      "##dley": 14232,
      "stein": 14233,
      "kidney": 14234,
      "##shu": 14235,
      "underwear": 14236,
      "wanderers": 14237,
      "##haw": 14238,
      "##icus": 14239,
      "guardians": 14240,
      "m³": 14241,
      "roared": 14242,
      "habits": 14243,
      "##wise": 14244,
      "permits": 14245,
      "gp": 14246,
      "uranium": 14247,
      "punished": 14248,
      "disguise": 14249,
      "bundesliga": 14250,
      "elise": 14251,
      "dundee": 14252,
      "erotic": 14253,
      "partisan": 14254,
      "pi": 14255,
      "collectors": 14256,
      "float": 14257,
      "individually": 14258,
      "rendering": 14259,
      "behavioral": 14260,
      "bucharest": 14261,
      "ser": 14262,
      "hare": 14263,
      "valerie": 14264,
      "corporal": 14265,
      "nutrition": 14266,
      "proportional": 14267,
      "##isa": 14268,
      "immense": 14269,
      "##kis": 14270,
      "pavement": 14271,
      "##zie": 14272,
      "##eld": 14273,
      "sutherland": 14274,
      "crouched": 14275,
      "1775": 14276,
      "##lp": 14277,
      "suzuki": 14278,
      "trades": 14279,
      "endurance": 14280,
      "operas": 14281,
      "crosby": 14282,
      "prayed": 14283,
      "priory": 14284,
      "rory": 14285,
      "socially": 14286,
      "##urn": 14287,
      "gujarat": 14288,
      "##pu": 14289,
      "walton": 14290,
      "cube": 14291,
      "pasha": 14292,
      "privilege": 14293,
      "lennon": 14294,
      "floods": 14295,
      "thorne": 14296,
      "waterfall": 14297,
      "nipple": 14298,
      "scouting": 14299,
      "approve": 14300,
      "##lov": 14301,
      "minorities": 14302,
      "voter": 14303,
      "dwight": 14304,
      "extensions": 14305,
      "assure": 14306,
      "ballroom": 14307,
      "slap": 14308,
      "dripping": 14309,
      "privileges": 14310,
      "rejoined": 14311,
      "confessed": 14312,
      "demonstrating": 14313,
      "patriotic": 14314,
      "yell": 14315,
      "investor": 14316,
      "##uth": 14317,
      "pagan": 14318,
      "slumped": 14319,
      "squares": 14320,
      "##cle": 14321,
      "##kins": 14322,
      "confront": 14323,
      "bert": 14324,
      "embarrassment": 14325,
      "##aid": 14326,
      "aston": 14327,
      "urging": 14328,
      "sweater": 14329,
      "starr": 14330,
      "yuri": 14331,
      "brains": 14332,
      "williamson": 14333,
      "commuter": 14334,
      "mortar": 14335,
      "structured": 14336,
      "selfish": 14337,
      "exports": 14338,
      "##jon": 14339,
      "cds": 14340,
      "##him": 14341,
      "unfinished": 14342,
      "##rre": 14343,
      "mortgage": 14344,
      "destinations": 14345,
      "##nagar": 14346,
      "canoe": 14347,
      "solitary": 14348,
      "buchanan": 14349,
      "delays": 14350,
      "magistrate": 14351,
      "fk": 14352,
      "##pling": 14353,
      "motivation": 14354,
      "##lier": 14355,
      "##vier": 14356,
      "recruiting": 14357,
      "assess": 14358,
      "##mouth": 14359,
      "malik": 14360,
      "antique": 14361,
      "1791": 14362,
      "pius": 14363,
      "rahman": 14364,
      "reich": 14365,
      "tub": 14366,
      "zhou": 14367,
      "smashed": 14368,
      "airs": 14369,
      "galway": 14370,
      "xii": 14371,
      "conditioning": 14372,
      "honduras": 14373,
      "discharged": 14374,
      "dexter": 14375,
      "##pf": 14376,
      "lionel": 14377,
      "129": 14378,
      "debates": 14379,
      "lemon": 14380,
      "tiffany": 14381,
      "volunteered": 14382,
      "dom": 14383,
      "dioxide": 14384,
      "procession": 14385,
      "devi": 14386,
      "sic": 14387,
      "tremendous": 14388,
      "advertisements": 14389,
      "colts": 14390,
      "transferring": 14391,
      "verdict": 14392,
      "hanover": 14393,
      "decommissioned": 14394,
      "utter": 14395,
      "relate": 14396,
      "pac": 14397,
      "racism": 14398,
      "##top": 14399,
      "beacon": 14400,
      "limp": 14401,
      "similarity": 14402,
      "terra": 14403,
      "occurrence": 14404,
      "ant": 14405,
      "##how": 14406,
      "becky": 14407,
      "capt": 14408,
      "updates": 14409,
      "armament": 14410,
      "richie": 14411,
      "pal": 14412,
      "##graph": 14413,
      "halloween": 14414,
      "mayo": 14415,
      "##ssen": 14416,
      "##bone": 14417,
      "cara": 14418,
      "serena": 14419,
      "fcc": 14420,
      "dolls": 14421,
      "obligations": 14422,
      "##dling": 14423,
      "violated": 14424,
      "lafayette": 14425,
      "jakarta": 14426,
      "exploitation": 14427,
      "##ime": 14428,
      "infamous": 14429,
      "iconic": 14430,
      "##lah": 14431,
      "##park": 14432,
      "kitty": 14433,
      "moody": 14434,
      "reginald": 14435,
      "dread": 14436,
      "spill": 14437,
      "crystals": 14438,
      "olivier": 14439,
      "modeled": 14440,
      "bluff": 14441,
      "equilibrium": 14442,
      "separating": 14443,
      "notices": 14444,
      "ordnance": 14445,
      "extinction": 14446,
      "onset": 14447,
      "cosmic": 14448,
      "attachment": 14449,
      "sammy": 14450,
      "expose": 14451,
      "privy": 14452,
      "anchored": 14453,
      "##bil": 14454,
      "abbott": 14455,
      "admits": 14456,
      "bending": 14457,
      "baritone": 14458,
      "emmanuel": 14459,
      "policeman": 14460,
      "vaughan": 14461,
      "winged": 14462,
      "climax": 14463,
      "dresses": 14464,
      "denny": 14465,
      "polytechnic": 14466,
      "mohamed": 14467,
      "burmese": 14468,
      "authentic": 14469,
      "nikki": 14470,
      "genetics": 14471,
      "grandparents": 14472,
      "homestead": 14473,
      "gaza": 14474,
      "postponed": 14475,
      "metacritic": 14476,
      "una": 14477,
      "##sby": 14478,
      "##bat": 14479,
      "unstable": 14480,
      "dissertation": 14481,
      "##rial": 14482,
      "##cian": 14483,
      "curls": 14484,
      "obscure": 14485,
      "uncovered": 14486,
      "bronx": 14487,
      "praying": 14488,
      "disappearing": 14489,
      "##hoe": 14490,
      "prehistoric": 14491,
      "coke": 14492,
      "turret": 14493,
      "mutations": 14494,
      "nonprofit": 14495,
      "pits": 14496,
      "monaco": 14497,
      "##ي": 14498,
      "##usion": 14499,
      "prominently": 14500,
      "dispatched": 14501,
      "podium": 14502,
      "##mir": 14503,
      "uci": 14504,
      "##uation": 14505,
      "133": 14506,
      "fortifications": 14507,
      "birthplace": 14508,
      "kendall": 14509,
      "##lby": 14510,
      "##oll": 14511,
      "preacher": 14512,
      "rack": 14513,
      "goodman": 14514,
      "##rman": 14515,
      "persistent": 14516,
      "##ott": 14517,
      "countless": 14518,
      "jaime": 14519,
      "recorder": 14520,
      "lexington": 14521,
      "persecution": 14522,
      "jumps": 14523,
      "renewal": 14524,
      "wagons": 14525,
      "##11": 14526,
      "crushing": 14527,
      "##holder": 14528,
      "decorations": 14529,
      "##lake": 14530,
      "abundance": 14531,
      "wrath": 14532,
      "laundry": 14533,
      "£1": 14534,
      "garde": 14535,
      "##rp": 14536,
      "jeanne": 14537,
      "beetles": 14538,
      "peasant": 14539,
      "##sl": 14540,
      "splitting": 14541,
      "caste": 14542,
      "sergei": 14543,
      "##rer": 14544,
      "##ema": 14545,
      "scripts": 14546,
      "##ively": 14547,
      "rub": 14548,
      "satellites": 14549,
      "##vor": 14550,
      "inscribed": 14551,
      "verlag": 14552,
      "scrapped": 14553,
      "gale": 14554,
      "packages": 14555,
      "chick": 14556,
      "potato": 14557,
      "slogan": 14558,
      "kathleen": 14559,
      "arabs": 14560,
      "##culture": 14561,
      "counterparts": 14562,
      "reminiscent": 14563,
      "choral": 14564,
      "##tead": 14565,
      "rand": 14566,
      "retains": 14567,
      "bushes": 14568,
      "dane": 14569,
      "accomplish": 14570,
      "courtesy": 14571,
      "closes": 14572,
      "##oth": 14573,
      "slaughter": 14574,
      "hague": 14575,
      "krakow": 14576,
      "lawson": 14577,
      "tailed": 14578,
      "elias": 14579,
      "ginger": 14580,
      "##ttes": 14581,
      "canopy": 14582,
      "betrayal": 14583,
      "rebuilding": 14584,
      "turf": 14585,
      "##hof": 14586,
      "frowning": 14587,
      "allegiance": 14588,
      "brigades": 14589,
      "kicks": 14590,
      "rebuild": 14591,
      "polls": 14592,
      "alias": 14593,
      "nationalism": 14594,
      "td": 14595,
      "rowan": 14596,
      "audition": 14597,
      "bowie": 14598,
      "fortunately": 14599,
      "recognizes": 14600,
      "harp": 14601,
      "dillon": 14602,
      "horrified": 14603,
      "##oro": 14604,
      "renault": 14605,
      "##tics": 14606,
      "ropes": 14607,
      "##α": 14608,
      "presumed": 14609,
      "rewarded": 14610,
      "infrared": 14611,
      "wiping": 14612,
      "accelerated": 14613,
      "illustration": 14614,
      "##rid": 14615,
      "presses": 14616,
      "practitioners": 14617,
      "badminton": 14618,
      "##iard": 14619,
      "detained": 14620,
      "##tera": 14621,
      "recognizing": 14622,
      "relates": 14623,
      "misery": 14624,
      "##sies": 14625,
      "##tly": 14626,
      "reproduction": 14627,
      "piercing": 14628,
      "potatoes": 14629,
      "thornton": 14630,
      "esther": 14631,
      "manners": 14632,
      "hbo": 14633,
      "##aan": 14634,
      "ours": 14635,
      "bullshit": 14636,
      "ernie": 14637,
      "perennial": 14638,
      "sensitivity": 14639,
      "illuminated": 14640,
      "rupert": 14641,
      "##jin": 14642,
      "##iss": 14643,
      "##ear": 14644,
      "rfc": 14645,
      "nassau": 14646,
      "##dock": 14647,
      "staggered": 14648,
      "socialism": 14649,
      "##haven": 14650,
      "appointments": 14651,
      "nonsense": 14652,
      "prestige": 14653,
      "sharma": 14654,
      "haul": 14655,
      "##tical": 14656,
      "solidarity": 14657,
      "gps": 14658,
      "##ook": 14659,
      "##rata": 14660,
      "igor": 14661,
      "pedestrian": 14662,
      "##uit": 14663,
      "baxter": 14664,
      "tenants": 14665,
      "wires": 14666,
      "medication": 14667,
      "unlimited": 14668,
      "guiding": 14669,
      "impacts": 14670,
      "diabetes": 14671,
      "##rama": 14672,
      "sasha": 14673,
      "pas": 14674,
      "clive": 14675,
      "extraction": 14676,
      "131": 14677,
      "continually": 14678,
      "constraints": 14679,
      "##bilities": 14680,
      "sonata": 14681,
      "hunted": 14682,
      "sixteenth": 14683,
      "chu": 14684,
      "planting": 14685,
      "quote": 14686,
      "mayer": 14687,
      "pretended": 14688,
      "abs": 14689,
      "spat": 14690,
      "##hua": 14691,
      "ceramic": 14692,
      "##cci": 14693,
      "curtains": 14694,
      "pigs": 14695,
      "pitching": 14696,
      "##dad": 14697,
      "latvian": 14698,
      "sore": 14699,
      "dayton": 14700,
      "##sted": 14701,
      "##qi": 14702,
      "patrols": 14703,
      "slice": 14704,
      "playground": 14705,
      "##nted": 14706,
      "shone": 14707,
      "stool": 14708,
      "apparatus": 14709,
      "inadequate": 14710,
      "mates": 14711,
      "treason": 14712,
      "##ija": 14713,
      "desires": 14714,
      "##liga": 14715,
      "##croft": 14716,
      "somalia": 14717,
      "laurent": 14718,
      "mir": 14719,
      "leonardo": 14720,
      "oracle": 14721,
      "grape": 14722,
      "obliged": 14723,
      "chevrolet": 14724,
      "thirteenth": 14725,
      "stunning": 14726,
      "enthusiastic": 14727,
      "##ede": 14728,
      "accounted": 14729,
      "concludes": 14730,
      "currents": 14731,
      "basil": 14732,
      "##kovic": 14733,
      "drought": 14734,
      "##rica": 14735,
      "mai": 14736,
      "##aire": 14737,
      "shove": 14738,
      "posting": 14739,
      "##shed": 14740,
      "pilgrimage": 14741,
      "humorous": 14742,
      "packing": 14743,
      "fry": 14744,
      "pencil": 14745,
      "wines": 14746,
      "smells": 14747,
      "144": 14748,
      "marilyn": 14749,
      "aching": 14750,
      "newest": 14751,
      "clung": 14752,
      "bon": 14753,
      "neighbours": 14754,
      "sanctioned": 14755,
      "##pie": 14756,
      "mug": 14757,
      "##stock": 14758,
      "drowning": 14759,
      "##mma": 14760,
      "hydraulic": 14761,
      "##vil": 14762,
      "hiring": 14763,
      "reminder": 14764,
      "lilly": 14765,
      "investigators": 14766,
      "##ncies": 14767,
      "sour": 14768,
      "##eous": 14769,
      "compulsory": 14770,
      "packet": 14771,
      "##rion": 14772,
      "##graphic": 14773,
      "##elle": 14774,
      "cannes": 14775,
      "##inate": 14776,
      "depressed": 14777,
      "##rit": 14778,
      "heroic": 14779,
      "importantly": 14780,
      "theresa": 14781,
      "##tled": 14782,
      "conway": 14783,
      "saturn": 14784,
      "marginal": 14785,
      "rae": 14786,
      "##xia": 14787,
      "corresponds": 14788,
      "royce": 14789,
      "pact": 14790,
      "jasper": 14791,
      "explosives": 14792,
      "packaging": 14793,
      "aluminium": 14794,
      "##ttered": 14795,
      "denotes": 14796,
      "rhythmic": 14797,
      "spans": 14798,
      "assignments": 14799,
      "hereditary": 14800,
      "outlined": 14801,
      "originating": 14802,
      "sundays": 14803,
      "lad": 14804,
      "reissued": 14805,
      "greeting": 14806,
      "beatrice": 14807,
      "##dic": 14808,
      "pillar": 14809,
      "marcos": 14810,
      "plots": 14811,
      "handbook": 14812,
      "alcoholic": 14813,
      "judiciary": 14814,
      "avant": 14815,
      "slides": 14816,
      "extract": 14817,
      "masculine": 14818,
      "blur": 14819,
      "##eum": 14820,
      "##force": 14821,
      "homage": 14822,
      "trembled": 14823,
      "owens": 14824,
      "hymn": 14825,
      "trey": 14826,
      "omega": 14827,
      "signaling": 14828,
      "socks": 14829,
      "accumulated": 14830,
      "reacted": 14831,
      "attic": 14832,
      "theo": 14833,
      "lining": 14834,
      "angie": 14835,
      "distraction": 14836,
      "primera": 14837,
      "talbot": 14838,
      "##key": 14839,
      "1200": 14840,
      "ti": 14841,
      "creativity": 14842,
      "billed": 14843,
      "##hey": 14844,
      "deacon": 14845,
      "eduardo": 14846,
      "identifies": 14847,
      "proposition": 14848,
      "dizzy": 14849,
      "gunner": 14850,
      "hogan": 14851,
      "##yam": 14852,
      "##pping": 14853,
      "##hol": 14854,
      "ja": 14855,
      "##chan": 14856,
      "jensen": 14857,
      "reconstructed": 14858,
      "##berger": 14859,
      "clearance": 14860,
      "darius": 14861,
      "##nier": 14862,
      "abe": 14863,
      "harlem": 14864,
      "plea": 14865,
      "dei": 14866,
      "circled": 14867,
      "emotionally": 14868,
      "notation": 14869,
      "fascist": 14870,
      "neville": 14871,
      "exceeded": 14872,
      "upwards": 14873,
      "viable": 14874,
      "ducks": 14875,
      "##fo": 14876,
      "workforce": 14877,
      "racer": 14878,
      "limiting": 14879,
      "shri": 14880,
      "##lson": 14881,
      "possesses": 14882,
      "1600": 14883,
      "kerr": 14884,
      "moths": 14885,
      "devastating": 14886,
      "laden": 14887,
      "disturbing": 14888,
      "locking": 14889,
      "##cture": 14890,
      "gal": 14891,
      "fearing": 14892,
      "accreditation": 14893,
      "flavor": 14894,
      "aide": 14895,
      "1870s": 14896,
      "mountainous": 14897,
      "##baum": 14898,
      "melt": 14899,
      "##ures": 14900,
      "motel": 14901,
      "texture": 14902,
      "servers": 14903,
      "soda": 14904,
      "##mb": 14905,
      "herd": 14906,
      "##nium": 14907,
      "erect": 14908,
      "puzzled": 14909,
      "hum": 14910,
      "peggy": 14911,
      "examinations": 14912,
      "gould": 14913,
      "testified": 14914,
      "geoff": 14915,
      "ren": 14916,
      "devised": 14917,
      "sacks": 14918,
      "##law": 14919,
      "denial": 14920,
      "posters": 14921,
      "grunted": 14922,
      "cesar": 14923,
      "tutor": 14924,
      "ec": 14925,
      "gerry": 14926,
      "offerings": 14927,
      "byrne": 14928,
      "falcons": 14929,
      "combinations": 14930,
      "ct": 14931,
      "incoming": 14932,
      "pardon": 14933,
      "rocking": 14934,
      "26th": 14935,
      "avengers": 14936,
      "flared": 14937,
      "mankind": 14938,
      "seller": 14939,
      "uttar": 14940,
      "loch": 14941,
      "nadia": 14942,
      "stroking": 14943,
      "exposing": 14944,
      "##hd": 14945,
      "fertile": 14946,
      "ancestral": 14947,
      "instituted": 14948,
      "##has": 14949,
      "noises": 14950,
      "prophecy": 14951,
      "taxation": 14952,
      "eminent": 14953,
      "vivid": 14954,
      "pol": 14955,
      "##bol": 14956,
      "dart": 14957,
      "indirect": 14958,
      "multimedia": 14959,
      "notebook": 14960,
      "upside": 14961,
      "displaying": 14962,
      "adrenaline": 14963,
      "referenced": 14964,
      "geometric": 14965,
      "##iving": 14966,
      "progression": 14967,
      "##ddy": 14968,
      "blunt": 14969,
      "announce": 14970,
      "##far": 14971,
      "implementing": 14972,
      "##lav": 14973,
      "aggression": 14974,
      "liaison": 14975,
      "cooler": 14976,
      "cares": 14977,
      "headache": 14978,
      "plantations": 14979,
      "gorge": 14980,
      "dots": 14981,
      "impulse": 14982,
      "thickness": 14983,
      "ashamed": 14984,
      "averaging": 14985,
      "kathy": 14986,
      "obligation": 14987,
      "precursor": 14988,
      "137": 14989,
      "fowler": 14990,
      "symmetry": 14991,
      "thee": 14992,
      "225": 14993,
      "hears": 14994,
      "##rai": 14995,
      "undergoing": 14996,
      "ads": 14997,
      "butcher": 14998,
      "bowler": 14999,
      "##lip": 15000,
      "cigarettes": 15001,
      "subscription": 15002,
      "goodness": 15003,
      "##ically": 15004,
      "browne": 15005,
      "##hos": 15006,
      "##tech": 15007,
      "kyoto": 15008,
      "donor": 15009,
      "##erty": 15010,
      "damaging": 15011,
      "friction": 15012,
      "drifting": 15013,
      "expeditions": 15014,
      "hardened": 15015,
      "prostitution": 15016,
      "152": 15017,
      "fauna": 15018,
      "blankets": 15019,
      "claw": 15020,
      "tossing": 15021,
      "snarled": 15022,
      "butterflies": 15023,
      "recruits": 15024,
      "investigative": 15025,
      "coated": 15026,
      "healed": 15027,
      "138": 15028,
      "communal": 15029,
      "hai": 15030,
      "xiii": 15031,
      "academics": 15032,
      "boone": 15033,
      "psychologist": 15034,
      "restless": 15035,
      "lahore": 15036,
      "stephens": 15037,
      "mba": 15038,
      "brendan": 15039,
      "foreigners": 15040,
      "printer": 15041,
      "##pc": 15042,
      "ached": 15043,
      "explode": 15044,
      "27th": 15045,
      "deed": 15046,
      "scratched": 15047,
      "dared": 15048,
      "##pole": 15049,
      "cardiac": 15050,
      "1780": 15051,
      "okinawa": 15052,
      "proto": 15053,
      "commando": 15054,
      "compelled": 15055,
      "oddly": 15056,
      "electrons": 15057,
      "##base": 15058,
      "replica": 15059,
      "thanksgiving": 15060,
      "##rist": 15061,
      "sheila": 15062,
      "deliberate": 15063,
      "stafford": 15064,
      "tidal": 15065,
      "representations": 15066,
      "hercules": 15067,
      "ou": 15068,
      "##path": 15069,
      "##iated": 15070,
      "kidnapping": 15071,
      "lenses": 15072,
      "##tling": 15073,
      "deficit": 15074,
      "samoa": 15075,
      "mouths": 15076,
      "consuming": 15077,
      "computational": 15078,
      "maze": 15079,
      "granting": 15080,
      "smirk": 15081,
      "razor": 15082,
      "fixture": 15083,
      "ideals": 15084,
      "inviting": 15085,
      "aiden": 15086,
      "nominal": 15087,
      "##vs": 15088,
      "issuing": 15089,
      "julio": 15090,
      "pitt": 15091,
      "ramsey": 15092,
      "docks": 15093,
      "##oss": 15094,
      "exhaust": 15095,
      "##owed": 15096,
      "bavarian": 15097,
      "draped": 15098,
      "anterior": 15099,
      "mating": 15100,
      "ethiopian": 15101,
      "explores": 15102,
      "noticing": 15103,
      "##nton": 15104,
      "discarded": 15105,
      "convenience": 15106,
      "hoffman": 15107,
      "endowment": 15108,
      "beasts": 15109,
      "cartridge": 15110,
      "mormon": 15111,
      "paternal": 15112,
      "probe": 15113,
      "sleeves": 15114,
      "interfere": 15115,
      "lump": 15116,
      "deadline": 15117,
      "##rail": 15118,
      "jenks": 15119,
      "bulldogs": 15120,
      "scrap": 15121,
      "alternating": 15122,
      "justified": 15123,
      "reproductive": 15124,
      "nam": 15125,
      "seize": 15126,
      "descending": 15127,
      "secretariat": 15128,
      "kirby": 15129,
      "coupe": 15130,
      "grouped": 15131,
      "smash": 15132,
      "panther": 15133,
      "sedan": 15134,
      "tapping": 15135,
      "##18": 15136,
      "lola": 15137,
      "cheer": 15138,
      "germanic": 15139,
      "unfortunate": 15140,
      "##eter": 15141,
      "unrelated": 15142,
      "##fan": 15143,
      "subordinate": 15144,
      "##sdale": 15145,
      "suzanne": 15146,
      "advertisement": 15147,
      "##ility": 15148,
      "horsepower": 15149,
      "##lda": 15150,
      "cautiously": 15151,
      "discourse": 15152,
      "luigi": 15153,
      "##mans": 15154,
      "##fields": 15155,
      "noun": 15156,
      "prevalent": 15157,
      "mao": 15158,
      "schneider": 15159,
      "everett": 15160,
      "surround": 15161,
      "governorate": 15162,
      "kira": 15163,
      "##avia": 15164,
      "westward": 15165,
      "##take": 15166,
      "misty": 15167,
      "rails": 15168,
      "sustainability": 15169,
      "134": 15170,
      "unused": 15171,
      "##rating": 15172,
      "packs": 15173,
      "toast": 15174,
      "unwilling": 15175,
      "regulate": 15176,
      "thy": 15177,
      "suffrage": 15178,
      "nile": 15179,
      "awe": 15180,
      "assam": 15181,
      "definitions": 15182,
      "travelers": 15183,
      "affordable": 15184,
      "##rb": 15185,
      "conferred": 15186,
      "sells": 15187,
      "undefeated": 15188,
      "beneficial": 15189,
      "torso": 15190,
      "basal": 15191,
      "repeating": 15192,
      "remixes": 15193,
      "##pass": 15194,
      "bahrain": 15195,
      "cables": 15196,
      "fang": 15197,
      "##itated": 15198,
      "excavated": 15199,
      "numbering": 15200,
      "statutory": 15201,
      "##rey": 15202,
      "deluxe": 15203,
      "##lian": 15204,
      "forested": 15205,
      "ramirez": 15206,
      "derbyshire": 15207,
      "zeus": 15208,
      "slamming": 15209,
      "transfers": 15210,
      "astronomer": 15211,
      "banana": 15212,
      "lottery": 15213,
      "berg": 15214,
      "histories": 15215,
      "bamboo": 15216,
      "##uchi": 15217,
      "resurrection": 15218,
      "posterior": 15219,
      "bowls": 15220,
      "vaguely": 15221,
      "##thi": 15222,
      "thou": 15223,
      "preserving": 15224,
      "tensed": 15225,
      "offence": 15226,
      "##inas": 15227,
      "meyrick": 15228,
      "callum": 15229,
      "ridden": 15230,
      "watt": 15231,
      "langdon": 15232,
      "tying": 15233,
      "lowland": 15234,
      "snorted": 15235,
      "daring": 15236,
      "truman": 15237,
      "##hale": 15238,
      "##girl": 15239,
      "aura": 15240,
      "overly": 15241,
      "filing": 15242,
      "weighing": 15243,
      "goa": 15244,
      "infections": 15245,
      "philanthropist": 15246,
      "saunders": 15247,
      "eponymous": 15248,
      "##owski": 15249,
      "latitude": 15250,
      "perspectives": 15251,
      "reviewing": 15252,
      "mets": 15253,
      "commandant": 15254,
      "radial": 15255,
      "##kha": 15256,
      "flashlight": 15257,
      "reliability": 15258,
      "koch": 15259,
      "vowels": 15260,
      "amazed": 15261,
      "ada": 15262,
      "elaine": 15263,
      "supper": 15264,
      "##rth": 15265,
      "##encies": 15266,
      "predator": 15267,
      "debated": 15268,
      "soviets": 15269,
      "cola": 15270,
      "##boards": 15271,
      "##nah": 15272,
      "compartment": 15273,
      "crooked": 15274,
      "arbitrary": 15275,
      "fourteenth": 15276,
      "##ctive": 15277,
      "havana": 15278,
      "majors": 15279,
      "steelers": 15280,
      "clips": 15281,
      "profitable": 15282,
      "ambush": 15283,
      "exited": 15284,
      "packers": 15285,
      "##tile": 15286,
      "nude": 15287,
      "cracks": 15288,
      "fungi": 15289,
      "##е": 15290,
      "limb": 15291,
      "trousers": 15292,
      "josie": 15293,
      "shelby": 15294,
      "tens": 15295,
      "frederic": 15296,
      "##ος": 15297,
      "definite": 15298,
      "smoothly": 15299,
      "constellation": 15300,
      "insult": 15301,
      "baton": 15302,
      "discs": 15303,
      "lingering": 15304,
      "##nco": 15305,
      "conclusions": 15306,
      "lent": 15307,
      "staging": 15308,
      "becker": 15309,
      "grandpa": 15310,
      "shaky": 15311,
      "##tron": 15312,
      "einstein": 15313,
      "obstacles": 15314,
      "sk": 15315,
      "adverse": 15316,
      "elle": 15317,
      "economically": 15318,
      "##moto": 15319,
      "mccartney": 15320,
      "thor": 15321,
      "dismissal": 15322,
      "motions": 15323,
      "readings": 15324,
      "nostrils": 15325,
      "treatise": 15326,
      "##pace": 15327,
      "squeezing": 15328,
      "evidently": 15329,
      "prolonged": 15330,
      "1783": 15331,
      "venezuelan": 15332,
      "je": 15333,
      "marguerite": 15334,
      "beirut": 15335,
      "takeover": 15336,
      "shareholders": 15337,
      "##vent": 15338,
      "denise": 15339,
      "digit": 15340,
      "airplay": 15341,
      "norse": 15342,
      "##bbling": 15343,
      "imaginary": 15344,
      "pills": 15345,
      "hubert": 15346,
      "blaze": 15347,
      "vacated": 15348,
      "eliminating": 15349,
      "##ello": 15350,
      "vine": 15351,
      "mansfield": 15352,
      "##tty": 15353,
      "retrospective": 15354,
      "barrow": 15355,
      "borne": 15356,
      "clutch": 15357,
      "bail": 15358,
      "forensic": 15359,
      "weaving": 15360,
      "##nett": 15361,
      "##witz": 15362,
      "desktop": 15363,
      "citadel": 15364,
      "promotions": 15365,
      "worrying": 15366,
      "dorset": 15367,
      "ieee": 15368,
      "subdivided": 15369,
      "##iating": 15370,
      "manned": 15371,
      "expeditionary": 15372,
      "pickup": 15373,
      "synod": 15374,
      "chuckle": 15375,
      "185": 15376,
      "barney": 15377,
      "##rz": 15378,
      "##ffin": 15379,
      "functionality": 15380,
      "karachi": 15381,
      "litigation": 15382,
      "meanings": 15383,
      "uc": 15384,
      "lick": 15385,
      "turbo": 15386,
      "anders": 15387,
      "##ffed": 15388,
      "execute": 15389,
      "curl": 15390,
      "oppose": 15391,
      "ankles": 15392,
      "typhoon": 15393,
      "##د": 15394,
      "##ache": 15395,
      "##asia": 15396,
      "linguistics": 15397,
      "compassion": 15398,
      "pressures": 15399,
      "grazing": 15400,
      "perfection": 15401,
      "##iting": 15402,
      "immunity": 15403,
      "monopoly": 15404,
      "muddy": 15405,
      "backgrounds": 15406,
      "136": 15407,
      "namibia": 15408,
      "francesca": 15409,
      "monitors": 15410,
      "attracting": 15411,
      "stunt": 15412,
      "tuition": 15413,
      "##ии": 15414,
      "vegetable": 15415,
      "##mates": 15416,
      "##quent": 15417,
      "mgm": 15418,
      "jen": 15419,
      "complexes": 15420,
      "forts": 15421,
      "##ond": 15422,
      "cellar": 15423,
      "bites": 15424,
      "seventeenth": 15425,
      "royals": 15426,
      "flemish": 15427,
      "failures": 15428,
      "mast": 15429,
      "charities": 15430,
      "##cular": 15431,
      "peruvian": 15432,
      "capitals": 15433,
      "macmillan": 15434,
      "ipswich": 15435,
      "outward": 15436,
      "frigate": 15437,
      "postgraduate": 15438,
      "folds": 15439,
      "employing": 15440,
      "##ouse": 15441,
      "concurrently": 15442,
      "fiery": 15443,
      "##tai": 15444,
      "contingent": 15445,
      "nightmares": 15446,
      "monumental": 15447,
      "nicaragua": 15448,
      "##kowski": 15449,
      "lizard": 15450,
      "mal": 15451,
      "fielding": 15452,
      "gig": 15453,
      "reject": 15454,
      "##pad": 15455,
      "harding": 15456,
      "##ipe": 15457,
      "coastline": 15458,
      "##cin": 15459,
      "##nos": 15460,
      "beethoven": 15461,
      "humphrey": 15462,
      "innovations": 15463,
      "##tam": 15464,
      "##nge": 15465,
      "norris": 15466,
      "doris": 15467,
      "solicitor": 15468,
      "huang": 15469,
      "obey": 15470,
      "141": 15471,
      "##lc": 15472,
      "niagara": 15473,
      "##tton": 15474,
      "shelves": 15475,
      "aug": 15476,
      "bourbon": 15477,
      "curry": 15478,
      "nightclub": 15479,
      "specifications": 15480,
      "hilton": 15481,
      "##ndo": 15482,
      "centennial": 15483,
      "dispersed": 15484,
      "worm": 15485,
      "neglected": 15486,
      "briggs": 15487,
      "sm": 15488,
      "font": 15489,
      "kuala": 15490,
      "uneasy": 15491,
      "plc": 15492,
      "##nstein": 15493,
      "##bound": 15494,
      "##aking": 15495,
      "##burgh": 15496,
      "awaiting": 15497,
      "pronunciation": 15498,
      "##bbed": 15499,
      "##quest": 15500,
      "eh": 15501,
      "optimal": 15502,
      "zhu": 15503,
      "raped": 15504,
      "greens": 15505,
      "presided": 15506,
      "brenda": 15507,
      "worries": 15508,
      "##life": 15509,
      "venetian": 15510,
      "marxist": 15511,
      "turnout": 15512,
      "##lius": 15513,
      "refined": 15514,
      "braced": 15515,
      "sins": 15516,
      "grasped": 15517,
      "sunderland": 15518,
      "nickel": 15519,
      "speculated": 15520,
      "lowell": 15521,
      "cyrillic": 15522,
      "communism": 15523,
      "fundraising": 15524,
      "resembling": 15525,
      "colonists": 15526,
      "mutant": 15527,
      "freddie": 15528,
      "usc": 15529,
      "##mos": 15530,
      "gratitude": 15531,
      "##run": 15532,
      "mural": 15533,
      "##lous": 15534,
      "chemist": 15535,
      "wi": 15536,
      "reminds": 15537,
      "28th": 15538,
      "steals": 15539,
      "tess": 15540,
      "pietro": 15541,
      "##ingen": 15542,
      "promoter": 15543,
      "ri": 15544,
      "microphone": 15545,
      "honoured": 15546,
      "rai": 15547,
      "sant": 15548,
      "##qui": 15549,
      "feather": 15550,
      "##nson": 15551,
      "burlington": 15552,
      "kurdish": 15553,
      "terrorists": 15554,
      "deborah": 15555,
      "sickness": 15556,
      "##wed": 15557,
      "##eet": 15558,
      "hazard": 15559,
      "irritated": 15560,
      "desperation": 15561,
      "veil": 15562,
      "clarity": 15563,
      "##rik": 15564,
      "jewels": 15565,
      "xv": 15566,
      "##gged": 15567,
      "##ows": 15568,
      "##cup": 15569,
      "berkshire": 15570,
      "unfair": 15571,
      "mysteries": 15572,
      "orchid": 15573,
      "winced": 15574,
      "exhaustion": 15575,
      "renovations": 15576,
      "stranded": 15577,
      "obe": 15578,
      "infinity": 15579,
      "##nies": 15580,
      "adapt": 15581,
      "redevelopment": 15582,
      "thanked": 15583,
      "registry": 15584,
      "olga": 15585,
      "domingo": 15586,
      "noir": 15587,
      "tudor": 15588,
      "ole": 15589,
      "##atus": 15590,
      "commenting": 15591,
      "behaviors": 15592,
      "##ais": 15593,
      "crisp": 15594,
      "pauline": 15595,
      "probable": 15596,
      "stirling": 15597,
      "wigan": 15598,
      "##bian": 15599,
      "paralympics": 15600,
      "panting": 15601,
      "surpassed": 15602,
      "##rew": 15603,
      "luca": 15604,
      "barred": 15605,
      "pony": 15606,
      "famed": 15607,
      "##sters": 15608,
      "cassandra": 15609,
      "waiter": 15610,
      "carolyn": 15611,
      "exported": 15612,
      "##orted": 15613,
      "andres": 15614,
      "destructive": 15615,
      "deeds": 15616,
      "jonah": 15617,
      "castles": 15618,
      "vacancy": 15619,
      "suv": 15620,
      "##glass": 15621,
      "1788": 15622,
      "orchard": 15623,
      "yep": 15624,
      "famine": 15625,
      "belarusian": 15626,
      "sprang": 15627,
      "##forth": 15628,
      "skinny": 15629,
      "##mis": 15630,
      "administrators": 15631,
      "rotterdam": 15632,
      "zambia": 15633,
      "zhao": 15634,
      "boiler": 15635,
      "discoveries": 15636,
      "##ride": 15637,
      "##physics": 15638,
      "lucius": 15639,
      "disappointing": 15640,
      "outreach": 15641,
      "spoon": 15642,
      "##frame": 15643,
      "qualifications": 15644,
      "unanimously": 15645,
      "enjoys": 15646,
      "regency": 15647,
      "##iidae": 15648,
      "stade": 15649,
      "realism": 15650,
      "veterinary": 15651,
      "rodgers": 15652,
      "dump": 15653,
      "alain": 15654,
      "chestnut": 15655,
      "castile": 15656,
      "censorship": 15657,
      "rumble": 15658,
      "gibbs": 15659,
      "##itor": 15660,
      "communion": 15661,
      "reggae": 15662,
      "inactivated": 15663,
      "logs": 15664,
      "loads": 15665,
      "##houses": 15666,
      "homosexual": 15667,
      "##iano": 15668,
      "ale": 15669,
      "informs": 15670,
      "##cas": 15671,
      "phrases": 15672,
      "plaster": 15673,
      "linebacker": 15674,
      "ambrose": 15675,
      "kaiser": 15676,
      "fascinated": 15677,
      "850": 15678,
      "limerick": 15679,
      "recruitment": 15680,
      "forge": 15681,
      "mastered": 15682,
      "##nding": 15683,
      "leinster": 15684,
      "rooted": 15685,
      "threaten": 15686,
      "##strom": 15687,
      "borneo": 15688,
      "##hes": 15689,
      "suggestions": 15690,
      "scholarships": 15691,
      "propeller": 15692,
      "documentaries": 15693,
      "patronage": 15694,
      "coats": 15695,
      "constructing": 15696,
      "invest": 15697,
      "neurons": 15698,
      "comet": 15699,
      "entirety": 15700,
      "shouts": 15701,
      "identities": 15702,
      "annoying": 15703,
      "unchanged": 15704,
      "wary": 15705,
      "##antly": 15706,
      "##ogy": 15707,
      "neat": 15708,
      "oversight": 15709,
      "##kos": 15710,
      "phillies": 15711,
      "replay": 15712,
      "constance": 15713,
      "##kka": 15714,
      "incarnation": 15715,
      "humble": 15716,
      "skies": 15717,
      "minus": 15718,
      "##acy": 15719,
      "smithsonian": 15720,
      "##chel": 15721,
      "guerrilla": 15722,
      "jar": 15723,
      "cadets": 15724,
      "##plate": 15725,
      "surplus": 15726,
      "audit": 15727,
      "##aru": 15728,
      "cracking": 15729,
      "joanna": 15730,
      "louisa": 15731,
      "pacing": 15732,
      "##lights": 15733,
      "intentionally": 15734,
      "##iri": 15735,
      "diner": 15736,
      "nwa": 15737,
      "imprint": 15738,
      "australians": 15739,
      "tong": 15740,
      "unprecedented": 15741,
      "bunker": 15742,
      "naive": 15743,
      "specialists": 15744,
      "ark": 15745,
      "nichols": 15746,
      "railing": 15747,
      "leaked": 15748,
      "pedal": 15749,
      "##uka": 15750,
      "shrub": 15751,
      "longing": 15752,
      "roofs": 15753,
      "v8": 15754,
      "captains": 15755,
      "neural": 15756,
      "tuned": 15757,
      "##ntal": 15758,
      "##jet": 15759,
      "emission": 15760,
      "medina": 15761,
      "frantic": 15762,
      "codex": 15763,
      "definitive": 15764,
      "sid": 15765,
      "abolition": 15766,
      "intensified": 15767,
      "stocks": 15768,
      "enrique": 15769,
      "sustain": 15770,
      "genoa": 15771,
      "oxide": 15772,
      "##written": 15773,
      "clues": 15774,
      "cha": 15775,
      "##gers": 15776,
      "tributaries": 15777,
      "fragment": 15778,
      "venom": 15779,
      "##rity": 15780,
      "##ente": 15781,
      "##sca": 15782,
      "muffled": 15783,
      "vain": 15784,
      "sire": 15785,
      "laos": 15786,
      "##ingly": 15787,
      "##hana": 15788,
      "hastily": 15789,
      "snapping": 15790,
      "surfaced": 15791,
      "sentiment": 15792,
      "motive": 15793,
      "##oft": 15794,
      "contests": 15795,
      "approximate": 15796,
      "mesa": 15797,
      "luckily": 15798,
      "dinosaur": 15799,
      "exchanges": 15800,
      "propelled": 15801,
      "accord": 15802,
      "bourne": 15803,
      "relieve": 15804,
      "tow": 15805,
      "masks": 15806,
      "offended": 15807,
      "##ues": 15808,
      "cynthia": 15809,
      "##mmer": 15810,
      "rains": 15811,
      "bartender": 15812,
      "zinc": 15813,
      "reviewers": 15814,
      "lois": 15815,
      "##sai": 15816,
      "legged": 15817,
      "arrogant": 15818,
      "rafe": 15819,
      "rosie": 15820,
      "comprise": 15821,
      "handicap": 15822,
      "blockade": 15823,
      "inlet": 15824,
      "lagoon": 15825,
      "copied": 15826,
      "drilling": 15827,
      "shelley": 15828,
      "petals": 15829,
      "##inian": 15830,
      "mandarin": 15831,
      "obsolete": 15832,
      "##inated": 15833,
      "onward": 15834,
      "arguably": 15835,
      "productivity": 15836,
      "cindy": 15837,
      "praising": 15838,
      "seldom": 15839,
      "busch": 15840,
      "discusses": 15841,
      "raleigh": 15842,
      "shortage": 15843,
      "ranged": 15844,
      "stanton": 15845,
      "encouragement": 15846,
      "firstly": 15847,
      "conceded": 15848,
      "overs": 15849,
      "temporal": 15850,
      "##uke": 15851,
      "cbe": 15852,
      "##bos": 15853,
      "woo": 15854,
      "certainty": 15855,
      "pumps": 15856,
      "##pton": 15857,
      "stalked": 15858,
      "##uli": 15859,
      "lizzie": 15860,
      "periodic": 15861,
      "thieves": 15862,
      "weaker": 15863,
      "##night": 15864,
      "gases": 15865,
      "shoving": 15866,
      "chooses": 15867,
      "wc": 15868,
      "##chemical": 15869,
      "prompting": 15870,
      "weights": 15871,
      "##kill": 15872,
      "robust": 15873,
      "flanked": 15874,
      "sticky": 15875,
      "hu": 15876,
      "tuberculosis": 15877,
      "##eb": 15878,
      "##eal": 15879,
      "christchurch": 15880,
      "resembled": 15881,
      "wallet": 15882,
      "reese": 15883,
      "inappropriate": 15884,
      "pictured": 15885,
      "distract": 15886,
      "fixing": 15887,
      "fiddle": 15888,
      "giggled": 15889,
      "burger": 15890,
      "heirs": 15891,
      "hairy": 15892,
      "mechanic": 15893,
      "torque": 15894,
      "apache": 15895,
      "obsessed": 15896,
      "chiefly": 15897,
      "cheng": 15898,
      "logging": 15899,
      "##tag": 15900,
      "extracted": 15901,
      "meaningful": 15902,
      "numb": 15903,
      "##vsky": 15904,
      "gloucestershire": 15905,
      "reminding": 15906,
      "##bay": 15907,
      "unite": 15908,
      "##lit": 15909,
      "breeds": 15910,
      "diminished": 15911,
      "clown": 15912,
      "glove": 15913,
      "1860s": 15914,
      "##ن": 15915,
      "##ug": 15916,
      "archibald": 15917,
      "focal": 15918,
      "freelance": 15919,
      "sliced": 15920,
      "depiction": 15921,
      "##yk": 15922,
      "organism": 15923,
      "switches": 15924,
      "sights": 15925,
      "stray": 15926,
      "crawling": 15927,
      "##ril": 15928,
      "lever": 15929,
      "leningrad": 15930,
      "interpretations": 15931,
      "loops": 15932,
      "anytime": 15933,
      "reel": 15934,
      "alicia": 15935,
      "delighted": 15936,
      "##ech": 15937,
      "inhaled": 15938,
      "xiv": 15939,
      "suitcase": 15940,
      "bernie": 15941,
      "vega": 15942,
      "licenses": 15943,
      "northampton": 15944,
      "exclusion": 15945,
      "induction": 15946,
      "monasteries": 15947,
      "racecourse": 15948,
      "homosexuality": 15949,
      "##right": 15950,
      "##sfield": 15951,
      "##rky": 15952,
      "dimitri": 15953,
      "michele": 15954,
      "alternatives": 15955,
      "ions": 15956,
      "commentators": 15957,
      "genuinely": 15958,
      "objected": 15959,
      "pork": 15960,
      "hospitality": 15961,
      "fencing": 15962,
      "stephan": 15963,
      "warships": 15964,
      "peripheral": 15965,
      "wit": 15966,
      "drunken": 15967,
      "wrinkled": 15968,
      "quentin": 15969,
      "spends": 15970,
      "departing": 15971,
      "chung": 15972,
      "numerical": 15973,
      "spokesperson": 15974,
      "##zone": 15975,
      "johannesburg": 15976,
      "caliber": 15977,
      "killers": 15978,
      "##udge": 15979,
      "assumes": 15980,
      "neatly": 15981,
      "demographic": 15982,
      "abigail": 15983,
      "bloc": 15984,
      "##vel": 15985,
      "mounting": 15986,
      "##lain": 15987,
      "bentley": 15988,
      "slightest": 15989,
      "xu": 15990,
      "recipients": 15991,
      "##jk": 15992,
      "merlin": 15993,
      "##writer": 15994,
      "seniors": 15995,
      "prisons": 15996,
      "blinking": 15997,
      "hindwings": 15998,
      "flickered": 15999,
      "kappa": 16000,
      "##hel": 16001,
      "80s": 16002,
      "strengthening": 16003,
      "appealing": 16004,
      "brewing": 16005,
      "gypsy": 16006,
      "mali": 16007,
      "lashes": 16008,
      "hulk": 16009,
      "unpleasant": 16010,
      "harassment": 16011,
      "bio": 16012,
      "treaties": 16013,
      "predict": 16014,
      "instrumentation": 16015,
      "pulp": 16016,
      "troupe": 16017,
      "boiling": 16018,
      "mantle": 16019,
      "##ffe": 16020,
      "ins": 16021,
      "##vn": 16022,
      "dividing": 16023,
      "handles": 16024,
      "verbs": 16025,
      "##onal": 16026,
      "coconut": 16027,
      "senegal": 16028,
      "340": 16029,
      "thorough": 16030,
      "gum": 16031,
      "momentarily": 16032,
      "##sto": 16033,
      "cocaine": 16034,
      "panicked": 16035,
      "destined": 16036,
      "##turing": 16037,
      "teatro": 16038,
      "denying": 16039,
      "weary": 16040,
      "captained": 16041,
      "mans": 16042,
      "##hawks": 16043,
      "##code": 16044,
      "wakefield": 16045,
      "bollywood": 16046,
      "thankfully": 16047,
      "##16": 16048,
      "cyril": 16049,
      "##wu": 16050,
      "amendments": 16051,
      "##bahn": 16052,
      "consultation": 16053,
      "stud": 16054,
      "reflections": 16055,
      "kindness": 16056,
      "1787": 16057,
      "internally": 16058,
      "##ovo": 16059,
      "tex": 16060,
      "mosaic": 16061,
      "distribute": 16062,
      "paddy": 16063,
      "seeming": 16064,
      "143": 16065,
      "##hic": 16066,
      "piers": 16067,
      "##15": 16068,
      "##mura": 16069,
      "##verse": 16070,
      "popularly": 16071,
      "winger": 16072,
      "kang": 16073,
      "sentinel": 16074,
      "mccoy": 16075,
      "##anza": 16076,
      "covenant": 16077,
      "##bag": 16078,
      "verge": 16079,
      "fireworks": 16080,
      "suppress": 16081,
      "thrilled": 16082,
      "dominate": 16083,
      "##jar": 16084,
      "swansea": 16085,
      "##60": 16086,
      "142": 16087,
      "reconciliation": 16088,
      "##ndi": 16089,
      "stiffened": 16090,
      "cue": 16091,
      "dorian": 16092,
      "##uf": 16093,
      "damascus": 16094,
      "amor": 16095,
      "ida": 16096,
      "foremost": 16097,
      "##aga": 16098,
      "porsche": 16099,
      "unseen": 16100,
      "dir": 16101,
      "##had": 16102,
      "##azi": 16103,
      "stony": 16104,
      "lexi": 16105,
      "melodies": 16106,
      "##nko": 16107,
      "angular": 16108,
      "integer": 16109,
      "podcast": 16110,
      "ants": 16111,
      "inherent": 16112,
      "jaws": 16113,
      "justify": 16114,
      "persona": 16115,
      "##olved": 16116,
      "josephine": 16117,
      "##nr": 16118,
      "##ressed": 16119,
      "customary": 16120,
      "flashes": 16121,
      "gala": 16122,
      "cyrus": 16123,
      "glaring": 16124,
      "backyard": 16125,
      "ariel": 16126,
      "physiology": 16127,
      "greenland": 16128,
      "html": 16129,
      "stir": 16130,
      "avon": 16131,
      "atletico": 16132,
      "finch": 16133,
      "methodology": 16134,
      "ked": 16135,
      "##lent": 16136,
      "mas": 16137,
      "catholicism": 16138,
      "townsend": 16139,
      "branding": 16140,
      "quincy": 16141,
      "fits": 16142,
      "containers": 16143,
      "1777": 16144,
      "ashore": 16145,
      "aragon": 16146,
      "##19": 16147,
      "forearm": 16148,
      "poisoning": 16149,
      "##sd": 16150,
      "adopting": 16151,
      "conquer": 16152,
      "grinding": 16153,
      "amnesty": 16154,
      "keller": 16155,
      "finances": 16156,
      "evaluate": 16157,
      "forged": 16158,
      "lankan": 16159,
      "instincts": 16160,
      "##uto": 16161,
      "guam": 16162,
      "bosnian": 16163,
      "photographed": 16164,
      "workplace": 16165,
      "desirable": 16166,
      "protector": 16167,
      "##dog": 16168,
      "allocation": 16169,
      "intently": 16170,
      "encourages": 16171,
      "willy": 16172,
      "##sten": 16173,
      "bodyguard": 16174,
      "electro": 16175,
      "brighter": 16176,
      "##ν": 16177,
      "bihar": 16178,
      "##chev": 16179,
      "lasts": 16180,
      "opener": 16181,
      "amphibious": 16182,
      "sal": 16183,
      "verde": 16184,
      "arte": 16185,
      "##cope": 16186,
      "captivity": 16187,
      "vocabulary": 16188,
      "yields": 16189,
      "##tted": 16190,
      "agreeing": 16191,
      "desmond": 16192,
      "pioneered": 16193,
      "##chus": 16194,
      "strap": 16195,
      "campaigned": 16196,
      "railroads": 16197,
      "##ович": 16198,
      "emblem": 16199,
      "##dre": 16200,
      "stormed": 16201,
      "501": 16202,
      "##ulous": 16203,
      "marijuana": 16204,
      "northumberland": 16205,
      "##gn": 16206,
      "##nath": 16207,
      "bowen": 16208,
      "landmarks": 16209,
      "beaumont": 16210,
      "##qua": 16211,
      "danube": 16212,
      "##bler": 16213,
      "attorneys": 16214,
      "th": 16215,
      "ge": 16216,
      "flyers": 16217,
      "critique": 16218,
      "villains": 16219,
      "cass": 16220,
      "mutation": 16221,
      "acc": 16222,
      "##0s": 16223,
      "colombo": 16224,
      "mckay": 16225,
      "motif": 16226,
      "sampling": 16227,
      "concluding": 16228,
      "syndicate": 16229,
      "##rell": 16230,
      "neon": 16231,
      "stables": 16232,
      "ds": 16233,
      "warnings": 16234,
      "clint": 16235,
      "mourning": 16236,
      "wilkinson": 16237,
      "##tated": 16238,
      "merrill": 16239,
      "leopard": 16240,
      "evenings": 16241,
      "exhaled": 16242,
      "emil": 16243,
      "sonia": 16244,
      "ezra": 16245,
      "discrete": 16246,
      "stove": 16247,
      "farrell": 16248,
      "fifteenth": 16249,
      "prescribed": 16250,
      "superhero": 16251,
      "##rier": 16252,
      "worms": 16253,
      "helm": 16254,
      "wren": 16255,
      "##duction": 16256,
      "##hc": 16257,
      "expo": 16258,
      "##rator": 16259,
      "hq": 16260,
      "unfamiliar": 16261,
      "antony": 16262,
      "prevents": 16263,
      "acceleration": 16264,
      "fiercely": 16265,
      "mari": 16266,
      "painfully": 16267,
      "calculations": 16268,
      "cheaper": 16269,
      "ign": 16270,
      "clifton": 16271,
      "irvine": 16272,
      "davenport": 16273,
      "mozambique": 16274,
      "##np": 16275,
      "pierced": 16276,
      "##evich": 16277,
      "wonders": 16278,
      "##wig": 16279,
      "##cate": 16280,
      "##iling": 16281,
      "crusade": 16282,
      "ware": 16283,
      "##uel": 16284,
      "enzymes": 16285,
      "reasonably": 16286,
      "mls": 16287,
      "##coe": 16288,
      "mater": 16289,
      "ambition": 16290,
      "bunny": 16291,
      "eliot": 16292,
      "kernel": 16293,
      "##fin": 16294,
      "asphalt": 16295,
      "headmaster": 16296,
      "torah": 16297,
      "aden": 16298,
      "lush": 16299,
      "pins": 16300,
      "waived": 16301,
      "##care": 16302,
      "##yas": 16303,
      "joao": 16304,
      "substrate": 16305,
      "enforce": 16306,
      "##grad": 16307,
      "##ules": 16308,
      "alvarez": 16309,
      "selections": 16310,
      "epidemic": 16311,
      "tempted": 16312,
      "##bit": 16313,
      "bremen": 16314,
      "translates": 16315,
      "ensured": 16316,
      "waterfront": 16317,
      "29th": 16318,
      "forrest": 16319,
      "manny": 16320,
      "malone": 16321,
      "kramer": 16322,
      "reigning": 16323,
      "cookies": 16324,
      "simpler": 16325,
      "absorption": 16326,
      "205": 16327,
      "engraved": 16328,
      "##ffy": 16329,
      "evaluated": 16330,
      "1778": 16331,
      "haze": 16332,
      "146": 16333,
      "comforting": 16334,
      "crossover": 16335,
      "##abe": 16336,
      "thorn": 16337,
      "##rift": 16338,
      "##imo": 16339,
      "##pop": 16340,
      "suppression": 16341,
      "fatigue": 16342,
      "cutter": 16343,
      "##tr": 16344,
      "201": 16345,
      "wurttemberg": 16346,
      "##orf": 16347,
      "enforced": 16348,
      "hovering": 16349,
      "proprietary": 16350,
      "gb": 16351,
      "samurai": 16352,
      "syllable": 16353,
      "ascent": 16354,
      "lacey": 16355,
      "tick": 16356,
      "lars": 16357,
      "tractor": 16358,
      "merchandise": 16359,
      "rep": 16360,
      "bouncing": 16361,
      "defendants": 16362,
      "##yre": 16363,
      "huntington": 16364,
      "##ground": 16365,
      "##oko": 16366,
      "standardized": 16367,
      "##hor": 16368,
      "##hima": 16369,
      "assassinated": 16370,
      "nu": 16371,
      "predecessors": 16372,
      "rainy": 16373,
      "liar": 16374,
      "assurance": 16375,
      "lyrical": 16376,
      "##uga": 16377,
      "secondly": 16378,
      "flattened": 16379,
      "ios": 16380,
      "parameter": 16381,
      "undercover": 16382,
      "##mity": 16383,
      "bordeaux": 16384,
      "punish": 16385,
      "ridges": 16386,
      "markers": 16387,
      "exodus": 16388,
      "inactive": 16389,
      "hesitate": 16390,
      "debbie": 16391,
      "nyc": 16392,
      "pledge": 16393,
      "savoy": 16394,
      "nagar": 16395,
      "offset": 16396,
      "organist": 16397,
      "##tium": 16398,
      "hesse": 16399,
      "marin": 16400,
      "converting": 16401,
      "##iver": 16402,
      "diagram": 16403,
      "propulsion": 16404,
      "pu": 16405,
      "validity": 16406,
      "reverted": 16407,
      "supportive": 16408,
      "##dc": 16409,
      "ministries": 16410,
      "clans": 16411,
      "responds": 16412,
      "proclamation": 16413,
      "##inae": 16414,
      "##ø": 16415,
      "##rea": 16416,
      "ein": 16417,
      "pleading": 16418,
      "patriot": 16419,
      "sf": 16420,
      "birch": 16421,
      "islanders": 16422,
      "strauss": 16423,
      "hates": 16424,
      "##dh": 16425,
      "brandenburg": 16426,
      "concession": 16427,
      "rd": 16428,
      "##ob": 16429,
      "1900s": 16430,
      "killings": 16431,
      "textbook": 16432,
      "antiquity": 16433,
      "cinematography": 16434,
      "wharf": 16435,
      "embarrassing": 16436,
      "setup": 16437,
      "creed": 16438,
      "farmland": 16439,
      "inequality": 16440,
      "centred": 16441,
      "signatures": 16442,
      "fallon": 16443,
      "370": 16444,
      "##ingham": 16445,
      "##uts": 16446,
      "ceylon": 16447,
      "gazing": 16448,
      "directive": 16449,
      "laurie": 16450,
      "##tern": 16451,
      "globally": 16452,
      "##uated": 16453,
      "##dent": 16454,
      "allah": 16455,
      "excavation": 16456,
      "threads": 16457,
      "##cross": 16458,
      "148": 16459,
      "frantically": 16460,
      "icc": 16461,
      "utilize": 16462,
      "determines": 16463,
      "respiratory": 16464,
      "thoughtful": 16465,
      "receptions": 16466,
      "##dicate": 16467,
      "merging": 16468,
      "chandra": 16469,
      "seine": 16470,
      "147": 16471,
      "builders": 16472,
      "builds": 16473,
      "diagnostic": 16474,
      "dev": 16475,
      "visibility": 16476,
      "goddamn": 16477,
      "analyses": 16478,
      "dhaka": 16479,
      "cho": 16480,
      "proves": 16481,
      "chancel": 16482,
      "concurrent": 16483,
      "curiously": 16484,
      "canadians": 16485,
      "pumped": 16486,
      "restoring": 16487,
      "1850s": 16488,
      "turtles": 16489,
      "jaguar": 16490,
      "sinister": 16491,
      "spinal": 16492,
      "traction": 16493,
      "declan": 16494,
      "vows": 16495,
      "1784": 16496,
      "glowed": 16497,
      "capitalism": 16498,
      "swirling": 16499,
      "install": 16500,
      "universidad": 16501,
      "##lder": 16502,
      "##oat": 16503,
      "soloist": 16504,
      "##genic": 16505,
      "##oor": 16506,
      "coincidence": 16507,
      "beginnings": 16508,
      "nissan": 16509,
      "dip": 16510,
      "resorts": 16511,
      "caucasus": 16512,
      "combustion": 16513,
      "infectious": 16514,
      "##eno": 16515,
      "pigeon": 16516,
      "serpent": 16517,
      "##itating": 16518,
      "conclude": 16519,
      "masked": 16520,
      "salad": 16521,
      "jew": 16522,
      "##gr": 16523,
      "surreal": 16524,
      "toni": 16525,
      "##wc": 16526,
      "harmonica": 16527,
      "151": 16528,
      "##gins": 16529,
      "##etic": 16530,
      "##coat": 16531,
      "fishermen": 16532,
      "intending": 16533,
      "bravery": 16534,
      "##wave": 16535,
      "klaus": 16536,
      "titan": 16537,
      "wembley": 16538,
      "taiwanese": 16539,
      "ransom": 16540,
      "40th": 16541,
      "incorrect": 16542,
      "hussein": 16543,
      "eyelids": 16544,
      "jp": 16545,
      "cooke": 16546,
      "dramas": 16547,
      "utilities": 16548,
      "##etta": 16549,
      "##print": 16550,
      "eisenhower": 16551,
      "principally": 16552,
      "granada": 16553,
      "lana": 16554,
      "##rak": 16555,
      "openings": 16556,
      "concord": 16557,
      "##bl": 16558,
      "bethany": 16559,
      "connie": 16560,
      "morality": 16561,
      "sega": 16562,
      "##mons": 16563,
      "##nard": 16564,
      "earnings": 16565,
      "##kara": 16566,
      "##cine": 16567,
      "wii": 16568,
      "communes": 16569,
      "##rel": 16570,
      "coma": 16571,
      "composing": 16572,
      "softened": 16573,
      "severed": 16574,
      "grapes": 16575,
      "##17": 16576,
      "nguyen": 16577,
      "analyzed": 16578,
      "warlord": 16579,
      "hubbard": 16580,
      "heavenly": 16581,
      "behave": 16582,
      "slovenian": 16583,
      "##hit": 16584,
      "##ony": 16585,
      "hailed": 16586,
      "filmmakers": 16587,
      "trance": 16588,
      "caldwell": 16589,
      "skye": 16590,
      "unrest": 16591,
      "coward": 16592,
      "likelihood": 16593,
      "##aging": 16594,
      "bern": 16595,
      "sci": 16596,
      "taliban": 16597,
      "honolulu": 16598,
      "propose": 16599,
      "##wang": 16600,
      "1700": 16601,
      "browser": 16602,
      "imagining": 16603,
      "cobra": 16604,
      "contributes": 16605,
      "dukes": 16606,
      "instinctively": 16607,
      "conan": 16608,
      "violinist": 16609,
      "##ores": 16610,
      "accessories": 16611,
      "gradual": 16612,
      "##amp": 16613,
      "quotes": 16614,
      "sioux": 16615,
      "##dating": 16616,
      "undertake": 16617,
      "intercepted": 16618,
      "sparkling": 16619,
      "compressed": 16620,
      "139": 16621,
      "fungus": 16622,
      "tombs": 16623,
      "haley": 16624,
      "imposing": 16625,
      "rests": 16626,
      "degradation": 16627,
      "lincolnshire": 16628,
      "retailers": 16629,
      "wetlands": 16630,
      "tulsa": 16631,
      "distributor": 16632,
      "dungeon": 16633,
      "nun": 16634,
      "greenhouse": 16635,
      "convey": 16636,
      "atlantis": 16637,
      "aft": 16638,
      "exits": 16639,
      "oman": 16640,
      "dresser": 16641,
      "lyons": 16642,
      "##sti": 16643,
      "joking": 16644,
      "eddy": 16645,
      "judgement": 16646,
      "omitted": 16647,
      "digits": 16648,
      "##cts": 16649,
      "##game": 16650,
      "juniors": 16651,
      "##rae": 16652,
      "cents": 16653,
      "stricken": 16654,
      "une": 16655,
      "##ngo": 16656,
      "wizards": 16657,
      "weir": 16658,
      "breton": 16659,
      "nan": 16660,
      "technician": 16661,
      "fibers": 16662,
      "liking": 16663,
      "royalty": 16664,
      "##cca": 16665,
      "154": 16666,
      "persia": 16667,
      "terribly": 16668,
      "magician": 16669,
      "##rable": 16670,
      "##unt": 16671,
      "vance": 16672,
      "cafeteria": 16673,
      "booker": 16674,
      "camille": 16675,
      "warmer": 16676,
      "##static": 16677,
      "consume": 16678,
      "cavern": 16679,
      "gaps": 16680,
      "compass": 16681,
      "contemporaries": 16682,
      "foyer": 16683,
      "soothing": 16684,
      "graveyard": 16685,
      "maj": 16686,
      "plunged": 16687,
      "blush": 16688,
      "##wear": 16689,
      "cascade": 16690,
      "demonstrates": 16691,
      "ordinance": 16692,
      "##nov": 16693,
      "boyle": 16694,
      "##lana": 16695,
      "rockefeller": 16696,
      "shaken": 16697,
      "banjo": 16698,
      "izzy": 16699,
      "##ense": 16700,
      "breathless": 16701,
      "vines": 16702,
      "##32": 16703,
      "##eman": 16704,
      "alterations": 16705,
      "chromosome": 16706,
      "dwellings": 16707,
      "feudal": 16708,
      "mole": 16709,
      "153": 16710,
      "catalonia": 16711,
      "relics": 16712,
      "tenant": 16713,
      "mandated": 16714,
      "##fm": 16715,
      "fridge": 16716,
      "hats": 16717,
      "honesty": 16718,
      "patented": 16719,
      "raul": 16720,
      "heap": 16721,
      "cruisers": 16722,
      "accusing": 16723,
      "enlightenment": 16724,
      "infants": 16725,
      "wherein": 16726,
      "chatham": 16727,
      "contractors": 16728,
      "zen": 16729,
      "affinity": 16730,
      "hc": 16731,
      "osborne": 16732,
      "piston": 16733,
      "156": 16734,
      "traps": 16735,
      "maturity": 16736,
      "##rana": 16737,
      "lagos": 16738,
      "##zal": 16739,
      "peering": 16740,
      "##nay": 16741,
      "attendant": 16742,
      "dealers": 16743,
      "protocols": 16744,
      "subset": 16745,
      "prospects": 16746,
      "biographical": 16747,
      "##cre": 16748,
      "artery": 16749,
      "##zers": 16750,
      "insignia": 16751,
      "nuns": 16752,
      "endured": 16753,
      "##eration": 16754,
      "recommend": 16755,
      "schwartz": 16756,
      "serbs": 16757,
      "berger": 16758,
      "cromwell": 16759,
      "crossroads": 16760,
      "##ctor": 16761,
      "enduring": 16762,
      "clasped": 16763,
      "grounded": 16764,
      "##bine": 16765,
      "marseille": 16766,
      "twitched": 16767,
      "abel": 16768,
      "choke": 16769,
      "https": 16770,
      "catalyst": 16771,
      "moldova": 16772,
      "italians": 16773,
      "##tist": 16774,
      "disastrous": 16775,
      "wee": 16776,
      "##oured": 16777,
      "##nti": 16778,
      "wwf": 16779,
      "nope": 16780,
      "##piration": 16781,
      "##asa": 16782,
      "expresses": 16783,
      "thumbs": 16784,
      "167": 16785,
      "##nza": 16786,
      "coca": 16787,
      "1781": 16788,
      "cheating": 16789,
      "##ption": 16790,
      "skipped": 16791,
      "sensory": 16792,
      "heidelberg": 16793,
      "spies": 16794,
      "satan": 16795,
      "dangers": 16796,
      "semifinal": 16797,
      "202": 16798,
      "bohemia": 16799,
      "whitish": 16800,
      "confusing": 16801,
      "shipbuilding": 16802,
      "relies": 16803,
      "surgeons": 16804,
      "landings": 16805,
      "ravi": 16806,
      "baku": 16807,
      "moor": 16808,
      "suffix": 16809,
      "alejandro": 16810,
      "##yana": 16811,
      "litre": 16812,
      "upheld": 16813,
      "##unk": 16814,
      "rajasthan": 16815,
      "##rek": 16816,
      "coaster": 16817,
      "insists": 16818,
      "posture": 16819,
      "scenarios": 16820,
      "etienne": 16821,
      "favoured": 16822,
      "appoint": 16823,
      "transgender": 16824,
      "elephants": 16825,
      "poked": 16826,
      "greenwood": 16827,
      "defences": 16828,
      "fulfilled": 16829,
      "militant": 16830,
      "somali": 16831,
      "1758": 16832,
      "chalk": 16833,
      "potent": 16834,
      "##ucci": 16835,
      "migrants": 16836,
      "wink": 16837,
      "assistants": 16838,
      "nos": 16839,
      "restriction": 16840,
      "activism": 16841,
      "niger": 16842,
      "##ario": 16843,
      "colon": 16844,
      "shaun": 16845,
      "##sat": 16846,
      "daphne": 16847,
      "##erated": 16848,
      "swam": 16849,
      "congregations": 16850,
      "reprise": 16851,
      "considerations": 16852,
      "magnet": 16853,
      "playable": 16854,
      "xvi": 16855,
      "##р": 16856,
      "overthrow": 16857,
      "tobias": 16858,
      "knob": 16859,
      "chavez": 16860,
      "coding": 16861,
      "##mers": 16862,
      "propped": 16863,
      "katrina": 16864,
      "orient": 16865,
      "newcomer": 16866,
      "##suke": 16867,
      "temperate": 16868,
      "##pool": 16869,
      "farmhouse": 16870,
      "interrogation": 16871,
      "##vd": 16872,
      "committing": 16873,
      "##vert": 16874,
      "forthcoming": 16875,
      "strawberry": 16876,
      "joaquin": 16877,
      "macau": 16878,
      "ponds": 16879,
      "shocking": 16880,
      "siberia": 16881,
      "##cellular": 16882,
      "chant": 16883,
      "contributors": 16884,
      "##nant": 16885,
      "##ologists": 16886,
      "sped": 16887,
      "absorb": 16888,
      "hail": 16889,
      "1782": 16890,
      "spared": 16891,
      "##hore": 16892,
      "barbados": 16893,
      "karate": 16894,
      "opus": 16895,
      "originates": 16896,
      "saul": 16897,
      "##xie": 16898,
      "evergreen": 16899,
      "leaped": 16900,
      "##rock": 16901,
      "correlation": 16902,
      "exaggerated": 16903,
      "weekday": 16904,
      "unification": 16905,
      "bump": 16906,
      "tracing": 16907,
      "brig": 16908,
      "afb": 16909,
      "pathways": 16910,
      "utilizing": 16911,
      "##ners": 16912,
      "mod": 16913,
      "mb": 16914,
      "disturbance": 16915,
      "kneeling": 16916,
      "##stad": 16917,
      "##guchi": 16918,
      "100th": 16919,
      "pune": 16920,
      "##thy": 16921,
      "decreasing": 16922,
      "168": 16923,
      "manipulation": 16924,
      "miriam": 16925,
      "academia": 16926,
      "ecosystem": 16927,
      "occupational": 16928,
      "rbi": 16929,
      "##lem": 16930,
      "rift": 16931,
      "##14": 16932,
      "rotary": 16933,
      "stacked": 16934,
      "incorporation": 16935,
      "awakening": 16936,
      "generators": 16937,
      "guerrero": 16938,
      "racist": 16939,
      "##omy": 16940,
      "cyber": 16941,
      "derivatives": 16942,
      "culminated": 16943,
      "allie": 16944,
      "annals": 16945,
      "panzer": 16946,
      "sainte": 16947,
      "wikipedia": 16948,
      "pops": 16949,
      "zu": 16950,
      "austro": 16951,
      "##vate": 16952,
      "algerian": 16953,
      "politely": 16954,
      "nicholson": 16955,
      "mornings": 16956,
      "educate": 16957,
      "tastes": 16958,
      "thrill": 16959,
      "dartmouth": 16960,
      "##gating": 16961,
      "db": 16962,
      "##jee": 16963,
      "regan": 16964,
      "differing": 16965,
      "concentrating": 16966,
      "choreography": 16967,
      "divinity": 16968,
      "##media": 16969,
      "pledged": 16970,
      "alexandre": 16971,
      "routing": 16972,
      "gregor": 16973,
      "madeline": 16974,
      "##idal": 16975,
      "apocalypse": 16976,
      "##hora": 16977,
      "gunfire": 16978,
      "culminating": 16979,
      "elves": 16980,
      "fined": 16981,
      "liang": 16982,
      "lam": 16983,
      "programmed": 16984,
      "tar": 16985,
      "guessing": 16986,
      "transparency": 16987,
      "gabrielle": 16988,
      "##gna": 16989,
      "cancellation": 16990,
      "flexibility": 16991,
      "##lining": 16992,
      "accession": 16993,
      "shea": 16994,
      "stronghold": 16995,
      "nets": 16996,
      "specializes": 16997,
      "##rgan": 16998,
      "abused": 16999,
      "hasan": 17000,
      "sgt": 17001,
      "ling": 17002,
      "exceeding": 17003,
      "##₄": 17004,
      "admiration": 17005,
      "supermarket": 17006,
      "##ark": 17007,
      "photographers": 17008,
      "specialised": 17009,
      "tilt": 17010,
      "resonance": 17011,
      "hmm": 17012,
      "perfume": 17013,
      "380": 17014,
      "sami": 17015,
      "threatens": 17016,
      "garland": 17017,
      "botany": 17018,
      "guarding": 17019,
      "boiled": 17020,
      "greet": 17021,
      "puppy": 17022,
      "russo": 17023,
      "supplier": 17024,
      "wilmington": 17025,
      "vibrant": 17026,
      "vijay": 17027,
      "##bius": 17028,
      "paralympic": 17029,
      "grumbled": 17030,
      "paige": 17031,
      "faa": 17032,
      "licking": 17033,
      "margins": 17034,
      "hurricanes": 17035,
      "##gong": 17036,
      "fest": 17037,
      "grenade": 17038,
      "ripping": 17039,
      "##uz": 17040,
      "counseling": 17041,
      "weigh": 17042,
      "##sian": 17043,
      "needles": 17044,
      "wiltshire": 17045,
      "edison": 17046,
      "costly": 17047,
      "##not": 17048,
      "fulton": 17049,
      "tramway": 17050,
      "redesigned": 17051,
      "staffordshire": 17052,
      "cache": 17053,
      "gasping": 17054,
      "watkins": 17055,
      "sleepy": 17056,
      "candidacy": 17057,
      "##group": 17058,
      "monkeys": 17059,
      "timeline": 17060,
      "throbbing": 17061,
      "##bid": 17062,
      "##sos": 17063,
      "berth": 17064,
      "uzbekistan": 17065,
      "vanderbilt": 17066,
      "bothering": 17067,
      "overturned": 17068,
      "ballots": 17069,
      "gem": 17070,
      "##iger": 17071,
      "sunglasses": 17072,
      "subscribers": 17073,
      "hooker": 17074,
      "compelling": 17075,
      "ang": 17076,
      "exceptionally": 17077,
      "saloon": 17078,
      "stab": 17079,
      "##rdi": 17080,
      "carla": 17081,
      "terrifying": 17082,
      "rom": 17083,
      "##vision": 17084,
      "coil": 17085,
      "##oids": 17086,
      "satisfying": 17087,
      "vendors": 17088,
      "31st": 17089,
      "mackay": 17090,
      "deities": 17091,
      "overlooked": 17092,
      "ambient": 17093,
      "bahamas": 17094,
      "felipe": 17095,
      "olympia": 17096,
      "whirled": 17097,
      "botanist": 17098,
      "advertised": 17099,
      "tugging": 17100,
      "##dden": 17101,
      "disciples": 17102,
      "morales": 17103,
      "unionist": 17104,
      "rites": 17105,
      "foley": 17106,
      "morse": 17107,
      "motives": 17108,
      "creepy": 17109,
      "##₀": 17110,
      "soo": 17111,
      "##sz": 17112,
      "bargain": 17113,
      "highness": 17114,
      "frightening": 17115,
      "turnpike": 17116,
      "tory": 17117,
      "reorganization": 17118,
      "##cer": 17119,
      "depict": 17120,
      "biographer": 17121,
      "##walk": 17122,
      "unopposed": 17123,
      "manifesto": 17124,
      "##gles": 17125,
      "institut": 17126,
      "emile": 17127,
      "accidental": 17128,
      "kapoor": 17129,
      "##dam": 17130,
      "kilkenny": 17131,
      "cortex": 17132,
      "lively": 17133,
      "##13": 17134,
      "romanesque": 17135,
      "jain": 17136,
      "shan": 17137,
      "cannons": 17138,
      "##ood": 17139,
      "##ske": 17140,
      "petrol": 17141,
      "echoing": 17142,
      "amalgamated": 17143,
      "disappears": 17144,
      "cautious": 17145,
      "proposes": 17146,
      "sanctions": 17147,
      "trenton": 17148,
      "##ر": 17149,
      "flotilla": 17150,
      "aus": 17151,
      "contempt": 17152,
      "tor": 17153,
      "canary": 17154,
      "cote": 17155,
      "theirs": 17156,
      "##hun": 17157,
      "conceptual": 17158,
      "deleted": 17159,
      "fascinating": 17160,
      "paso": 17161,
      "blazing": 17162,
      "elf": 17163,
      "honourable": 17164,
      "hutchinson": 17165,
      "##eiro": 17166,
      "##outh": 17167,
      "##zin": 17168,
      "surveyor": 17169,
      "tee": 17170,
      "amidst": 17171,
      "wooded": 17172,
      "reissue": 17173,
      "intro": 17174,
      "##ono": 17175,
      "cobb": 17176,
      "shelters": 17177,
      "newsletter": 17178,
      "hanson": 17179,
      "brace": 17180,
      "encoding": 17181,
      "confiscated": 17182,
      "dem": 17183,
      "caravan": 17184,
      "marino": 17185,
      "scroll": 17186,
      "melodic": 17187,
      "cows": 17188,
      "imam": 17189,
      "##adi": 17190,
      "##aneous": 17191,
      "northward": 17192,
      "searches": 17193,
      "biodiversity": 17194,
      "cora": 17195,
      "310": 17196,
      "roaring": 17197,
      "##bers": 17198,
      "connell": 17199,
      "theologian": 17200,
      "halo": 17201,
      "compose": 17202,
      "pathetic": 17203,
      "unmarried": 17204,
      "dynamo": 17205,
      "##oot": 17206,
      "az": 17207,
      "calculation": 17208,
      "toulouse": 17209,
      "deserves": 17210,
      "humour": 17211,
      "nr": 17212,
      "forgiveness": 17213,
      "tam": 17214,
      "undergone": 17215,
      "martyr": 17216,
      "pamela": 17217,
      "myths": 17218,
      "whore": 17219,
      "counselor": 17220,
      "hicks": 17221,
      "290": 17222,
      "heavens": 17223,
      "battleship": 17224,
      "electromagnetic": 17225,
      "##bbs": 17226,
      "stellar": 17227,
      "establishments": 17228,
      "presley": 17229,
      "hopped": 17230,
      "##chin": 17231,
      "temptation": 17232,
      "90s": 17233,
      "wills": 17234,
      "nas": 17235,
      "##yuan": 17236,
      "nhs": 17237,
      "##nya": 17238,
      "seminars": 17239,
      "##yev": 17240,
      "adaptations": 17241,
      "gong": 17242,
      "asher": 17243,
      "lex": 17244,
      "indicator": 17245,
      "sikh": 17246,
      "tobago": 17247,
      "cites": 17248,
      "goin": 17249,
      "##yte": 17250,
      "satirical": 17251,
      "##gies": 17252,
      "characterised": 17253,
      "correspond": 17254,
      "bubbles": 17255,
      "lure": 17256,
      "participates": 17257,
      "##vid": 17258,
      "eruption": 17259,
      "skate": 17260,
      "therapeutic": 17261,
      "1785": 17262,
      "canals": 17263,
      "wholesale": 17264,
      "defaulted": 17265,
      "sac": 17266,
      "460": 17267,
      "petit": 17268,
      "##zzled": 17269,
      "virgil": 17270,
      "leak": 17271,
      "ravens": 17272,
      "256": 17273,
      "portraying": 17274,
      "##yx": 17275,
      "ghetto": 17276,
      "creators": 17277,
      "dams": 17278,
      "portray": 17279,
      "vicente": 17280,
      "##rington": 17281,
      "fae": 17282,
      "namesake": 17283,
      "bounty": 17284,
      "##arium": 17285,
      "joachim": 17286,
      "##ota": 17287,
      "##iser": 17288,
      "aforementioned": 17289,
      "axle": 17290,
      "snout": 17291,
      "depended": 17292,
      "dismantled": 17293,
      "reuben": 17294,
      "480": 17295,
      "##ibly": 17296,
      "gallagher": 17297,
      "##lau": 17298,
      "##pd": 17299,
      "earnest": 17300,
      "##ieu": 17301,
      "##iary": 17302,
      "inflicted": 17303,
      "objections": 17304,
      "##llar": 17305,
      "asa": 17306,
      "gritted": 17307,
      "##athy": 17308,
      "jericho": 17309,
      "##sea": 17310,
      "##was": 17311,
      "flick": 17312,
      "underside": 17313,
      "ceramics": 17314,
      "undead": 17315,
      "substituted": 17316,
      "195": 17317,
      "eastward": 17318,
      "undoubtedly": 17319,
      "wheeled": 17320,
      "chimney": 17321,
      "##iche": 17322,
      "guinness": 17323,
      "cb": 17324,
      "##ager": 17325,
      "siding": 17326,
      "##bell": 17327,
      "traitor": 17328,
      "baptiste": 17329,
      "disguised": 17330,
      "inauguration": 17331,
      "149": 17332,
      "tipperary": 17333,
      "choreographer": 17334,
      "perched": 17335,
      "warmed": 17336,
      "stationary": 17337,
      "eco": 17338,
      "##ike": 17339,
      "##ntes": 17340,
      "bacterial": 17341,
      "##aurus": 17342,
      "flores": 17343,
      "phosphate": 17344,
      "##core": 17345,
      "attacker": 17346,
      "invaders": 17347,
      "alvin": 17348,
      "intersects": 17349,
      "a1": 17350,
      "indirectly": 17351,
      "immigrated": 17352,
      "businessmen": 17353,
      "cornelius": 17354,
      "valves": 17355,
      "narrated": 17356,
      "pill": 17357,
      "sober": 17358,
      "ul": 17359,
      "nationale": 17360,
      "monastic": 17361,
      "applicants": 17362,
      "scenery": 17363,
      "##jack": 17364,
      "161": 17365,
      "motifs": 17366,
      "constitutes": 17367,
      "cpu": 17368,
      "##osh": 17369,
      "jurisdictions": 17370,
      "sd": 17371,
      "tuning": 17372,
      "irritation": 17373,
      "woven": 17374,
      "##uddin": 17375,
      "fertility": 17376,
      "gao": 17377,
      "##erie": 17378,
      "antagonist": 17379,
      "impatient": 17380,
      "glacial": 17381,
      "hides": 17382,
      "boarded": 17383,
      "denominations": 17384,
      "interception": 17385,
      "##jas": 17386,
      "cookie": 17387,
      "nicola": 17388,
      "##tee": 17389,
      "algebraic": 17390,
      "marquess": 17391,
      "bahn": 17392,
      "parole": 17393,
      "buyers": 17394,
      "bait": 17395,
      "turbines": 17396,
      "paperwork": 17397,
      "bestowed": 17398,
      "natasha": 17399,
      "renee": 17400,
      "oceans": 17401,
      "purchases": 17402,
      "157": 17403,
      "vaccine": 17404,
      "215": 17405,
      "##tock": 17406,
      "fixtures": 17407,
      "playhouse": 17408,
      "integrate": 17409,
      "jai": 17410,
      "oswald": 17411,
      "intellectuals": 17412,
      "##cky": 17413,
      "booked": 17414,
      "nests": 17415,
      "mortimer": 17416,
      "##isi": 17417,
      "obsession": 17418,
      "sept": 17419,
      "##gler": 17420,
      "##sum": 17421,
      "440": 17422,
      "scrutiny": 17423,
      "simultaneous": 17424,
      "squinted": 17425,
      "##shin": 17426,
      "collects": 17427,
      "oven": 17428,
      "shankar": 17429,
      "penned": 17430,
      "remarkably": 17431,
      "##я": 17432,
      "slips": 17433,
      "luggage": 17434,
      "spectral": 17435,
      "1786": 17436,
      "collaborations": 17437,
      "louie": 17438,
      "consolidation": 17439,
      "##ailed": 17440,
      "##ivating": 17441,
      "420": 17442,
      "hoover": 17443,
      "blackpool": 17444,
      "harness": 17445,
      "ignition": 17446,
      "vest": 17447,
      "tails": 17448,
      "belmont": 17449,
      "mongol": 17450,
      "skinner": 17451,
      "##nae": 17452,
      "visually": 17453,
      "mage": 17454,
      "derry": 17455,
      "##tism": 17456,
      "##unce": 17457,
      "stevie": 17458,
      "transitional": 17459,
      "##rdy": 17460,
      "redskins": 17461,
      "drying": 17462,
      "prep": 17463,
      "prospective": 17464,
      "##21": 17465,
      "annoyance": 17466,
      "oversee": 17467,
      "##loaded": 17468,
      "fills": 17469,
      "##books": 17470,
      "##iki": 17471,
      "announces": 17472,
      "fda": 17473,
      "scowled": 17474,
      "respects": 17475,
      "prasad": 17476,
      "mystic": 17477,
      "tucson": 17478,
      "##vale": 17479,
      "revue": 17480,
      "springer": 17481,
      "bankrupt": 17482,
      "1772": 17483,
      "aristotle": 17484,
      "salvatore": 17485,
      "habsburg": 17486,
      "##geny": 17487,
      "dal": 17488,
      "natal": 17489,
      "nut": 17490,
      "pod": 17491,
      "chewing": 17492,
      "darts": 17493,
      "moroccan": 17494,
      "walkover": 17495,
      "rosario": 17496,
      "lenin": 17497,
      "punjabi": 17498,
      "##ße": 17499,
      "grossed": 17500,
      "scattering": 17501,
      "wired": 17502,
      "invasive": 17503,
      "hui": 17504,
      "polynomial": 17505,
      "corridors": 17506,
      "wakes": 17507,
      "gina": 17508,
      "portrays": 17509,
      "##cratic": 17510,
      "arid": 17511,
      "retreating": 17512,
      "erich": 17513,
      "irwin": 17514,
      "sniper": 17515,
      "##dha": 17516,
      "linen": 17517,
      "lindsey": 17518,
      "maneuver": 17519,
      "butch": 17520,
      "shutting": 17521,
      "socio": 17522,
      "bounce": 17523,
      "commemorative": 17524,
      "postseason": 17525,
      "jeremiah": 17526,
      "pines": 17527,
      "275": 17528,
      "mystical": 17529,
      "beads": 17530,
      "bp": 17531,
      "abbas": 17532,
      "furnace": 17533,
      "bidding": 17534,
      "consulted": 17535,
      "assaulted": 17536,
      "empirical": 17537,
      "rubble": 17538,
      "enclosure": 17539,
      "sob": 17540,
      "weakly": 17541,
      "cancel": 17542,
      "polly": 17543,
      "yielded": 17544,
      "##emann": 17545,
      "curly": 17546,
      "prediction": 17547,
      "battered": 17548,
      "70s": 17549,
      "vhs": 17550,
      "jacqueline": 17551,
      "render": 17552,
      "sails": 17553,
      "barked": 17554,
      "detailing": 17555,
      "grayson": 17556,
      "riga": 17557,
      "sloane": 17558,
      "raging": 17559,
      "##yah": 17560,
      "herbs": 17561,
      "bravo": 17562,
      "##athlon": 17563,
      "alloy": 17564,
      "giggle": 17565,
      "imminent": 17566,
      "suffers": 17567,
      "assumptions": 17568,
      "waltz": 17569,
      "##itate": 17570,
      "accomplishments": 17571,
      "##ited": 17572,
      "bathing": 17573,
      "remixed": 17574,
      "deception": 17575,
      "prefix": 17576,
      "##emia": 17577,
      "deepest": 17578,
      "##tier": 17579,
      "##eis": 17580,
      "balkan": 17581,
      "frogs": 17582,
      "##rong": 17583,
      "slab": 17584,
      "##pate": 17585,
      "philosophers": 17586,
      "peterborough": 17587,
      "grains": 17588,
      "imports": 17589,
      "dickinson": 17590,
      "rwanda": 17591,
      "##atics": 17592,
      "1774": 17593,
      "dirk": 17594,
      "lan": 17595,
      "tablets": 17596,
      "##rove": 17597,
      "clone": 17598,
      "##rice": 17599,
      "caretaker": 17600,
      "hostilities": 17601,
      "mclean": 17602,
      "##gre": 17603,
      "regimental": 17604,
      "treasures": 17605,
      "norms": 17606,
      "impose": 17607,
      "tsar": 17608,
      "tango": 17609,
      "diplomacy": 17610,
      "variously": 17611,
      "complain": 17612,
      "192": 17613,
      "recognise": 17614,
      "arrests": 17615,
      "1779": 17616,
      "celestial": 17617,
      "pulitzer": 17618,
      "##dus": 17619,
      "bing": 17620,
      "libretto": 17621,
      "##moor": 17622,
      "adele": 17623,
      "splash": 17624,
      "##rite": 17625,
      "expectation": 17626,
      "lds": 17627,
      "confronts": 17628,
      "##izer": 17629,
      "spontaneous": 17630,
      "harmful": 17631,
      "wedge": 17632,
      "entrepreneurs": 17633,
      "buyer": 17634,
      "##ope": 17635,
      "bilingual": 17636,
      "translate": 17637,
      "rugged": 17638,
      "conner": 17639,
      "circulated": 17640,
      "uae": 17641,
      "eaton": 17642,
      "##gra": 17643,
      "##zzle": 17644,
      "lingered": 17645,
      "lockheed": 17646,
      "vishnu": 17647,
      "reelection": 17648,
      "alonso": 17649,
      "##oom": 17650,
      "joints": 17651,
      "yankee": 17652,
      "headline": 17653,
      "cooperate": 17654,
      "heinz": 17655,
      "laureate": 17656,
      "invading": 17657,
      "##sford": 17658,
      "echoes": 17659,
      "scandinavian": 17660,
      "##dham": 17661,
      "hugging": 17662,
      "vitamin": 17663,
      "salute": 17664,
      "micah": 17665,
      "hind": 17666,
      "trader": 17667,
      "##sper": 17668,
      "radioactive": 17669,
      "##ndra": 17670,
      "militants": 17671,
      "poisoned": 17672,
      "ratified": 17673,
      "remark": 17674,
      "campeonato": 17675,
      "deprived": 17676,
      "wander": 17677,
      "prop": 17678,
      "##dong": 17679,
      "outlook": 17680,
      "##tani": 17681,
      "##rix": 17682,
      "##eye": 17683,
      "chiang": 17684,
      "darcy": 17685,
      "##oping": 17686,
      "mandolin": 17687,
      "spice": 17688,
      "statesman": 17689,
      "babylon": 17690,
      "182": 17691,
      "walled": 17692,
      "forgetting": 17693,
      "afro": 17694,
      "##cap": 17695,
      "158": 17696,
      "giorgio": 17697,
      "buffer": 17698,
      "##polis": 17699,
      "planetary": 17700,
      "##gis": 17701,
      "overlap": 17702,
      "terminals": 17703,
      "kinda": 17704,
      "centenary": 17705,
      "##bir": 17706,
      "arising": 17707,
      "manipulate": 17708,
      "elm": 17709,
      "ke": 17710,
      "1770": 17711,
      "ak": 17712,
      "##tad": 17713,
      "chrysler": 17714,
      "mapped": 17715,
      "moose": 17716,
      "pomeranian": 17717,
      "quad": 17718,
      "macarthur": 17719,
      "assemblies": 17720,
      "shoreline": 17721,
      "recalls": 17722,
      "stratford": 17723,
      "##rted": 17724,
      "noticeable": 17725,
      "##evic": 17726,
      "imp": 17727,
      "##rita": 17728,
      "##sque": 17729,
      "accustomed": 17730,
      "supplying": 17731,
      "tents": 17732,
      "disgusted": 17733,
      "vogue": 17734,
      "sipped": 17735,
      "filters": 17736,
      "khz": 17737,
      "reno": 17738,
      "selecting": 17739,
      "luftwaffe": 17740,
      "mcmahon": 17741,
      "tyne": 17742,
      "masterpiece": 17743,
      "carriages": 17744,
      "collided": 17745,
      "dunes": 17746,
      "exercised": 17747,
      "flare": 17748,
      "remembers": 17749,
      "muzzle": 17750,
      "##mobile": 17751,
      "heck": 17752,
      "##rson": 17753,
      "burgess": 17754,
      "lunged": 17755,
      "middleton": 17756,
      "boycott": 17757,
      "bilateral": 17758,
      "##sity": 17759,
      "hazardous": 17760,
      "lumpur": 17761,
      "multiplayer": 17762,
      "spotlight": 17763,
      "jackets": 17764,
      "goldman": 17765,
      "liege": 17766,
      "porcelain": 17767,
      "rag": 17768,
      "waterford": 17769,
      "benz": 17770,
      "attracts": 17771,
      "hopeful": 17772,
      "battling": 17773,
      "ottomans": 17774,
      "kensington": 17775,
      "baked": 17776,
      "hymns": 17777,
      "cheyenne": 17778,
      "lattice": 17779,
      "levine": 17780,
      "borrow": 17781,
      "polymer": 17782,
      "clashes": 17783,
      "michaels": 17784,
      "monitored": 17785,
      "commitments": 17786,
      "denounced": 17787,
      "##25": 17788,
      "##von": 17789,
      "cavity": 17790,
      "##oney": 17791,
      "hobby": 17792,
      "akin": 17793,
      "##holders": 17794,
      "futures": 17795,
      "intricate": 17796,
      "cornish": 17797,
      "patty": 17798,
      "##oned": 17799,
      "illegally": 17800,
      "dolphin": 17801,
      "##lag": 17802,
      "barlow": 17803,
      "yellowish": 17804,
      "maddie": 17805,
      "apologized": 17806,
      "luton": 17807,
      "plagued": 17808,
      "##puram": 17809,
      "nana": 17810,
      "##rds": 17811,
      "sway": 17812,
      "fanny": 17813,
      "łodz": 17814,
      "##rino": 17815,
      "psi": 17816,
      "suspicions": 17817,
      "hanged": 17818,
      "##eding": 17819,
      "initiate": 17820,
      "charlton": 17821,
      "##por": 17822,
      "nak": 17823,
      "competent": 17824,
      "235": 17825,
      "analytical": 17826,
      "annex": 17827,
      "wardrobe": 17828,
      "reservations": 17829,
      "##rma": 17830,
      "sect": 17831,
      "162": 17832,
      "fairfax": 17833,
      "hedge": 17834,
      "piled": 17835,
      "buckingham": 17836,
      "uneven": 17837,
      "bauer": 17838,
      "simplicity": 17839,
      "snyder": 17840,
      "interpret": 17841,
      "accountability": 17842,
      "donors": 17843,
      "moderately": 17844,
      "byrd": 17845,
      "continents": 17846,
      "##cite": 17847,
      "##max": 17848,
      "disciple": 17849,
      "hr": 17850,
      "jamaican": 17851,
      "ping": 17852,
      "nominees": 17853,
      "##uss": 17854,
      "mongolian": 17855,
      "diver": 17856,
      "attackers": 17857,
      "eagerly": 17858,
      "ideological": 17859,
      "pillows": 17860,
      "miracles": 17861,
      "apartheid": 17862,
      "revolver": 17863,
      "sulfur": 17864,
      "clinics": 17865,
      "moran": 17866,
      "163": 17867,
      "##enko": 17868,
      "ile": 17869,
      "katy": 17870,
      "rhetoric": 17871,
      "##icated": 17872,
      "chronology": 17873,
      "recycling": 17874,
      "##hrer": 17875,
      "elongated": 17876,
      "mughal": 17877,
      "pascal": 17878,
      "profiles": 17879,
      "vibration": 17880,
      "databases": 17881,
      "domination": 17882,
      "##fare": 17883,
      "##rant": 17884,
      "matthias": 17885,
      "digest": 17886,
      "rehearsal": 17887,
      "polling": 17888,
      "weiss": 17889,
      "initiation": 17890,
      "reeves": 17891,
      "clinging": 17892,
      "flourished": 17893,
      "impress": 17894,
      "ngo": 17895,
      "##hoff": 17896,
      "##ume": 17897,
      "buckley": 17898,
      "symposium": 17899,
      "rhythms": 17900,
      "weed": 17901,
      "emphasize": 17902,
      "transforming": 17903,
      "##taking": 17904,
      "##gence": 17905,
      "##yman": 17906,
      "accountant": 17907,
      "analyze": 17908,
      "flicker": 17909,
      "foil": 17910,
      "priesthood": 17911,
      "voluntarily": 17912,
      "decreases": 17913,
      "##80": 17914,
      "##hya": 17915,
      "slater": 17916,
      "sv": 17917,
      "charting": 17918,
      "mcgill": 17919,
      "##lde": 17920,
      "moreno": 17921,
      "##iu": 17922,
      "besieged": 17923,
      "zur": 17924,
      "robes": 17925,
      "##phic": 17926,
      "admitting": 17927,
      "api": 17928,
      "deported": 17929,
      "turmoil": 17930,
      "peyton": 17931,
      "earthquakes": 17932,
      "##ares": 17933,
      "nationalists": 17934,
      "beau": 17935,
      "clair": 17936,
      "brethren": 17937,
      "interrupt": 17938,
      "welch": 17939,
      "curated": 17940,
      "galerie": 17941,
      "requesting": 17942,
      "164": 17943,
      "##ested": 17944,
      "impending": 17945,
      "steward": 17946,
      "viper": 17947,
      "##vina": 17948,
      "complaining": 17949,
      "beautifully": 17950,
      "brandy": 17951,
      "foam": 17952,
      "nl": 17953,
      "1660": 17954,
      "##cake": 17955,
      "alessandro": 17956,
      "punches": 17957,
      "laced": 17958,
      "explanations": 17959,
      "##lim": 17960,
      "attribute": 17961,
      "clit": 17962,
      "reggie": 17963,
      "discomfort": 17964,
      "##cards": 17965,
      "smoothed": 17966,
      "whales": 17967,
      "##cene": 17968,
      "adler": 17969,
      "countered": 17970,
      "duffy": 17971,
      "disciplinary": 17972,
      "widening": 17973,
      "recipe": 17974,
      "reliance": 17975,
      "conducts": 17976,
      "goats": 17977,
      "gradient": 17978,
      "preaching": 17979,
      "##shaw": 17980,
      "matilda": 17981,
      "quasi": 17982,
      "striped": 17983,
      "meridian": 17984,
      "cannabis": 17985,
      "cordoba": 17986,
      "certificates": 17987,
      "##agh": 17988,
      "##tering": 17989,
      "graffiti": 17990,
      "hangs": 17991,
      "pilgrims": 17992,
      "repeats": 17993,
      "##ych": 17994,
      "revive": 17995,
      "urine": 17996,
      "etat": 17997,
      "##hawk": 17998,
      "fueled": 17999,
      "belts": 18000,
      "fuzzy": 18001,
      "susceptible": 18002,
      "##hang": 18003,
      "mauritius": 18004,
      "salle": 18005,
      "sincere": 18006,
      "beers": 18007,
      "hooks": 18008,
      "##cki": 18009,
      "arbitration": 18010,
      "entrusted": 18011,
      "advise": 18012,
      "sniffed": 18013,
      "seminar": 18014,
      "junk": 18015,
      "donnell": 18016,
      "processors": 18017,
      "principality": 18018,
      "strapped": 18019,
      "celia": 18020,
      "mendoza": 18021,
      "everton": 18022,
      "fortunes": 18023,
      "prejudice": 18024,
      "starving": 18025,
      "reassigned": 18026,
      "steamer": 18027,
      "##lund": 18028,
      "tuck": 18029,
      "evenly": 18030,
      "foreman": 18031,
      "##ffen": 18032,
      "dans": 18033,
      "375": 18034,
      "envisioned": 18035,
      "slit": 18036,
      "##xy": 18037,
      "baseman": 18038,
      "liberia": 18039,
      "rosemary": 18040,
      "##weed": 18041,
      "electrified": 18042,
      "periodically": 18043,
      "potassium": 18044,
      "stride": 18045,
      "contexts": 18046,
      "sperm": 18047,
      "slade": 18048,
      "mariners": 18049,
      "influx": 18050,
      "bianca": 18051,
      "subcommittee": 18052,
      "##rane": 18053,
      "spilling": 18054,
      "icao": 18055,
      "estuary": 18056,
      "##nock": 18057,
      "delivers": 18058,
      "iphone": 18059,
      "##ulata": 18060,
      "isa": 18061,
      "mira": 18062,
      "bohemian": 18063,
      "dessert": 18064,
      "##sbury": 18065,
      "welcoming": 18066,
      "proudly": 18067,
      "slowing": 18068,
      "##chs": 18069,
      "musee": 18070,
      "ascension": 18071,
      "russ": 18072,
      "##vian": 18073,
      "waits": 18074,
      "##psy": 18075,
      "africans": 18076,
      "exploit": 18077,
      "##morphic": 18078,
      "gov": 18079,
      "eccentric": 18080,
      "crab": 18081,
      "peck": 18082,
      "##ull": 18083,
      "entrances": 18084,
      "formidable": 18085,
      "marketplace": 18086,
      "groom": 18087,
      "bolted": 18088,
      "metabolism": 18089,
      "patton": 18090,
      "robbins": 18091,
      "courier": 18092,
      "payload": 18093,
      "endure": 18094,
      "##ifier": 18095,
      "andes": 18096,
      "refrigerator": 18097,
      "##pr": 18098,
      "ornate": 18099,
      "##uca": 18100,
      "ruthless": 18101,
      "illegitimate": 18102,
      "masonry": 18103,
      "strasbourg": 18104,
      "bikes": 18105,
      "adobe": 18106,
      "##³": 18107,
      "apples": 18108,
      "quintet": 18109,
      "willingly": 18110,
      "niche": 18111,
      "bakery": 18112,
      "corpses": 18113,
      "energetic": 18114,
      "##cliffe": 18115,
      "##sser": 18116,
      "##ards": 18117,
      "177": 18118,
      "centimeters": 18119,
      "centro": 18120,
      "fuscous": 18121,
      "cretaceous": 18122,
      "rancho": 18123,
      "##yde": 18124,
      "andrei": 18125,
      "telecom": 18126,
      "tottenham": 18127,
      "oasis": 18128,
      "ordination": 18129,
      "vulnerability": 18130,
      "presiding": 18131,
      "corey": 18132,
      "cp": 18133,
      "penguins": 18134,
      "sims": 18135,
      "##pis": 18136,
      "malawi": 18137,
      "piss": 18138,
      "##48": 18139,
      "correction": 18140,
      "##cked": 18141,
      "##ffle": 18142,
      "##ryn": 18143,
      "countdown": 18144,
      "detectives": 18145,
      "psychiatrist": 18146,
      "psychedelic": 18147,
      "dinosaurs": 18148,
      "blouse": 18149,
      "##get": 18150,
      "choi": 18151,
      "vowed": 18152,
      "##oz": 18153,
      "randomly": 18154,
      "##pol": 18155,
      "49ers": 18156,
      "scrub": 18157,
      "blanche": 18158,
      "bruins": 18159,
      "dusseldorf": 18160,
      "##using": 18161,
      "unwanted": 18162,
      "##ums": 18163,
      "212": 18164,
      "dominique": 18165,
      "elevations": 18166,
      "headlights": 18167,
      "om": 18168,
      "laguna": 18169,
      "##oga": 18170,
      "1750": 18171,
      "famously": 18172,
      "ignorance": 18173,
      "shrewsbury": 18174,
      "##aine": 18175,
      "ajax": 18176,
      "breuning": 18177,
      "che": 18178,
      "confederacy": 18179,
      "greco": 18180,
      "overhaul": 18181,
      "##screen": 18182,
      "paz": 18183,
      "skirts": 18184,
      "disagreement": 18185,
      "cruelty": 18186,
      "jagged": 18187,
      "phoebe": 18188,
      "shifter": 18189,
      "hovered": 18190,
      "viruses": 18191,
      "##wes": 18192,
      "mandy": 18193,
      "##lined": 18194,
      "##gc": 18195,
      "landlord": 18196,
      "squirrel": 18197,
      "dashed": 18198,
      "##ι": 18199,
      "ornamental": 18200,
      "gag": 18201,
      "wally": 18202,
      "grange": 18203,
      "literal": 18204,
      "spurs": 18205,
      "undisclosed": 18206,
      "proceeding": 18207,
      "yin": 18208,
      "##text": 18209,
      "billie": 18210,
      "orphan": 18211,
      "spanned": 18212,
      "humidity": 18213,
      "indy": 18214,
      "weighted": 18215,
      "presentations": 18216,
      "explosions": 18217,
      "lucian": 18218,
      "##tary": 18219,
      "vaughn": 18220,
      "hindus": 18221,
      "##anga": 18222,
      "##hell": 18223,
      "psycho": 18224,
      "171": 18225,
      "daytona": 18226,
      "protects": 18227,
      "efficiently": 18228,
      "rematch": 18229,
      "sly": 18230,
      "tandem": 18231,
      "##oya": 18232,
      "rebranded": 18233,
      "impaired": 18234,
      "hee": 18235,
      "metropolis": 18236,
      "peach": 18237,
      "godfrey": 18238,
      "diaspora": 18239,
      "ethnicity": 18240,
      "prosperous": 18241,
      "gleaming": 18242,
      "dar": 18243,
      "grossing": 18244,
      "playback": 18245,
      "##rden": 18246,
      "stripe": 18247,
      "pistols": 18248,
      "##tain": 18249,
      "births": 18250,
      "labelled": 18251,
      "##cating": 18252,
      "172": 18253,
      "rudy": 18254,
      "alba": 18255,
      "##onne": 18256,
      "aquarium": 18257,
      "hostility": 18258,
      "##gb": 18259,
      "##tase": 18260,
      "shudder": 18261,
      "sumatra": 18262,
      "hardest": 18263,
      "lakers": 18264,
      "consonant": 18265,
      "creeping": 18266,
      "demos": 18267,
      "homicide": 18268,
      "capsule": 18269,
      "zeke": 18270,
      "liberties": 18271,
      "expulsion": 18272,
      "pueblo": 18273,
      "##comb": 18274,
      "trait": 18275,
      "transporting": 18276,
      "##ddin": 18277,
      "##neck": 18278,
      "##yna": 18279,
      "depart": 18280,
      "gregg": 18281,
      "mold": 18282,
      "ledge": 18283,
      "hangar": 18284,
      "oldham": 18285,
      "playboy": 18286,
      "termination": 18287,
      "analysts": 18288,
      "gmbh": 18289,
      "romero": 18290,
      "##itic": 18291,
      "insist": 18292,
      "cradle": 18293,
      "filthy": 18294,
      "brightness": 18295,
      "slash": 18296,
      "shootout": 18297,
      "deposed": 18298,
      "bordering": 18299,
      "##truct": 18300,
      "isis": 18301,
      "microwave": 18302,
      "tumbled": 18303,
      "sheltered": 18304,
      "cathy": 18305,
      "werewolves": 18306,
      "messy": 18307,
      "andersen": 18308,
      "convex": 18309,
      "clapped": 18310,
      "clinched": 18311,
      "satire": 18312,
      "wasting": 18313,
      "edo": 18314,
      "vc": 18315,
      "rufus": 18316,
      "##jak": 18317,
      "mont": 18318,
      "##etti": 18319,
      "poznan": 18320,
      "##keeping": 18321,
      "restructuring": 18322,
      "transverse": 18323,
      "##rland": 18324,
      "azerbaijani": 18325,
      "slovene": 18326,
      "gestures": 18327,
      "roommate": 18328,
      "choking": 18329,
      "shear": 18330,
      "##quist": 18331,
      "vanguard": 18332,
      "oblivious": 18333,
      "##hiro": 18334,
      "disagreed": 18335,
      "baptism": 18336,
      "##lich": 18337,
      "coliseum": 18338,
      "##aceae": 18339,
      "salvage": 18340,
      "societe": 18341,
      "cory": 18342,
      "locke": 18343,
      "relocation": 18344,
      "relying": 18345,
      "versailles": 18346,
      "ahl": 18347,
      "swelling": 18348,
      "##elo": 18349,
      "cheerful": 18350,
      "##word": 18351,
      "##edes": 18352,
      "gin": 18353,
      "sarajevo": 18354,
      "obstacle": 18355,
      "diverted": 18356,
      "##nac": 18357,
      "messed": 18358,
      "thoroughbred": 18359,
      "fluttered": 18360,
      "utrecht": 18361,
      "chewed": 18362,
      "acquaintance": 18363,
      "assassins": 18364,
      "dispatch": 18365,
      "mirza": 18366,
      "##wart": 18367,
      "nike": 18368,
      "salzburg": 18369,
      "swell": 18370,
      "yen": 18371,
      "##gee": 18372,
      "idle": 18373,
      "ligue": 18374,
      "samson": 18375,
      "##nds": 18376,
      "##igh": 18377,
      "playful": 18378,
      "spawned": 18379,
      "##cise": 18380,
      "tease": 18381,
      "##case": 18382,
      "burgundy": 18383,
      "##bot": 18384,
      "stirring": 18385,
      "skeptical": 18386,
      "interceptions": 18387,
      "marathi": 18388,
      "##dies": 18389,
      "bedrooms": 18390,
      "aroused": 18391,
      "pinch": 18392,
      "##lik": 18393,
      "preferences": 18394,
      "tattoos": 18395,
      "buster": 18396,
      "digitally": 18397,
      "projecting": 18398,
      "rust": 18399,
      "##ital": 18400,
      "kitten": 18401,
      "priorities": 18402,
      "addison": 18403,
      "pseudo": 18404,
      "##guard": 18405,
      "dusk": 18406,
      "icons": 18407,
      "sermon": 18408,
      "##psis": 18409,
      "##iba": 18410,
      "bt": 18411,
      "##lift": 18412,
      "##xt": 18413,
      "ju": 18414,
      "truce": 18415,
      "rink": 18416,
      "##dah": 18417,
      "##wy": 18418,
      "defects": 18419,
      "psychiatry": 18420,
      "offences": 18421,
      "calculate": 18422,
      "glucose": 18423,
      "##iful": 18424,
      "##rized": 18425,
      "##unda": 18426,
      "francaise": 18427,
      "##hari": 18428,
      "richest": 18429,
      "warwickshire": 18430,
      "carly": 18431,
      "1763": 18432,
      "purity": 18433,
      "redemption": 18434,
      "lending": 18435,
      "##cious": 18436,
      "muse": 18437,
      "bruises": 18438,
      "cerebral": 18439,
      "aero": 18440,
      "carving": 18441,
      "##name": 18442,
      "preface": 18443,
      "terminology": 18444,
      "invade": 18445,
      "monty": 18446,
      "##int": 18447,
      "anarchist": 18448,
      "blurred": 18449,
      "##iled": 18450,
      "rossi": 18451,
      "treats": 18452,
      "guts": 18453,
      "shu": 18454,
      "foothills": 18455,
      "ballads": 18456,
      "undertaking": 18457,
      "premise": 18458,
      "cecilia": 18459,
      "affiliates": 18460,
      "blasted": 18461,
      "conditional": 18462,
      "wilder": 18463,
      "minors": 18464,
      "drone": 18465,
      "rudolph": 18466,
      "buffy": 18467,
      "swallowing": 18468,
      "horton": 18469,
      "attested": 18470,
      "##hop": 18471,
      "rutherford": 18472,
      "howell": 18473,
      "primetime": 18474,
      "livery": 18475,
      "penal": 18476,
      "##bis": 18477,
      "minimize": 18478,
      "hydro": 18479,
      "wrecked": 18480,
      "wrought": 18481,
      "palazzo": 18482,
      "##gling": 18483,
      "cans": 18484,
      "vernacular": 18485,
      "friedman": 18486,
      "nobleman": 18487,
      "shale": 18488,
      "walnut": 18489,
      "danielle": 18490,
      "##ection": 18491,
      "##tley": 18492,
      "sears": 18493,
      "##kumar": 18494,
      "chords": 18495,
      "lend": 18496,
      "flipping": 18497,
      "streamed": 18498,
      "por": 18499,
      "dracula": 18500,
      "gallons": 18501,
      "sacrifices": 18502,
      "gamble": 18503,
      "orphanage": 18504,
      "##iman": 18505,
      "mckenzie": 18506,
      "##gible": 18507,
      "boxers": 18508,
      "daly": 18509,
      "##balls": 18510,
      "##ان": 18511,
      "208": 18512,
      "##ific": 18513,
      "##rative": 18514,
      "##iq": 18515,
      "exploited": 18516,
      "slated": 18517,
      "##uity": 18518,
      "circling": 18519,
      "hillary": 18520,
      "pinched": 18521,
      "goldberg": 18522,
      "provost": 18523,
      "campaigning": 18524,
      "lim": 18525,
      "piles": 18526,
      "ironically": 18527,
      "jong": 18528,
      "mohan": 18529,
      "successors": 18530,
      "usaf": 18531,
      "##tem": 18532,
      "##ught": 18533,
      "autobiographical": 18534,
      "haute": 18535,
      "preserves": 18536,
      "##ending": 18537,
      "acquitted": 18538,
      "comparisons": 18539,
      "203": 18540,
      "hydroelectric": 18541,
      "gangs": 18542,
      "cypriot": 18543,
      "torpedoes": 18544,
      "rushes": 18545,
      "chrome": 18546,
      "derive": 18547,
      "bumps": 18548,
      "instability": 18549,
      "fiat": 18550,
      "pets": 18551,
      "##mbe": 18552,
      "silas": 18553,
      "dye": 18554,
      "reckless": 18555,
      "settler": 18556,
      "##itation": 18557,
      "info": 18558,
      "heats": 18559,
      "##writing": 18560,
      "176": 18561,
      "canonical": 18562,
      "maltese": 18563,
      "fins": 18564,
      "mushroom": 18565,
      "stacy": 18566,
      "aspen": 18567,
      "avid": 18568,
      "##kur": 18569,
      "##loading": 18570,
      "vickers": 18571,
      "gaston": 18572,
      "hillside": 18573,
      "statutes": 18574,
      "wilde": 18575,
      "gail": 18576,
      "kung": 18577,
      "sabine": 18578,
      "comfortably": 18579,
      "motorcycles": 18580,
      "##rgo": 18581,
      "169": 18582,
      "pneumonia": 18583,
      "fetch": 18584,
      "##sonic": 18585,
      "axel": 18586,
      "faintly": 18587,
      "parallels": 18588,
      "##oop": 18589,
      "mclaren": 18590,
      "spouse": 18591,
      "compton": 18592,
      "interdisciplinary": 18593,
      "miner": 18594,
      "##eni": 18595,
      "181": 18596,
      "clamped": 18597,
      "##chal": 18598,
      "##llah": 18599,
      "separates": 18600,
      "versa": 18601,
      "##mler": 18602,
      "scarborough": 18603,
      "labrador": 18604,
      "##lity": 18605,
      "##osing": 18606,
      "rutgers": 18607,
      "hurdles": 18608,
      "como": 18609,
      "166": 18610,
      "burt": 18611,
      "divers": 18612,
      "##100": 18613,
      "wichita": 18614,
      "cade": 18615,
      "coincided": 18616,
      "##erson": 18617,
      "bruised": 18618,
      "mla": 18619,
      "##pper": 18620,
      "vineyard": 18621,
      "##ili": 18622,
      "##brush": 18623,
      "notch": 18624,
      "mentioning": 18625,
      "jase": 18626,
      "hearted": 18627,
      "kits": 18628,
      "doe": 18629,
      "##acle": 18630,
      "pomerania": 18631,
      "##ady": 18632,
      "ronan": 18633,
      "seizure": 18634,
      "pavel": 18635,
      "problematic": 18636,
      "##zaki": 18637,
      "domenico": 18638,
      "##ulin": 18639,
      "catering": 18640,
      "penelope": 18641,
      "dependence": 18642,
      "parental": 18643,
      "emilio": 18644,
      "ministerial": 18645,
      "atkinson": 18646,
      "##bolic": 18647,
      "clarkson": 18648,
      "chargers": 18649,
      "colby": 18650,
      "grill": 18651,
      "peeked": 18652,
      "arises": 18653,
      "summon": 18654,
      "##aged": 18655,
      "fools": 18656,
      "##grapher": 18657,
      "faculties": 18658,
      "qaeda": 18659,
      "##vial": 18660,
      "garner": 18661,
      "refurbished": 18662,
      "##hwa": 18663,
      "geelong": 18664,
      "disasters": 18665,
      "nudged": 18666,
      "bs": 18667,
      "shareholder": 18668,
      "lori": 18669,
      "algae": 18670,
      "reinstated": 18671,
      "rot": 18672,
      "##ades": 18673,
      "##nous": 18674,
      "invites": 18675,
      "stainless": 18676,
      "183": 18677,
      "inclusive": 18678,
      "##itude": 18679,
      "diocesan": 18680,
      "til": 18681,
      "##icz": 18682,
      "denomination": 18683,
      "##xa": 18684,
      "benton": 18685,
      "floral": 18686,
      "registers": 18687,
      "##ider": 18688,
      "##erman": 18689,
      "##kell": 18690,
      "absurd": 18691,
      "brunei": 18692,
      "guangzhou": 18693,
      "hitter": 18694,
      "retaliation": 18695,
      "##uled": 18696,
      "##eve": 18697,
      "blanc": 18698,
      "nh": 18699,
      "consistency": 18700,
      "contamination": 18701,
      "##eres": 18702,
      "##rner": 18703,
      "dire": 18704,
      "palermo": 18705,
      "broadcasters": 18706,
      "diaries": 18707,
      "inspire": 18708,
      "vols": 18709,
      "brewer": 18710,
      "tightening": 18711,
      "ky": 18712,
      "mixtape": 18713,
      "hormone": 18714,
      "##tok": 18715,
      "stokes": 18716,
      "##color": 18717,
      "##dly": 18718,
      "##ssi": 18719,
      "pg": 18720,
      "##ometer": 18721,
      "##lington": 18722,
      "sanitation": 18723,
      "##tility": 18724,
      "intercontinental": 18725,
      "apps": 18726,
      "##adt": 18727,
      "¹⁄₂": 18728,
      "cylinders": 18729,
      "economies": 18730,
      "favourable": 18731,
      "unison": 18732,
      "croix": 18733,
      "gertrude": 18734,
      "odyssey": 18735,
      "vanity": 18736,
      "dangling": 18737,
      "##logists": 18738,
      "upgrades": 18739,
      "dice": 18740,
      "middleweight": 18741,
      "practitioner": 18742,
      "##ight": 18743,
      "206": 18744,
      "henrik": 18745,
      "parlor": 18746,
      "orion": 18747,
      "angered": 18748,
      "lac": 18749,
      "python": 18750,
      "blurted": 18751,
      "##rri": 18752,
      "sensual": 18753,
      "intends": 18754,
      "swings": 18755,
      "angled": 18756,
      "##phs": 18757,
      "husky": 18758,
      "attain": 18759,
      "peerage": 18760,
      "precinct": 18761,
      "textiles": 18762,
      "cheltenham": 18763,
      "shuffled": 18764,
      "dai": 18765,
      "confess": 18766,
      "tasting": 18767,
      "bhutan": 18768,
      "##riation": 18769,
      "tyrone": 18770,
      "segregation": 18771,
      "abrupt": 18772,
      "ruiz": 18773,
      "##rish": 18774,
      "smirked": 18775,
      "blackwell": 18776,
      "confidential": 18777,
      "browning": 18778,
      "amounted": 18779,
      "##put": 18780,
      "vase": 18781,
      "scarce": 18782,
      "fabulous": 18783,
      "raided": 18784,
      "staple": 18785,
      "guyana": 18786,
      "unemployed": 18787,
      "glider": 18788,
      "shay": 18789,
      "##tow": 18790,
      "carmine": 18791,
      "troll": 18792,
      "intervene": 18793,
      "squash": 18794,
      "superstar": 18795,
      "##uce": 18796,
      "cylindrical": 18797,
      "len": 18798,
      "roadway": 18799,
      "researched": 18800,
      "handy": 18801,
      "##rium": 18802,
      "##jana": 18803,
      "meta": 18804,
      "lao": 18805,
      "declares": 18806,
      "##rring": 18807,
      "##tadt": 18808,
      "##elin": 18809,
      "##kova": 18810,
      "willem": 18811,
      "shrubs": 18812,
      "napoleonic": 18813,
      "realms": 18814,
      "skater": 18815,
      "qi": 18816,
      "volkswagen": 18817,
      "##ł": 18818,
      "tad": 18819,
      "hara": 18820,
      "archaeologist": 18821,
      "awkwardly": 18822,
      "eerie": 18823,
      "##kind": 18824,
      "wiley": 18825,
      "##heimer": 18826,
      "##24": 18827,
      "titus": 18828,
      "organizers": 18829,
      "cfl": 18830,
      "crusaders": 18831,
      "lama": 18832,
      "usb": 18833,
      "vent": 18834,
      "enraged": 18835,
      "thankful": 18836,
      "occupants": 18837,
      "maximilian": 18838,
      "##gaard": 18839,
      "possessing": 18840,
      "textbooks": 18841,
      "##oran": 18842,
      "collaborator": 18843,
      "quaker": 18844,
      "##ulo": 18845,
      "avalanche": 18846,
      "mono": 18847,
      "silky": 18848,
      "straits": 18849,
      "isaiah": 18850,
      "mustang": 18851,
      "surged": 18852,
      "resolutions": 18853,
      "potomac": 18854,
      "descend": 18855,
      "cl": 18856,
      "kilograms": 18857,
      "plato": 18858,
      "strains": 18859,
      "saturdays": 18860,
      "##olin": 18861,
      "bernstein": 18862,
      "##ype": 18863,
      "holstein": 18864,
      "ponytail": 18865,
      "##watch": 18866,
      "belize": 18867,
      "conversely": 18868,
      "heroine": 18869,
      "perpetual": 18870,
      "##ylus": 18871,
      "charcoal": 18872,
      "piedmont": 18873,
      "glee": 18874,
      "negotiating": 18875,
      "backdrop": 18876,
      "prologue": 18877,
      "##jah": 18878,
      "##mmy": 18879,
      "pasadena": 18880,
      "climbs": 18881,
      "ramos": 18882,
      "sunni": 18883,
      "##holm": 18884,
      "##tner": 18885,
      "##tri": 18886,
      "anand": 18887,
      "deficiency": 18888,
      "hertfordshire": 18889,
      "stout": 18890,
      "##avi": 18891,
      "aperture": 18892,
      "orioles": 18893,
      "##irs": 18894,
      "doncaster": 18895,
      "intrigued": 18896,
      "bombed": 18897,
      "coating": 18898,
      "otis": 18899,
      "##mat": 18900,
      "cocktail": 18901,
      "##jit": 18902,
      "##eto": 18903,
      "amir": 18904,
      "arousal": 18905,
      "sar": 18906,
      "##proof": 18907,
      "##act": 18908,
      "##ories": 18909,
      "dixie": 18910,
      "pots": 18911,
      "##bow": 18912,
      "whereabouts": 18913,
      "159": 18914,
      "##fted": 18915,
      "drains": 18916,
      "bullying": 18917,
      "cottages": 18918,
      "scripture": 18919,
      "coherent": 18920,
      "fore": 18921,
      "poe": 18922,
      "appetite": 18923,
      "##uration": 18924,
      "sampled": 18925,
      "##ators": 18926,
      "##dp": 18927,
      "derrick": 18928,
      "rotor": 18929,
      "jays": 18930,
      "peacock": 18931,
      "installment": 18932,
      "##rro": 18933,
      "advisors": 18934,
      "##coming": 18935,
      "rodeo": 18936,
      "scotch": 18937,
      "##mot": 18938,
      "##db": 18939,
      "##fen": 18940,
      "##vant": 18941,
      "ensued": 18942,
      "rodrigo": 18943,
      "dictatorship": 18944,
      "martyrs": 18945,
      "twenties": 18946,
      "##н": 18947,
      "towed": 18948,
      "incidence": 18949,
      "marta": 18950,
      "rainforest": 18951,
      "sai": 18952,
      "scaled": 18953,
      "##cles": 18954,
      "oceanic": 18955,
      "qualifiers": 18956,
      "symphonic": 18957,
      "mcbride": 18958,
      "dislike": 18959,
      "generalized": 18960,
      "aubrey": 18961,
      "colonization": 18962,
      "##iation": 18963,
      "##lion": 18964,
      "##ssing": 18965,
      "disliked": 18966,
      "lublin": 18967,
      "salesman": 18968,
      "##ulates": 18969,
      "spherical": 18970,
      "whatsoever": 18971,
      "sweating": 18972,
      "avalon": 18973,
      "contention": 18974,
      "punt": 18975,
      "severity": 18976,
      "alderman": 18977,
      "atari": 18978,
      "##dina": 18979,
      "##grant": 18980,
      "##rop": 18981,
      "scarf": 18982,
      "seville": 18983,
      "vertices": 18984,
      "annexation": 18985,
      "fairfield": 18986,
      "fascination": 18987,
      "inspiring": 18988,
      "launches": 18989,
      "palatinate": 18990,
      "regretted": 18991,
      "##rca": 18992,
      "feral": 18993,
      "##iom": 18994,
      "elk": 18995,
      "nap": 18996,
      "olsen": 18997,
      "reddy": 18998,
      "yong": 18999,
      "##leader": 19000,
      "##iae": 19001,
      "garment": 19002,
      "transports": 19003,
      "feng": 19004,
      "gracie": 19005,
      "outrage": 19006,
      "viceroy": 19007,
      "insides": 19008,
      "##esis": 19009,
      "breakup": 19010,
      "grady": 19011,
      "organizer": 19012,
      "softer": 19013,
      "grimaced": 19014,
      "222": 19015,
      "murals": 19016,
      "galicia": 19017,
      "arranging": 19018,
      "vectors": 19019,
      "##rsten": 19020,
      "bas": 19021,
      "##sb": 19022,
      "##cens": 19023,
      "sloan": 19024,
      "##eka": 19025,
      "bitten": 19026,
      "ara": 19027,
      "fender": 19028,
      "nausea": 19029,
      "bumped": 19030,
      "kris": 19031,
      "banquet": 19032,
      "comrades": 19033,
      "detector": 19034,
      "persisted": 19035,
      "##llan": 19036,
      "adjustment": 19037,
      "endowed": 19038,
      "cinemas": 19039,
      "##shot": 19040,
      "sellers": 19041,
      "##uman": 19042,
      "peek": 19043,
      "epa": 19044,
      "kindly": 19045,
      "neglect": 19046,
      "simpsons": 19047,
      "talon": 19048,
      "mausoleum": 19049,
      "runaway": 19050,
      "hangul": 19051,
      "lookout": 19052,
      "##cic": 19053,
      "rewards": 19054,
      "coughed": 19055,
      "acquainted": 19056,
      "chloride": 19057,
      "##ald": 19058,
      "quicker": 19059,
      "accordion": 19060,
      "neolithic": 19061,
      "##qa": 19062,
      "artemis": 19063,
      "coefficient": 19064,
      "lenny": 19065,
      "pandora": 19066,
      "tx": 19067,
      "##xed": 19068,
      "ecstasy": 19069,
      "litter": 19070,
      "segunda": 19071,
      "chairperson": 19072,
      "gemma": 19073,
      "hiss": 19074,
      "rumor": 19075,
      "vow": 19076,
      "nasal": 19077,
      "antioch": 19078,
      "compensate": 19079,
      "patiently": 19080,
      "transformers": 19081,
      "##eded": 19082,
      "judo": 19083,
      "morrow": 19084,
      "penis": 19085,
      "posthumous": 19086,
      "philips": 19087,
      "bandits": 19088,
      "husbands": 19089,
      "denote": 19090,
      "flaming": 19091,
      "##any": 19092,
      "##phones": 19093,
      "langley": 19094,
      "yorker": 19095,
      "1760": 19096,
      "walters": 19097,
      "##uo": 19098,
      "##kle": 19099,
      "gubernatorial": 19100,
      "fatty": 19101,
      "samsung": 19102,
      "leroy": 19103,
      "outlaw": 19104,
      "##nine": 19105,
      "unpublished": 19106,
      "poole": 19107,
      "jakob": 19108,
      "##ᵢ": 19109,
      "##ₙ": 19110,
      "crete": 19111,
      "distorted": 19112,
      "superiority": 19113,
      "##dhi": 19114,
      "intercept": 19115,
      "crust": 19116,
      "mig": 19117,
      "claus": 19118,
      "crashes": 19119,
      "positioning": 19120,
      "188": 19121,
      "stallion": 19122,
      "301": 19123,
      "frontal": 19124,
      "armistice": 19125,
      "##estinal": 19126,
      "elton": 19127,
      "aj": 19128,
      "encompassing": 19129,
      "camel": 19130,
      "commemorated": 19131,
      "malaria": 19132,
      "woodward": 19133,
      "calf": 19134,
      "cigar": 19135,
      "penetrate": 19136,
      "##oso": 19137,
      "willard": 19138,
      "##rno": 19139,
      "##uche": 19140,
      "illustrate": 19141,
      "amusing": 19142,
      "convergence": 19143,
      "noteworthy": 19144,
      "##lma": 19145,
      "##rva": 19146,
      "journeys": 19147,
      "realise": 19148,
      "manfred": 19149,
      "##sable": 19150,
      "410": 19151,
      "##vocation": 19152,
      "hearings": 19153,
      "fiance": 19154,
      "##posed": 19155,
      "educators": 19156,
      "provoked": 19157,
      "adjusting": 19158,
      "##cturing": 19159,
      "modular": 19160,
      "stockton": 19161,
      "paterson": 19162,
      "vlad": 19163,
      "rejects": 19164,
      "electors": 19165,
      "selena": 19166,
      "maureen": 19167,
      "##tres": 19168,
      "uber": 19169,
      "##rce": 19170,
      "swirled": 19171,
      "##num": 19172,
      "proportions": 19173,
      "nanny": 19174,
      "pawn": 19175,
      "naturalist": 19176,
      "parma": 19177,
      "apostles": 19178,
      "awoke": 19179,
      "ethel": 19180,
      "wen": 19181,
      "##bey": 19182,
      "monsoon": 19183,
      "overview": 19184,
      "##inating": 19185,
      "mccain": 19186,
      "rendition": 19187,
      "risky": 19188,
      "adorned": 19189,
      "##ih": 19190,
      "equestrian": 19191,
      "germain": 19192,
      "nj": 19193,
      "conspicuous": 19194,
      "confirming": 19195,
      "##yoshi": 19196,
      "shivering": 19197,
      "##imeter": 19198,
      "milestone": 19199,
      "rumours": 19200,
      "flinched": 19201,
      "bounds": 19202,
      "smacked": 19203,
      "token": 19204,
      "##bei": 19205,
      "lectured": 19206,
      "automobiles": 19207,
      "##shore": 19208,
      "impacted": 19209,
      "##iable": 19210,
      "nouns": 19211,
      "nero": 19212,
      "##leaf": 19213,
      "ismail": 19214,
      "prostitute": 19215,
      "trams": 19216,
      "##lace": 19217,
      "bridget": 19218,
      "sud": 19219,
      "stimulus": 19220,
      "impressions": 19221,
      "reins": 19222,
      "revolves": 19223,
      "##oud": 19224,
      "##gned": 19225,
      "giro": 19226,
      "honeymoon": 19227,
      "##swell": 19228,
      "criterion": 19229,
      "##sms": 19230,
      "##uil": 19231,
      "libyan": 19232,
      "prefers": 19233,
      "##osition": 19234,
      "211": 19235,
      "preview": 19236,
      "sucks": 19237,
      "accusation": 19238,
      "bursts": 19239,
      "metaphor": 19240,
      "diffusion": 19241,
      "tolerate": 19242,
      "faye": 19243,
      "betting": 19244,
      "cinematographer": 19245,
      "liturgical": 19246,
      "specials": 19247,
      "bitterly": 19248,
      "humboldt": 19249,
      "##ckle": 19250,
      "flux": 19251,
      "rattled": 19252,
      "##itzer": 19253,
      "archaeologists": 19254,
      "odor": 19255,
      "authorised": 19256,
      "marshes": 19257,
      "discretion": 19258,
      "##ов": 19259,
      "alarmed": 19260,
      "archaic": 19261,
      "inverse": 19262,
      "##leton": 19263,
      "explorers": 19264,
      "##pine": 19265,
      "drummond": 19266,
      "tsunami": 19267,
      "woodlands": 19268,
      "##minate": 19269,
      "##tland": 19270,
      "booklet": 19271,
      "insanity": 19272,
      "owning": 19273,
      "insert": 19274,
      "crafted": 19275,
      "calculus": 19276,
      "##tore": 19277,
      "receivers": 19278,
      "##bt": 19279,
      "stung": 19280,
      "##eca": 19281,
      "##nched": 19282,
      "prevailing": 19283,
      "travellers": 19284,
      "eyeing": 19285,
      "lila": 19286,
      "graphs": 19287,
      "##borne": 19288,
      "178": 19289,
      "julien": 19290,
      "##won": 19291,
      "morale": 19292,
      "adaptive": 19293,
      "therapist": 19294,
      "erica": 19295,
      "cw": 19296,
      "libertarian": 19297,
      "bowman": 19298,
      "pitches": 19299,
      "vita": 19300,
      "##ional": 19301,
      "crook": 19302,
      "##ads": 19303,
      "##entation": 19304,
      "caledonia": 19305,
      "mutiny": 19306,
      "##sible": 19307,
      "1840s": 19308,
      "automation": 19309,
      "##ß": 19310,
      "flock": 19311,
      "##pia": 19312,
      "ironic": 19313,
      "pathology": 19314,
      "##imus": 19315,
      "remarried": 19316,
      "##22": 19317,
      "joker": 19318,
      "withstand": 19319,
      "energies": 19320,
      "##att": 19321,
      "shropshire": 19322,
      "hostages": 19323,
      "madeleine": 19324,
      "tentatively": 19325,
      "conflicting": 19326,
      "mateo": 19327,
      "recipes": 19328,
      "euros": 19329,
      "ol": 19330,
      "mercenaries": 19331,
      "nico": 19332,
      "##ndon": 19333,
      "albuquerque": 19334,
      "augmented": 19335,
      "mythical": 19336,
      "bel": 19337,
      "freud": 19338,
      "##child": 19339,
      "cough": 19340,
      "##lica": 19341,
      "365": 19342,
      "freddy": 19343,
      "lillian": 19344,
      "genetically": 19345,
      "nuremberg": 19346,
      "calder": 19347,
      "209": 19348,
      "bonn": 19349,
      "outdoors": 19350,
      "paste": 19351,
      "suns": 19352,
      "urgency": 19353,
      "vin": 19354,
      "restraint": 19355,
      "tyson": 19356,
      "##cera": 19357,
      "##selle": 19358,
      "barrage": 19359,
      "bethlehem": 19360,
      "kahn": 19361,
      "##par": 19362,
      "mounts": 19363,
      "nippon": 19364,
      "barony": 19365,
      "happier": 19366,
      "ryu": 19367,
      "makeshift": 19368,
      "sheldon": 19369,
      "blushed": 19370,
      "castillo": 19371,
      "barking": 19372,
      "listener": 19373,
      "taped": 19374,
      "bethel": 19375,
      "fluent": 19376,
      "headlines": 19377,
      "pornography": 19378,
      "rum": 19379,
      "disclosure": 19380,
      "sighing": 19381,
      "mace": 19382,
      "doubling": 19383,
      "gunther": 19384,
      "manly": 19385,
      "##plex": 19386,
      "rt": 19387,
      "interventions": 19388,
      "physiological": 19389,
      "forwards": 19390,
      "emerges": 19391,
      "##tooth": 19392,
      "##gny": 19393,
      "compliment": 19394,
      "rib": 19395,
      "recession": 19396,
      "visibly": 19397,
      "barge": 19398,
      "faults": 19399,
      "connector": 19400,
      "exquisite": 19401,
      "prefect": 19402,
      "##rlin": 19403,
      "patio": 19404,
      "##cured": 19405,
      "elevators": 19406,
      "brandt": 19407,
      "italics": 19408,
      "pena": 19409,
      "173": 19410,
      "wasp": 19411,
      "satin": 19412,
      "ea": 19413,
      "botswana": 19414,
      "graceful": 19415,
      "respectable": 19416,
      "##jima": 19417,
      "##rter": 19418,
      "##oic": 19419,
      "franciscan": 19420,
      "generates": 19421,
      "##dl": 19422,
      "alfredo": 19423,
      "disgusting": 19424,
      "##olate": 19425,
      "##iously": 19426,
      "sherwood": 19427,
      "warns": 19428,
      "cod": 19429,
      "promo": 19430,
      "cheryl": 19431,
      "sino": 19432,
      "##ة": 19433,
      "##escu": 19434,
      "twitch": 19435,
      "##zhi": 19436,
      "brownish": 19437,
      "thom": 19438,
      "ortiz": 19439,
      "##dron": 19440,
      "densely": 19441,
      "##beat": 19442,
      "carmel": 19443,
      "reinforce": 19444,
      "##bana": 19445,
      "187": 19446,
      "anastasia": 19447,
      "downhill": 19448,
      "vertex": 19449,
      "contaminated": 19450,
      "remembrance": 19451,
      "harmonic": 19452,
      "homework": 19453,
      "##sol": 19454,
      "fiancee": 19455,
      "gears": 19456,
      "olds": 19457,
      "angelica": 19458,
      "loft": 19459,
      "ramsay": 19460,
      "quiz": 19461,
      "colliery": 19462,
      "sevens": 19463,
      "##cape": 19464,
      "autism": 19465,
      "##hil": 19466,
      "walkway": 19467,
      "##boats": 19468,
      "ruben": 19469,
      "abnormal": 19470,
      "ounce": 19471,
      "khmer": 19472,
      "##bbe": 19473,
      "zachary": 19474,
      "bedside": 19475,
      "morphology": 19476,
      "punching": 19477,
      "##olar": 19478,
      "sparrow": 19479,
      "convinces": 19480,
      "##35": 19481,
      "hewitt": 19482,
      "queer": 19483,
      "remastered": 19484,
      "rods": 19485,
      "mabel": 19486,
      "solemn": 19487,
      "notified": 19488,
      "lyricist": 19489,
      "symmetric": 19490,
      "##xide": 19491,
      "174": 19492,
      "encore": 19493,
      "passports": 19494,
      "wildcats": 19495,
      "##uni": 19496,
      "baja": 19497,
      "##pac": 19498,
      "mildly": 19499,
      "##ease": 19500,
      "bleed": 19501,
      "commodity": 19502,
      "mounds": 19503,
      "glossy": 19504,
      "orchestras": 19505,
      "##omo": 19506,
      "damian": 19507,
      "prelude": 19508,
      "ambitions": 19509,
      "##vet": 19510,
      "awhile": 19511,
      "remotely": 19512,
      "##aud": 19513,
      "asserts": 19514,
      "imply": 19515,
      "##iques": 19516,
      "distinctly": 19517,
      "modelling": 19518,
      "remedy": 19519,
      "##dded": 19520,
      "windshield": 19521,
      "dani": 19522,
      "xiao": 19523,
      "##endra": 19524,
      "audible": 19525,
      "powerplant": 19526,
      "1300": 19527,
      "invalid": 19528,
      "elemental": 19529,
      "acquisitions": 19530,
      "##hala": 19531,
      "immaculate": 19532,
      "libby": 19533,
      "plata": 19534,
      "smuggling": 19535,
      "ventilation": 19536,
      "denoted": 19537,
      "minh": 19538,
      "##morphism": 19539,
      "430": 19540,
      "differed": 19541,
      "dion": 19542,
      "kelley": 19543,
      "lore": 19544,
      "mocking": 19545,
      "sabbath": 19546,
      "spikes": 19547,
      "hygiene": 19548,
      "drown": 19549,
      "runoff": 19550,
      "stylized": 19551,
      "tally": 19552,
      "liberated": 19553,
      "aux": 19554,
      "interpreter": 19555,
      "righteous": 19556,
      "aba": 19557,
      "siren": 19558,
      "reaper": 19559,
      "pearce": 19560,
      "millie": 19561,
      "##cier": 19562,
      "##yra": 19563,
      "gaius": 19564,
      "##iso": 19565,
      "captures": 19566,
      "##ttering": 19567,
      "dorm": 19568,
      "claudio": 19569,
      "##sic": 19570,
      "benches": 19571,
      "knighted": 19572,
      "blackness": 19573,
      "##ored": 19574,
      "discount": 19575,
      "fumble": 19576,
      "oxidation": 19577,
      "routed": 19578,
      "##ς": 19579,
      "novak": 19580,
      "perpendicular": 19581,
      "spoiled": 19582,
      "fracture": 19583,
      "splits": 19584,
      "##urt": 19585,
      "pads": 19586,
      "topology": 19587,
      "##cats": 19588,
      "axes": 19589,
      "fortunate": 19590,
      "offenders": 19591,
      "protestants": 19592,
      "esteem": 19593,
      "221": 19594,
      "broadband": 19595,
      "convened": 19596,
      "frankly": 19597,
      "hound": 19598,
      "prototypes": 19599,
      "isil": 19600,
      "facilitated": 19601,
      "keel": 19602,
      "##sher": 19603,
      "sahara": 19604,
      "awaited": 19605,
      "bubba": 19606,
      "orb": 19607,
      "prosecutors": 19608,
      "186": 19609,
      "hem": 19610,
      "520": 19611,
      "##xing": 19612,
      "relaxing": 19613,
      "remnant": 19614,
      "romney": 19615,
      "sorted": 19616,
      "slalom": 19617,
      "stefano": 19618,
      "ulrich": 19619,
      "##active": 19620,
      "exemption": 19621,
      "folder": 19622,
      "pauses": 19623,
      "foliage": 19624,
      "hitchcock": 19625,
      "epithet": 19626,
      "204": 19627,
      "criticisms": 19628,
      "##aca": 19629,
      "ballistic": 19630,
      "brody": 19631,
      "hinduism": 19632,
      "chaotic": 19633,
      "youths": 19634,
      "equals": 19635,
      "##pala": 19636,
      "pts": 19637,
      "thicker": 19638,
      "analogous": 19639,
      "capitalist": 19640,
      "improvised": 19641,
      "overseeing": 19642,
      "sinatra": 19643,
      "ascended": 19644,
      "beverage": 19645,
      "##tl": 19646,
      "straightforward": 19647,
      "##kon": 19648,
      "curran": 19649,
      "##west": 19650,
      "bois": 19651,
      "325": 19652,
      "induce": 19653,
      "surveying": 19654,
      "emperors": 19655,
      "sax": 19656,
      "unpopular": 19657,
      "##kk": 19658,
      "cartoonist": 19659,
      "fused": 19660,
      "##mble": 19661,
      "unto": 19662,
      "##yuki": 19663,
      "localities": 19664,
      "##cko": 19665,
      "##ln": 19666,
      "darlington": 19667,
      "slain": 19668,
      "academie": 19669,
      "lobbying": 19670,
      "sediment": 19671,
      "puzzles": 19672,
      "##grass": 19673,
      "defiance": 19674,
      "dickens": 19675,
      "manifest": 19676,
      "tongues": 19677,
      "alumnus": 19678,
      "arbor": 19679,
      "coincide": 19680,
      "184": 19681,
      "appalachian": 19682,
      "mustafa": 19683,
      "examiner": 19684,
      "cabaret": 19685,
      "traumatic": 19686,
      "yves": 19687,
      "bracelet": 19688,
      "draining": 19689,
      "heroin": 19690,
      "magnum": 19691,
      "baths": 19692,
      "odessa": 19693,
      "consonants": 19694,
      "mitsubishi": 19695,
      "##gua": 19696,
      "kellan": 19697,
      "vaudeville": 19698,
      "##fr": 19699,
      "joked": 19700,
      "null": 19701,
      "straps": 19702,
      "probation": 19703,
      "##ław": 19704,
      "ceded": 19705,
      "interfaces": 19706,
      "##pas": 19707,
      "##zawa": 19708,
      "blinding": 19709,
      "viet": 19710,
      "224": 19711,
      "rothschild": 19712,
      "museo": 19713,
      "640": 19714,
      "huddersfield": 19715,
      "##vr": 19716,
      "tactic": 19717,
      "##storm": 19718,
      "brackets": 19719,
      "dazed": 19720,
      "incorrectly": 19721,
      "##vu": 19722,
      "reg": 19723,
      "glazed": 19724,
      "fearful": 19725,
      "manifold": 19726,
      "benefited": 19727,
      "irony": 19728,
      "##sun": 19729,
      "stumbling": 19730,
      "##rte": 19731,
      "willingness": 19732,
      "balkans": 19733,
      "mei": 19734,
      "wraps": 19735,
      "##aba": 19736,
      "injected": 19737,
      "##lea": 19738,
      "gu": 19739,
      "syed": 19740,
      "harmless": 19741,
      "##hammer": 19742,
      "bray": 19743,
      "takeoff": 19744,
      "poppy": 19745,
      "timor": 19746,
      "cardboard": 19747,
      "astronaut": 19748,
      "purdue": 19749,
      "weeping": 19750,
      "southbound": 19751,
      "cursing": 19752,
      "stalls": 19753,
      "diagonal": 19754,
      "##neer": 19755,
      "lamar": 19756,
      "bryce": 19757,
      "comte": 19758,
      "weekdays": 19759,
      "harrington": 19760,
      "##uba": 19761,
      "negatively": 19762,
      "##see": 19763,
      "lays": 19764,
      "grouping": 19765,
      "##cken": 19766,
      "##henko": 19767,
      "affirmed": 19768,
      "halle": 19769,
      "modernist": 19770,
      "##lai": 19771,
      "hodges": 19772,
      "smelling": 19773,
      "aristocratic": 19774,
      "baptized": 19775,
      "dismiss": 19776,
      "justification": 19777,
      "oilers": 19778,
      "##now": 19779,
      "coupling": 19780,
      "qin": 19781,
      "snack": 19782,
      "healer": 19783,
      "##qing": 19784,
      "gardener": 19785,
      "layla": 19786,
      "battled": 19787,
      "formulated": 19788,
      "stephenson": 19789,
      "gravitational": 19790,
      "##gill": 19791,
      "##jun": 19792,
      "1768": 19793,
      "granny": 19794,
      "coordinating": 19795,
      "suites": 19796,
      "##cd": 19797,
      "##ioned": 19798,
      "monarchs": 19799,
      "##cote": 19800,
      "##hips": 19801,
      "sep": 19802,
      "blended": 19803,
      "apr": 19804,
      "barrister": 19805,
      "deposition": 19806,
      "fia": 19807,
      "mina": 19808,
      "policemen": 19809,
      "paranoid": 19810,
      "##pressed": 19811,
      "churchyard": 19812,
      "covert": 19813,
      "crumpled": 19814,
      "creep": 19815,
      "abandoning": 19816,
      "tr": 19817,
      "transmit": 19818,
      "conceal": 19819,
      "barr": 19820,
      "understands": 19821,
      "readiness": 19822,
      "spire": 19823,
      "##cology": 19824,
      "##enia": 19825,
      "##erry": 19826,
      "610": 19827,
      "startling": 19828,
      "unlock": 19829,
      "vida": 19830,
      "bowled": 19831,
      "slots": 19832,
      "##nat": 19833,
      "##islav": 19834,
      "spaced": 19835,
      "trusting": 19836,
      "admire": 19837,
      "rig": 19838,
      "##ink": 19839,
      "slack": 19840,
      "##70": 19841,
      "mv": 19842,
      "207": 19843,
      "casualty": 19844,
      "##wei": 19845,
      "classmates": 19846,
      "##odes": 19847,
      "##rar": 19848,
      "##rked": 19849,
      "amherst": 19850,
      "furnished": 19851,
      "evolve": 19852,
      "foundry": 19853,
      "menace": 19854,
      "mead": 19855,
      "##lein": 19856,
      "flu": 19857,
      "wesleyan": 19858,
      "##kled": 19859,
      "monterey": 19860,
      "webber": 19861,
      "##vos": 19862,
      "wil": 19863,
      "##mith": 19864,
      "##на": 19865,
      "bartholomew": 19866,
      "justices": 19867,
      "restrained": 19868,
      "##cke": 19869,
      "amenities": 19870,
      "191": 19871,
      "mediated": 19872,
      "sewage": 19873,
      "trenches": 19874,
      "ml": 19875,
      "mainz": 19876,
      "##thus": 19877,
      "1800s": 19878,
      "##cula": 19879,
      "##inski": 19880,
      "caine": 19881,
      "bonding": 19882,
      "213": 19883,
      "converts": 19884,
      "spheres": 19885,
      "superseded": 19886,
      "marianne": 19887,
      "crypt": 19888,
      "sweaty": 19889,
      "ensign": 19890,
      "historia": 19891,
      "##br": 19892,
      "spruce": 19893,
      "##post": 19894,
      "##ask": 19895,
      "forks": 19896,
      "thoughtfully": 19897,
      "yukon": 19898,
      "pamphlet": 19899,
      "ames": 19900,
      "##uter": 19901,
      "karma": 19902,
      "##yya": 19903,
      "bryn": 19904,
      "negotiation": 19905,
      "sighs": 19906,
      "incapable": 19907,
      "##mbre": 19908,
      "##ntial": 19909,
      "actresses": 19910,
      "taft": 19911,
      "##mill": 19912,
      "luce": 19913,
      "prevailed": 19914,
      "##amine": 19915,
      "1773": 19916,
      "motionless": 19917,
      "envoy": 19918,
      "testify": 19919,
      "investing": 19920,
      "sculpted": 19921,
      "instructors": 19922,
      "provence": 19923,
      "kali": 19924,
      "cullen": 19925,
      "horseback": 19926,
      "##while": 19927,
      "goodwin": 19928,
      "##jos": 19929,
      "gaa": 19930,
      "norte": 19931,
      "##ldon": 19932,
      "modify": 19933,
      "wavelength": 19934,
      "abd": 19935,
      "214": 19936,
      "skinned": 19937,
      "sprinter": 19938,
      "forecast": 19939,
      "scheduling": 19940,
      "marries": 19941,
      "squared": 19942,
      "tentative": 19943,
      "##chman": 19944,
      "boer": 19945,
      "##isch": 19946,
      "bolts": 19947,
      "swap": 19948,
      "fisherman": 19949,
      "assyrian": 19950,
      "impatiently": 19951,
      "guthrie": 19952,
      "martins": 19953,
      "murdoch": 19954,
      "194": 19955,
      "tanya": 19956,
      "nicely": 19957,
      "dolly": 19958,
      "lacy": 19959,
      "med": 19960,
      "##45": 19961,
      "syn": 19962,
      "decks": 19963,
      "fashionable": 19964,
      "millionaire": 19965,
      "##ust": 19966,
      "surfing": 19967,
      "##ml": 19968,
      "##ision": 19969,
      "heaved": 19970,
      "tammy": 19971,
      "consulate": 19972,
      "attendees": 19973,
      "routinely": 19974,
      "197": 19975,
      "fuse": 19976,
      "saxophonist": 19977,
      "backseat": 19978,
      "malaya": 19979,
      "##lord": 19980,
      "scowl": 19981,
      "tau": 19982,
      "##ishly": 19983,
      "193": 19984,
      "sighted": 19985,
      "steaming": 19986,
      "##rks": 19987,
      "303": 19988,
      "911": 19989,
      "##holes": 19990,
      "##hong": 19991,
      "ching": 19992,
      "##wife": 19993,
      "bless": 19994,
      "conserved": 19995,
      "jurassic": 19996,
      "stacey": 19997,
      "unix": 19998,
      "zion": 19999,
      "chunk": 20000,
      "rigorous": 20001,
      "blaine": 20002,
      "198": 20003,
      "peabody": 20004,
      "slayer": 20005,
      "dismay": 20006,
      "brewers": 20007,
      "nz": 20008,
      "##jer": 20009,
      "det": 20010,
      "##glia": 20011,
      "glover": 20012,
      "postwar": 20013,
      "int": 20014,
      "penetration": 20015,
      "sylvester": 20016,
      "imitation": 20017,
      "vertically": 20018,
      "airlift": 20019,
      "heiress": 20020,
      "knoxville": 20021,
      "viva": 20022,
      "##uin": 20023,
      "390": 20024,
      "macon": 20025,
      "##rim": 20026,
      "##fighter": 20027,
      "##gonal": 20028,
      "janice": 20029,
      "##orescence": 20030,
      "##wari": 20031,
      "marius": 20032,
      "belongings": 20033,
      "leicestershire": 20034,
      "196": 20035,
      "blanco": 20036,
      "inverted": 20037,
      "preseason": 20038,
      "sanity": 20039,
      "sobbing": 20040,
      "##due": 20041,
      "##elt": 20042,
      "##dled": 20043,
      "collingwood": 20044,
      "regeneration": 20045,
      "flickering": 20046,
      "shortest": 20047,
      "##mount": 20048,
      "##osi": 20049,
      "feminism": 20050,
      "##lat": 20051,
      "sherlock": 20052,
      "cabinets": 20053,
      "fumbled": 20054,
      "northbound": 20055,
      "precedent": 20056,
      "snaps": 20057,
      "##mme": 20058,
      "researching": 20059,
      "##akes": 20060,
      "guillaume": 20061,
      "insights": 20062,
      "manipulated": 20063,
      "vapor": 20064,
      "neighbour": 20065,
      "sap": 20066,
      "gangster": 20067,
      "frey": 20068,
      "f1": 20069,
      "stalking": 20070,
      "scarcely": 20071,
      "callie": 20072,
      "barnett": 20073,
      "tendencies": 20074,
      "audi": 20075,
      "doomed": 20076,
      "assessing": 20077,
      "slung": 20078,
      "panchayat": 20079,
      "ambiguous": 20080,
      "bartlett": 20081,
      "##etto": 20082,
      "distributing": 20083,
      "violating": 20084,
      "wolverhampton": 20085,
      "##hetic": 20086,
      "swami": 20087,
      "histoire": 20088,
      "##urus": 20089,
      "liable": 20090,
      "pounder": 20091,
      "groin": 20092,
      "hussain": 20093,
      "larsen": 20094,
      "popping": 20095,
      "surprises": 20096,
      "##atter": 20097,
      "vie": 20098,
      "curt": 20099,
      "##station": 20100,
      "mute": 20101,
      "relocate": 20102,
      "musicals": 20103,
      "authorization": 20104,
      "richter": 20105,
      "##sef": 20106,
      "immortality": 20107,
      "tna": 20108,
      "bombings": 20109,
      "##press": 20110,
      "deteriorated": 20111,
      "yiddish": 20112,
      "##acious": 20113,
      "robbed": 20114,
      "colchester": 20115,
      "cs": 20116,
      "pmid": 20117,
      "ao": 20118,
      "verified": 20119,
      "balancing": 20120,
      "apostle": 20121,
      "swayed": 20122,
      "recognizable": 20123,
      "oxfordshire": 20124,
      "retention": 20125,
      "nottinghamshire": 20126,
      "contender": 20127,
      "judd": 20128,
      "invitational": 20129,
      "shrimp": 20130,
      "uhf": 20131,
      "##icient": 20132,
      "cleaner": 20133,
      "longitudinal": 20134,
      "tanker": 20135,
      "##mur": 20136,
      "acronym": 20137,
      "broker": 20138,
      "koppen": 20139,
      "sundance": 20140,
      "suppliers": 20141,
      "##gil": 20142,
      "4000": 20143,
      "clipped": 20144,
      "fuels": 20145,
      "petite": 20146,
      "##anne": 20147,
      "landslide": 20148,
      "helene": 20149,
      "diversion": 20150,
      "populous": 20151,
      "landowners": 20152,
      "auspices": 20153,
      "melville": 20154,
      "quantitative": 20155,
      "##xes": 20156,
      "ferries": 20157,
      "nicky": 20158,
      "##llus": 20159,
      "doo": 20160,
      "haunting": 20161,
      "roche": 20162,
      "carver": 20163,
      "downed": 20164,
      "unavailable": 20165,
      "##pathy": 20166,
      "approximation": 20167,
      "hiroshima": 20168,
      "##hue": 20169,
      "garfield": 20170,
      "valle": 20171,
      "comparatively": 20172,
      "keyboardist": 20173,
      "traveler": 20174,
      "##eit": 20175,
      "congestion": 20176,
      "calculating": 20177,
      "subsidiaries": 20178,
      "##bate": 20179,
      "serb": 20180,
      "modernization": 20181,
      "fairies": 20182,
      "deepened": 20183,
      "ville": 20184,
      "averages": 20185,
      "##lore": 20186,
      "inflammatory": 20187,
      "tonga": 20188,
      "##itch": 20189,
      "co₂": 20190,
      "squads": 20191,
      "##hea": 20192,
      "gigantic": 20193,
      "serum": 20194,
      "enjoyment": 20195,
      "retailer": 20196,
      "verona": 20197,
      "35th": 20198,
      "cis": 20199,
      "##phobic": 20200,
      "magna": 20201,
      "technicians": 20202,
      "##vati": 20203,
      "arithmetic": 20204,
      "##sport": 20205,
      "levin": 20206,
      "##dation": 20207,
      "amtrak": 20208,
      "chow": 20209,
      "sienna": 20210,
      "##eyer": 20211,
      "backstage": 20212,
      "entrepreneurship": 20213,
      "##otic": 20214,
      "learnt": 20215,
      "tao": 20216,
      "##udy": 20217,
      "worcestershire": 20218,
      "formulation": 20219,
      "baggage": 20220,
      "hesitant": 20221,
      "bali": 20222,
      "sabotage": 20223,
      "##kari": 20224,
      "barren": 20225,
      "enhancing": 20226,
      "murmur": 20227,
      "pl": 20228,
      "freshly": 20229,
      "putnam": 20230,
      "syntax": 20231,
      "aces": 20232,
      "medicines": 20233,
      "resentment": 20234,
      "bandwidth": 20235,
      "##sier": 20236,
      "grins": 20237,
      "chili": 20238,
      "guido": 20239,
      "##sei": 20240,
      "framing": 20241,
      "implying": 20242,
      "gareth": 20243,
      "lissa": 20244,
      "genevieve": 20245,
      "pertaining": 20246,
      "admissions": 20247,
      "geo": 20248,
      "thorpe": 20249,
      "proliferation": 20250,
      "sato": 20251,
      "bela": 20252,
      "analyzing": 20253,
      "parting": 20254,
      "##gor": 20255,
      "awakened": 20256,
      "##isman": 20257,
      "huddled": 20258,
      "secrecy": 20259,
      "##kling": 20260,
      "hush": 20261,
      "gentry": 20262,
      "540": 20263,
      "dungeons": 20264,
      "##ego": 20265,
      "coasts": 20266,
      "##utz": 20267,
      "sacrificed": 20268,
      "##chule": 20269,
      "landowner": 20270,
      "mutually": 20271,
      "prevalence": 20272,
      "programmer": 20273,
      "adolescent": 20274,
      "disrupted": 20275,
      "seaside": 20276,
      "gee": 20277,
      "trusts": 20278,
      "vamp": 20279,
      "georgie": 20280,
      "##nesian": 20281,
      "##iol": 20282,
      "schedules": 20283,
      "sindh": 20284,
      "##market": 20285,
      "etched": 20286,
      "hm": 20287,
      "sparse": 20288,
      "bey": 20289,
      "beaux": 20290,
      "scratching": 20291,
      "gliding": 20292,
      "unidentified": 20293,
      "216": 20294,
      "collaborating": 20295,
      "gems": 20296,
      "jesuits": 20297,
      "oro": 20298,
      "accumulation": 20299,
      "shaping": 20300,
      "mbe": 20301,
      "anal": 20302,
      "##xin": 20303,
      "231": 20304,
      "enthusiasts": 20305,
      "newscast": 20306,
      "##egan": 20307,
      "janata": 20308,
      "dewey": 20309,
      "parkinson": 20310,
      "179": 20311,
      "ankara": 20312,
      "biennial": 20313,
      "towering": 20314,
      "dd": 20315,
      "inconsistent": 20316,
      "950": 20317,
      "##chet": 20318,
      "thriving": 20319,
      "terminate": 20320,
      "cabins": 20321,
      "furiously": 20322,
      "eats": 20323,
      "advocating": 20324,
      "donkey": 20325,
      "marley": 20326,
      "muster": 20327,
      "phyllis": 20328,
      "leiden": 20329,
      "##user": 20330,
      "grassland": 20331,
      "glittering": 20332,
      "iucn": 20333,
      "loneliness": 20334,
      "217": 20335,
      "memorandum": 20336,
      "armenians": 20337,
      "##ddle": 20338,
      "popularized": 20339,
      "rhodesia": 20340,
      "60s": 20341,
      "lame": 20342,
      "##illon": 20343,
      "sans": 20344,
      "bikini": 20345,
      "header": 20346,
      "orbits": 20347,
      "##xx": 20348,
      "##finger": 20349,
      "##ulator": 20350,
      "sharif": 20351,
      "spines": 20352,
      "biotechnology": 20353,
      "strolled": 20354,
      "naughty": 20355,
      "yates": 20356,
      "##wire": 20357,
      "fremantle": 20358,
      "milo": 20359,
      "##mour": 20360,
      "abducted": 20361,
      "removes": 20362,
      "##atin": 20363,
      "humming": 20364,
      "wonderland": 20365,
      "##chrome": 20366,
      "##ester": 20367,
      "hume": 20368,
      "pivotal": 20369,
      "##rates": 20370,
      "armand": 20371,
      "grams": 20372,
      "believers": 20373,
      "elector": 20374,
      "rte": 20375,
      "apron": 20376,
      "bis": 20377,
      "scraped": 20378,
      "##yria": 20379,
      "endorsement": 20380,
      "initials": 20381,
      "##llation": 20382,
      "eps": 20383,
      "dotted": 20384,
      "hints": 20385,
      "buzzing": 20386,
      "emigration": 20387,
      "nearer": 20388,
      "##tom": 20389,
      "indicators": 20390,
      "##ulu": 20391,
      "coarse": 20392,
      "neutron": 20393,
      "protectorate": 20394,
      "##uze": 20395,
      "directional": 20396,
      "exploits": 20397,
      "pains": 20398,
      "loire": 20399,
      "1830s": 20400,
      "proponents": 20401,
      "guggenheim": 20402,
      "rabbits": 20403,
      "ritchie": 20404,
      "305": 20405,
      "hectare": 20406,
      "inputs": 20407,
      "hutton": 20408,
      "##raz": 20409,
      "verify": 20410,
      "##ako": 20411,
      "boilers": 20412,
      "longitude": 20413,
      "##lev": 20414,
      "skeletal": 20415,
      "yer": 20416,
      "emilia": 20417,
      "citrus": 20418,
      "compromised": 20419,
      "##gau": 20420,
      "pokemon": 20421,
      "prescription": 20422,
      "paragraph": 20423,
      "eduard": 20424,
      "cadillac": 20425,
      "attire": 20426,
      "categorized": 20427,
      "kenyan": 20428,
      "weddings": 20429,
      "charley": 20430,
      "##bourg": 20431,
      "entertain": 20432,
      "monmouth": 20433,
      "##lles": 20434,
      "nutrients": 20435,
      "davey": 20436,
      "mesh": 20437,
      "incentive": 20438,
      "practised": 20439,
      "ecosystems": 20440,
      "kemp": 20441,
      "subdued": 20442,
      "overheard": 20443,
      "##rya": 20444,
      "bodily": 20445,
      "maxim": 20446,
      "##nius": 20447,
      "apprenticeship": 20448,
      "ursula": 20449,
      "##fight": 20450,
      "lodged": 20451,
      "rug": 20452,
      "silesian": 20453,
      "unconstitutional": 20454,
      "patel": 20455,
      "inspected": 20456,
      "coyote": 20457,
      "unbeaten": 20458,
      "##hak": 20459,
      "34th": 20460,
      "disruption": 20461,
      "convict": 20462,
      "parcel": 20463,
      "##cl": 20464,
      "##nham": 20465,
      "collier": 20466,
      "implicated": 20467,
      "mallory": 20468,
      "##iac": 20469,
      "##lab": 20470,
      "susannah": 20471,
      "winkler": 20472,
      "##rber": 20473,
      "shia": 20474,
      "phelps": 20475,
      "sediments": 20476,
      "graphical": 20477,
      "robotic": 20478,
      "##sner": 20479,
      "adulthood": 20480,
      "mart": 20481,
      "smoked": 20482,
      "##isto": 20483,
      "kathryn": 20484,
      "clarified": 20485,
      "##aran": 20486,
      "divides": 20487,
      "convictions": 20488,
      "oppression": 20489,
      "pausing": 20490,
      "burying": 20491,
      "##mt": 20492,
      "federico": 20493,
      "mathias": 20494,
      "eileen": 20495,
      "##tana": 20496,
      "kite": 20497,
      "hunched": 20498,
      "##acies": 20499,
      "189": 20500,
      "##atz": 20501,
      "disadvantage": 20502,
      "liza": 20503,
      "kinetic": 20504,
      "greedy": 20505,
      "paradox": 20506,
      "yokohama": 20507,
      "dowager": 20508,
      "trunks": 20509,
      "ventured": 20510,
      "##gement": 20511,
      "gupta": 20512,
      "vilnius": 20513,
      "olaf": 20514,
      "##thest": 20515,
      "crimean": 20516,
      "hopper": 20517,
      "##ej": 20518,
      "progressively": 20519,
      "arturo": 20520,
      "mouthed": 20521,
      "arrondissement": 20522,
      "##fusion": 20523,
      "rubin": 20524,
      "simulcast": 20525,
      "oceania": 20526,
      "##orum": 20527,
      "##stra": 20528,
      "##rred": 20529,
      "busiest": 20530,
      "intensely": 20531,
      "navigator": 20532,
      "cary": 20533,
      "##vine": 20534,
      "##hini": 20535,
      "##bies": 20536,
      "fife": 20537,
      "rowe": 20538,
      "rowland": 20539,
      "posing": 20540,
      "insurgents": 20541,
      "shafts": 20542,
      "lawsuits": 20543,
      "activate": 20544,
      "conor": 20545,
      "inward": 20546,
      "culturally": 20547,
      "garlic": 20548,
      "265": 20549,
      "##eering": 20550,
      "eclectic": 20551,
      "##hui": 20552,
      "##kee": 20553,
      "##nl": 20554,
      "furrowed": 20555,
      "vargas": 20556,
      "meteorological": 20557,
      "rendezvous": 20558,
      "##aus": 20559,
      "culinary": 20560,
      "commencement": 20561,
      "##dition": 20562,
      "quota": 20563,
      "##notes": 20564,
      "mommy": 20565,
      "salaries": 20566,
      "overlapping": 20567,
      "mule": 20568,
      "##iology": 20569,
      "##mology": 20570,
      "sums": 20571,
      "wentworth": 20572,
      "##isk": 20573,
      "##zione": 20574,
      "mainline": 20575,
      "subgroup": 20576,
      "##illy": 20577,
      "hack": 20578,
      "plaintiff": 20579,
      "verdi": 20580,
      "bulb": 20581,
      "differentiation": 20582,
      "engagements": 20583,
      "multinational": 20584,
      "supplemented": 20585,
      "bertrand": 20586,
      "caller": 20587,
      "regis": 20588,
      "##naire": 20589,
      "##sler": 20590,
      "##arts": 20591,
      "##imated": 20592,
      "blossom": 20593,
      "propagation": 20594,
      "kilometer": 20595,
      "viaduct": 20596,
      "vineyards": 20597,
      "##uate": 20598,
      "beckett": 20599,
      "optimization": 20600,
      "golfer": 20601,
      "songwriters": 20602,
      "seminal": 20603,
      "semitic": 20604,
      "thud": 20605,
      "volatile": 20606,
      "evolving": 20607,
      "ridley": 20608,
      "##wley": 20609,
      "trivial": 20610,
      "distributions": 20611,
      "scandinavia": 20612,
      "jiang": 20613,
      "##ject": 20614,
      "wrestled": 20615,
      "insistence": 20616,
      "##dio": 20617,
      "emphasizes": 20618,
      "napkin": 20619,
      "##ods": 20620,
      "adjunct": 20621,
      "rhyme": 20622,
      "##ricted": 20623,
      "##eti": 20624,
      "hopeless": 20625,
      "surrounds": 20626,
      "tremble": 20627,
      "32nd": 20628,
      "smoky": 20629,
      "##ntly": 20630,
      "oils": 20631,
      "medicinal": 20632,
      "padded": 20633,
      "steer": 20634,
      "wilkes": 20635,
      "219": 20636,
      "255": 20637,
      "concessions": 20638,
      "hue": 20639,
      "uniquely": 20640,
      "blinded": 20641,
      "landon": 20642,
      "yahoo": 20643,
      "##lane": 20644,
      "hendrix": 20645,
      "commemorating": 20646,
      "dex": 20647,
      "specify": 20648,
      "chicks": 20649,
      "##ggio": 20650,
      "intercity": 20651,
      "1400": 20652,
      "morley": 20653,
      "##torm": 20654,
      "highlighting": 20655,
      "##oting": 20656,
      "pang": 20657,
      "oblique": 20658,
      "stalled": 20659,
      "##liner": 20660,
      "flirting": 20661,
      "newborn": 20662,
      "1769": 20663,
      "bishopric": 20664,
      "shaved": 20665,
      "232": 20666,
      "currie": 20667,
      "##ush": 20668,
      "dharma": 20669,
      "spartan": 20670,
      "##ooped": 20671,
      "favorites": 20672,
      "smug": 20673,
      "novella": 20674,
      "sirens": 20675,
      "abusive": 20676,
      "creations": 20677,
      "espana": 20678,
      "##lage": 20679,
      "paradigm": 20680,
      "semiconductor": 20681,
      "sheen": 20682,
      "##rdo": 20683,
      "##yen": 20684,
      "##zak": 20685,
      "nrl": 20686,
      "renew": 20687,
      "##pose": 20688,
      "##tur": 20689,
      "adjutant": 20690,
      "marches": 20691,
      "norma": 20692,
      "##enity": 20693,
      "ineffective": 20694,
      "weimar": 20695,
      "grunt": 20696,
      "##gat": 20697,
      "lordship": 20698,
      "plotting": 20699,
      "expenditure": 20700,
      "infringement": 20701,
      "lbs": 20702,
      "refrain": 20703,
      "av": 20704,
      "mimi": 20705,
      "mistakenly": 20706,
      "postmaster": 20707,
      "1771": 20708,
      "##bara": 20709,
      "ras": 20710,
      "motorsports": 20711,
      "tito": 20712,
      "199": 20713,
      "subjective": 20714,
      "##zza": 20715,
      "bully": 20716,
      "stew": 20717,
      "##kaya": 20718,
      "prescott": 20719,
      "1a": 20720,
      "##raphic": 20721,
      "##zam": 20722,
      "bids": 20723,
      "styling": 20724,
      "paranormal": 20725,
      "reeve": 20726,
      "sneaking": 20727,
      "exploding": 20728,
      "katz": 20729,
      "akbar": 20730,
      "migrant": 20731,
      "syllables": 20732,
      "indefinitely": 20733,
      "##ogical": 20734,
      "destroys": 20735,
      "replaces": 20736,
      "applause": 20737,
      "##phine": 20738,
      "pest": 20739,
      "##fide": 20740,
      "218": 20741,
      "articulated": 20742,
      "bertie": 20743,
      "##thing": 20744,
      "##cars": 20745,
      "##ptic": 20746,
      "courtroom": 20747,
      "crowley": 20748,
      "aesthetics": 20749,
      "cummings": 20750,
      "tehsil": 20751,
      "hormones": 20752,
      "titanic": 20753,
      "dangerously": 20754,
      "##ibe": 20755,
      "stadion": 20756,
      "jaenelle": 20757,
      "auguste": 20758,
      "ciudad": 20759,
      "##chu": 20760,
      "mysore": 20761,
      "partisans": 20762,
      "##sio": 20763,
      "lucan": 20764,
      "philipp": 20765,
      "##aly": 20766,
      "debating": 20767,
      "henley": 20768,
      "interiors": 20769,
      "##rano": 20770,
      "##tious": 20771,
      "homecoming": 20772,
      "beyonce": 20773,
      "usher": 20774,
      "henrietta": 20775,
      "prepares": 20776,
      "weeds": 20777,
      "##oman": 20778,
      "ely": 20779,
      "plucked": 20780,
      "##pire": 20781,
      "##dable": 20782,
      "luxurious": 20783,
      "##aq": 20784,
      "artifact": 20785,
      "password": 20786,
      "pasture": 20787,
      "juno": 20788,
      "maddy": 20789,
      "minsk": 20790,
      "##dder": 20791,
      "##ologies": 20792,
      "##rone": 20793,
      "assessments": 20794,
      "martian": 20795,
      "royalist": 20796,
      "1765": 20797,
      "examines": 20798,
      "##mani": 20799,
      "##rge": 20800,
      "nino": 20801,
      "223": 20802,
      "parry": 20803,
      "scooped": 20804,
      "relativity": 20805,
      "##eli": 20806,
      "##uting": 20807,
      "##cao": 20808,
      "congregational": 20809,
      "noisy": 20810,
      "traverse": 20811,
      "##agawa": 20812,
      "strikeouts": 20813,
      "nickelodeon": 20814,
      "obituary": 20815,
      "transylvania": 20816,
      "binds": 20817,
      "depictions": 20818,
      "polk": 20819,
      "trolley": 20820,
      "##yed": 20821,
      "##lard": 20822,
      "breeders": 20823,
      "##under": 20824,
      "dryly": 20825,
      "hokkaido": 20826,
      "1762": 20827,
      "strengths": 20828,
      "stacks": 20829,
      "bonaparte": 20830,
      "connectivity": 20831,
      "neared": 20832,
      "prostitutes": 20833,
      "stamped": 20834,
      "anaheim": 20835,
      "gutierrez": 20836,
      "sinai": 20837,
      "##zzling": 20838,
      "bram": 20839,
      "fresno": 20840,
      "madhya": 20841,
      "##86": 20842,
      "proton": 20843,
      "##lena": 20844,
      "##llum": 20845,
      "##phon": 20846,
      "reelected": 20847,
      "wanda": 20848,
      "##anus": 20849,
      "##lb": 20850,
      "ample": 20851,
      "distinguishing": 20852,
      "##yler": 20853,
      "grasping": 20854,
      "sermons": 20855,
      "tomato": 20856,
      "bland": 20857,
      "stimulation": 20858,
      "avenues": 20859,
      "##eux": 20860,
      "spreads": 20861,
      "scarlett": 20862,
      "fern": 20863,
      "pentagon": 20864,
      "assert": 20865,
      "baird": 20866,
      "chesapeake": 20867,
      "ir": 20868,
      "calmed": 20869,
      "distortion": 20870,
      "fatalities": 20871,
      "##olis": 20872,
      "correctional": 20873,
      "pricing": 20874,
      "##astic": 20875,
      "##gina": 20876,
      "prom": 20877,
      "dammit": 20878,
      "ying": 20879,
      "collaborate": 20880,
      "##chia": 20881,
      "welterweight": 20882,
      "33rd": 20883,
      "pointer": 20884,
      "substitution": 20885,
      "bonded": 20886,
      "umpire": 20887,
      "communicating": 20888,
      "multitude": 20889,
      "paddle": 20890,
      "##obe": 20891,
      "federally": 20892,
      "intimacy": 20893,
      "##insky": 20894,
      "betray": 20895,
      "ssr": 20896,
      "##lett": 20897,
      "##lean": 20898,
      "##lves": 20899,
      "##therapy": 20900,
      "airbus": 20901,
      "##tery": 20902,
      "functioned": 20903,
      "ud": 20904,
      "bearer": 20905,
      "biomedical": 20906,
      "netflix": 20907,
      "##hire": 20908,
      "##nca": 20909,
      "condom": 20910,
      "brink": 20911,
      "ik": 20912,
      "##nical": 20913,
      "macy": 20914,
      "##bet": 20915,
      "flap": 20916,
      "gma": 20917,
      "experimented": 20918,
      "jelly": 20919,
      "lavender": 20920,
      "##icles": 20921,
      "##ulia": 20922,
      "munro": 20923,
      "##mian": 20924,
      "##tial": 20925,
      "rye": 20926,
      "##rle": 20927,
      "60th": 20928,
      "gigs": 20929,
      "hottest": 20930,
      "rotated": 20931,
      "predictions": 20932,
      "fuji": 20933,
      "bu": 20934,
      "##erence": 20935,
      "##omi": 20936,
      "barangay": 20937,
      "##fulness": 20938,
      "##sas": 20939,
      "clocks": 20940,
      "##rwood": 20941,
      "##liness": 20942,
      "cereal": 20943,
      "roe": 20944,
      "wight": 20945,
      "decker": 20946,
      "uttered": 20947,
      "babu": 20948,
      "onion": 20949,
      "xml": 20950,
      "forcibly": 20951,
      "##df": 20952,
      "petra": 20953,
      "sarcasm": 20954,
      "hartley": 20955,
      "peeled": 20956,
      "storytelling": 20957,
      "##42": 20958,
      "##xley": 20959,
      "##ysis": 20960,
      "##ffa": 20961,
      "fibre": 20962,
      "kiel": 20963,
      "auditor": 20964,
      "fig": 20965,
      "harald": 20966,
      "greenville": 20967,
      "##berries": 20968,
      "geographically": 20969,
      "nell": 20970,
      "quartz": 20971,
      "##athic": 20972,
      "cemeteries": 20973,
      "##lr": 20974,
      "crossings": 20975,
      "nah": 20976,
      "holloway": 20977,
      "reptiles": 20978,
      "chun": 20979,
      "sichuan": 20980,
      "snowy": 20981,
      "660": 20982,
      "corrections": 20983,
      "##ivo": 20984,
      "zheng": 20985,
      "ambassadors": 20986,
      "blacksmith": 20987,
      "fielded": 20988,
      "fluids": 20989,
      "hardcover": 20990,
      "turnover": 20991,
      "medications": 20992,
      "melvin": 20993,
      "academies": 20994,
      "##erton": 20995,
      "ro": 20996,
      "roach": 20997,
      "absorbing": 20998,
      "spaniards": 20999,
      "colton": 21000,
      "##founded": 21001,
      "outsider": 21002,
      "espionage": 21003,
      "kelsey": 21004,
      "245": 21005,
      "edible": 21006,
      "##ulf": 21007,
      "dora": 21008,
      "establishes": 21009,
      "##sham": 21010,
      "##tries": 21011,
      "contracting": 21012,
      "##tania": 21013,
      "cinematic": 21014,
      "costello": 21015,
      "nesting": 21016,
      "##uron": 21017,
      "connolly": 21018,
      "duff": 21019,
      "##nology": 21020,
      "mma": 21021,
      "##mata": 21022,
      "fergus": 21023,
      "sexes": 21024,
      "gi": 21025,
      "optics": 21026,
      "spectator": 21027,
      "woodstock": 21028,
      "banning": 21029,
      "##hee": 21030,
      "##fle": 21031,
      "differentiate": 21032,
      "outfielder": 21033,
      "refinery": 21034,
      "226": 21035,
      "312": 21036,
      "gerhard": 21037,
      "horde": 21038,
      "lair": 21039,
      "drastically": 21040,
      "##udi": 21041,
      "landfall": 21042,
      "##cheng": 21043,
      "motorsport": 21044,
      "odi": 21045,
      "##achi": 21046,
      "predominant": 21047,
      "quay": 21048,
      "skins": 21049,
      "##ental": 21050,
      "edna": 21051,
      "harshly": 21052,
      "complementary": 21053,
      "murdering": 21054,
      "##aves": 21055,
      "wreckage": 21056,
      "##90": 21057,
      "ono": 21058,
      "outstretched": 21059,
      "lennox": 21060,
      "munitions": 21061,
      "galen": 21062,
      "reconcile": 21063,
      "470": 21064,
      "scalp": 21065,
      "bicycles": 21066,
      "gillespie": 21067,
      "questionable": 21068,
      "rosenberg": 21069,
      "guillermo": 21070,
      "hostel": 21071,
      "jarvis": 21072,
      "kabul": 21073,
      "volvo": 21074,
      "opium": 21075,
      "yd": 21076,
      "##twined": 21077,
      "abuses": 21078,
      "decca": 21079,
      "outpost": 21080,
      "##cino": 21081,
      "sensible": 21082,
      "neutrality": 21083,
      "##64": 21084,
      "ponce": 21085,
      "anchorage": 21086,
      "atkins": 21087,
      "turrets": 21088,
      "inadvertently": 21089,
      "disagree": 21090,
      "libre": 21091,
      "vodka": 21092,
      "reassuring": 21093,
      "weighs": 21094,
      "##yal": 21095,
      "glide": 21096,
      "jumper": 21097,
      "ceilings": 21098,
      "repertory": 21099,
      "outs": 21100,
      "stain": 21101,
      "##bial": 21102,
      "envy": 21103,
      "##ucible": 21104,
      "smashing": 21105,
      "heightened": 21106,
      "policing": 21107,
      "hyun": 21108,
      "mixes": 21109,
      "lai": 21110,
      "prima": 21111,
      "##ples": 21112,
      "celeste": 21113,
      "##bina": 21114,
      "lucrative": 21115,
      "intervened": 21116,
      "kc": 21117,
      "manually": 21118,
      "##rned": 21119,
      "stature": 21120,
      "staffed": 21121,
      "bun": 21122,
      "bastards": 21123,
      "nairobi": 21124,
      "priced": 21125,
      "##auer": 21126,
      "thatcher": 21127,
      "##kia": 21128,
      "tripped": 21129,
      "comune": 21130,
      "##ogan": 21131,
      "##pled": 21132,
      "brasil": 21133,
      "incentives": 21134,
      "emanuel": 21135,
      "hereford": 21136,
      "musica": 21137,
      "##kim": 21138,
      "benedictine": 21139,
      "biennale": 21140,
      "##lani": 21141,
      "eureka": 21142,
      "gardiner": 21143,
      "rb": 21144,
      "knocks": 21145,
      "sha": 21146,
      "##ael": 21147,
      "##elled": 21148,
      "##onate": 21149,
      "efficacy": 21150,
      "ventura": 21151,
      "masonic": 21152,
      "sanford": 21153,
      "maize": 21154,
      "leverage": 21155,
      "##feit": 21156,
      "capacities": 21157,
      "santana": 21158,
      "##aur": 21159,
      "novelty": 21160,
      "vanilla": 21161,
      "##cter": 21162,
      "##tour": 21163,
      "benin": 21164,
      "##oir": 21165,
      "##rain": 21166,
      "neptune": 21167,
      "drafting": 21168,
      "tallinn": 21169,
      "##cable": 21170,
      "humiliation": 21171,
      "##boarding": 21172,
      "schleswig": 21173,
      "fabian": 21174,
      "bernardo": 21175,
      "liturgy": 21176,
      "spectacle": 21177,
      "sweeney": 21178,
      "pont": 21179,
      "routledge": 21180,
      "##tment": 21181,
      "cosmos": 21182,
      "ut": 21183,
      "hilt": 21184,
      "sleek": 21185,
      "universally": 21186,
      "##eville": 21187,
      "##gawa": 21188,
      "typed": 21189,
      "##dry": 21190,
      "favors": 21191,
      "allegheny": 21192,
      "glaciers": 21193,
      "##rly": 21194,
      "recalling": 21195,
      "aziz": 21196,
      "##log": 21197,
      "parasite": 21198,
      "requiem": 21199,
      "auf": 21200,
      "##berto": 21201,
      "##llin": 21202,
      "illumination": 21203,
      "##breaker": 21204,
      "##issa": 21205,
      "festivities": 21206,
      "bows": 21207,
      "govern": 21208,
      "vibe": 21209,
      "vp": 21210,
      "333": 21211,
      "sprawled": 21212,
      "larson": 21213,
      "pilgrim": 21214,
      "bwf": 21215,
      "leaping": 21216,
      "##rts": 21217,
      "##ssel": 21218,
      "alexei": 21219,
      "greyhound": 21220,
      "hoarse": 21221,
      "##dler": 21222,
      "##oration": 21223,
      "seneca": 21224,
      "##cule": 21225,
      "gaping": 21226,
      "##ulously": 21227,
      "##pura": 21228,
      "cinnamon": 21229,
      "##gens": 21230,
      "##rricular": 21231,
      "craven": 21232,
      "fantasies": 21233,
      "houghton": 21234,
      "engined": 21235,
      "reigned": 21236,
      "dictator": 21237,
      "supervising": 21238,
      "##oris": 21239,
      "bogota": 21240,
      "commentaries": 21241,
      "unnatural": 21242,
      "fingernails": 21243,
      "spirituality": 21244,
      "tighten": 21245,
      "##tm": 21246,
      "canadiens": 21247,
      "protesting": 21248,
      "intentional": 21249,
      "cheers": 21250,
      "sparta": 21251,
      "##ytic": 21252,
      "##iere": 21253,
      "##zine": 21254,
      "widen": 21255,
      "belgarath": 21256,
      "controllers": 21257,
      "dodd": 21258,
      "iaaf": 21259,
      "navarre": 21260,
      "##ication": 21261,
      "defect": 21262,
      "squire": 21263,
      "steiner": 21264,
      "whisky": 21265,
      "##mins": 21266,
      "560": 21267,
      "inevitably": 21268,
      "tome": 21269,
      "##gold": 21270,
      "chew": 21271,
      "##uid": 21272,
      "##lid": 21273,
      "elastic": 21274,
      "##aby": 21275,
      "streaked": 21276,
      "alliances": 21277,
      "jailed": 21278,
      "regal": 21279,
      "##ined": 21280,
      "##phy": 21281,
      "czechoslovak": 21282,
      "narration": 21283,
      "absently": 21284,
      "##uld": 21285,
      "bluegrass": 21286,
      "guangdong": 21287,
      "quran": 21288,
      "criticizing": 21289,
      "hose": 21290,
      "hari": 21291,
      "##liest": 21292,
      "##owa": 21293,
      "skier": 21294,
      "streaks": 21295,
      "deploy": 21296,
      "##lom": 21297,
      "raft": 21298,
      "bose": 21299,
      "dialed": 21300,
      "huff": 21301,
      "##eira": 21302,
      "haifa": 21303,
      "simplest": 21304,
      "bursting": 21305,
      "endings": 21306,
      "ib": 21307,
      "sultanate": 21308,
      "##titled": 21309,
      "franks": 21310,
      "whitman": 21311,
      "ensures": 21312,
      "sven": 21313,
      "##ggs": 21314,
      "collaborators": 21315,
      "forster": 21316,
      "organising": 21317,
      "ui": 21318,
      "banished": 21319,
      "napier": 21320,
      "injustice": 21321,
      "teller": 21322,
      "layered": 21323,
      "thump": 21324,
      "##otti": 21325,
      "roc": 21326,
      "battleships": 21327,
      "evidenced": 21328,
      "fugitive": 21329,
      "sadie": 21330,
      "robotics": 21331,
      "##roud": 21332,
      "equatorial": 21333,
      "geologist": 21334,
      "##iza": 21335,
      "yielding": 21336,
      "##bron": 21337,
      "##sr": 21338,
      "internationale": 21339,
      "mecca": 21340,
      "##diment": 21341,
      "sbs": 21342,
      "skyline": 21343,
      "toad": 21344,
      "uploaded": 21345,
      "reflective": 21346,
      "undrafted": 21347,
      "lal": 21348,
      "leafs": 21349,
      "bayern": 21350,
      "##dai": 21351,
      "lakshmi": 21352,
      "shortlisted": 21353,
      "##stick": 21354,
      "##wicz": 21355,
      "camouflage": 21356,
      "donate": 21357,
      "af": 21358,
      "christi": 21359,
      "lau": 21360,
      "##acio": 21361,
      "disclosed": 21362,
      "nemesis": 21363,
      "1761": 21364,
      "assemble": 21365,
      "straining": 21366,
      "northamptonshire": 21367,
      "tal": 21368,
      "##asi": 21369,
      "bernardino": 21370,
      "premature": 21371,
      "heidi": 21372,
      "42nd": 21373,
      "coefficients": 21374,
      "galactic": 21375,
      "reproduce": 21376,
      "buzzed": 21377,
      "sensations": 21378,
      "zionist": 21379,
      "monsieur": 21380,
      "myrtle": 21381,
      "##eme": 21382,
      "archery": 21383,
      "strangled": 21384,
      "musically": 21385,
      "viewpoint": 21386,
      "antiquities": 21387,
      "bei": 21388,
      "trailers": 21389,
      "seahawks": 21390,
      "cured": 21391,
      "pee": 21392,
      "preferring": 21393,
      "tasmanian": 21394,
      "lange": 21395,
      "sul": 21396,
      "##mail": 21397,
      "##working": 21398,
      "colder": 21399,
      "overland": 21400,
      "lucivar": 21401,
      "massey": 21402,
      "gatherings": 21403,
      "haitian": 21404,
      "##smith": 21405,
      "disapproval": 21406,
      "flaws": 21407,
      "##cco": 21408,
      "##enbach": 21409,
      "1766": 21410,
      "npr": 21411,
      "##icular": 21412,
      "boroughs": 21413,
      "creole": 21414,
      "forums": 21415,
      "techno": 21416,
      "1755": 21417,
      "dent": 21418,
      "abdominal": 21419,
      "streetcar": 21420,
      "##eson": 21421,
      "##stream": 21422,
      "procurement": 21423,
      "gemini": 21424,
      "predictable": 21425,
      "##tya": 21426,
      "acheron": 21427,
      "christoph": 21428,
      "feeder": 21429,
      "fronts": 21430,
      "vendor": 21431,
      "bernhard": 21432,
      "jammu": 21433,
      "tumors": 21434,
      "slang": 21435,
      "##uber": 21436,
      "goaltender": 21437,
      "twists": 21438,
      "curving": 21439,
      "manson": 21440,
      "vuelta": 21441,
      "mer": 21442,
      "peanut": 21443,
      "confessions": 21444,
      "pouch": 21445,
      "unpredictable": 21446,
      "allowance": 21447,
      "theodor": 21448,
      "vascular": 21449,
      "##factory": 21450,
      "bala": 21451,
      "authenticity": 21452,
      "metabolic": 21453,
      "coughing": 21454,
      "nanjing": 21455,
      "##cea": 21456,
      "pembroke": 21457,
      "##bard": 21458,
      "splendid": 21459,
      "36th": 21460,
      "ff": 21461,
      "hourly": 21462,
      "##ahu": 21463,
      "elmer": 21464,
      "handel": 21465,
      "##ivate": 21466,
      "awarding": 21467,
      "thrusting": 21468,
      "dl": 21469,
      "experimentation": 21470,
      "##hesion": 21471,
      "##46": 21472,
      "caressed": 21473,
      "entertained": 21474,
      "steak": 21475,
      "##rangle": 21476,
      "biologist": 21477,
      "orphans": 21478,
      "baroness": 21479,
      "oyster": 21480,
      "stepfather": 21481,
      "##dridge": 21482,
      "mirage": 21483,
      "reefs": 21484,
      "speeding": 21485,
      "##31": 21486,
      "barons": 21487,
      "1764": 21488,
      "227": 21489,
      "inhabit": 21490,
      "preached": 21491,
      "repealed": 21492,
      "##tral": 21493,
      "honoring": 21494,
      "boogie": 21495,
      "captives": 21496,
      "administer": 21497,
      "johanna": 21498,
      "##imate": 21499,
      "gel": 21500,
      "suspiciously": 21501,
      "1767": 21502,
      "sobs": 21503,
      "##dington": 21504,
      "backbone": 21505,
      "hayward": 21506,
      "garry": 21507,
      "##folding": 21508,
      "##nesia": 21509,
      "maxi": 21510,
      "##oof": 21511,
      "##ppe": 21512,
      "ellison": 21513,
      "galileo": 21514,
      "##stand": 21515,
      "crimea": 21516,
      "frenzy": 21517,
      "amour": 21518,
      "bumper": 21519,
      "matrices": 21520,
      "natalia": 21521,
      "baking": 21522,
      "garth": 21523,
      "palestinians": 21524,
      "##grove": 21525,
      "smack": 21526,
      "conveyed": 21527,
      "ensembles": 21528,
      "gardening": 21529,
      "##manship": 21530,
      "##rup": 21531,
      "##stituting": 21532,
      "1640": 21533,
      "harvesting": 21534,
      "topography": 21535,
      "jing": 21536,
      "shifters": 21537,
      "dormitory": 21538,
      "##carriage": 21539,
      "##lston": 21540,
      "ist": 21541,
      "skulls": 21542,
      "##stadt": 21543,
      "dolores": 21544,
      "jewellery": 21545,
      "sarawak": 21546,
      "##wai": 21547,
      "##zier": 21548,
      "fences": 21549,
      "christy": 21550,
      "confinement": 21551,
      "tumbling": 21552,
      "credibility": 21553,
      "fir": 21554,
      "stench": 21555,
      "##bria": 21556,
      "##plication": 21557,
      "##nged": 21558,
      "##sam": 21559,
      "virtues": 21560,
      "##belt": 21561,
      "marjorie": 21562,
      "pba": 21563,
      "##eem": 21564,
      "##made": 21565,
      "celebrates": 21566,
      "schooner": 21567,
      "agitated": 21568,
      "barley": 21569,
      "fulfilling": 21570,
      "anthropologist": 21571,
      "##pro": 21572,
      "restrict": 21573,
      "novi": 21574,
      "regulating": 21575,
      "##nent": 21576,
      "padres": 21577,
      "##rani": 21578,
      "##hesive": 21579,
      "loyola": 21580,
      "tabitha": 21581,
      "milky": 21582,
      "olson": 21583,
      "proprietor": 21584,
      "crambidae": 21585,
      "guarantees": 21586,
      "intercollegiate": 21587,
      "ljubljana": 21588,
      "hilda": 21589,
      "##sko": 21590,
      "ignorant": 21591,
      "hooded": 21592,
      "##lts": 21593,
      "sardinia": 21594,
      "##lidae": 21595,
      "##vation": 21596,
      "frontman": 21597,
      "privileged": 21598,
      "witchcraft": 21599,
      "##gp": 21600,
      "jammed": 21601,
      "laude": 21602,
      "poking": 21603,
      "##than": 21604,
      "bracket": 21605,
      "amazement": 21606,
      "yunnan": 21607,
      "##erus": 21608,
      "maharaja": 21609,
      "linnaeus": 21610,
      "264": 21611,
      "commissioning": 21612,
      "milano": 21613,
      "peacefully": 21614,
      "##logies": 21615,
      "akira": 21616,
      "rani": 21617,
      "regulator": 21618,
      "##36": 21619,
      "grasses": 21620,
      "##rance": 21621,
      "luzon": 21622,
      "crows": 21623,
      "compiler": 21624,
      "gretchen": 21625,
      "seaman": 21626,
      "edouard": 21627,
      "tab": 21628,
      "buccaneers": 21629,
      "ellington": 21630,
      "hamlets": 21631,
      "whig": 21632,
      "socialists": 21633,
      "##anto": 21634,
      "directorial": 21635,
      "easton": 21636,
      "mythological": 21637,
      "##kr": 21638,
      "##vary": 21639,
      "rhineland": 21640,
      "semantic": 21641,
      "taut": 21642,
      "dune": 21643,
      "inventions": 21644,
      "succeeds": 21645,
      "##iter": 21646,
      "replication": 21647,
      "branched": 21648,
      "##pired": 21649,
      "jul": 21650,
      "prosecuted": 21651,
      "kangaroo": 21652,
      "penetrated": 21653,
      "##avian": 21654,
      "middlesbrough": 21655,
      "doses": 21656,
      "bleak": 21657,
      "madam": 21658,
      "predatory": 21659,
      "relentless": 21660,
      "##vili": 21661,
      "reluctance": 21662,
      "##vir": 21663,
      "hailey": 21664,
      "crore": 21665,
      "silvery": 21666,
      "1759": 21667,
      "monstrous": 21668,
      "swimmers": 21669,
      "transmissions": 21670,
      "hawthorn": 21671,
      "informing": 21672,
      "##eral": 21673,
      "toilets": 21674,
      "caracas": 21675,
      "crouch": 21676,
      "kb": 21677,
      "##sett": 21678,
      "295": 21679,
      "cartel": 21680,
      "hadley": 21681,
      "##aling": 21682,
      "alexia": 21683,
      "yvonne": 21684,
      "##biology": 21685,
      "cinderella": 21686,
      "eton": 21687,
      "superb": 21688,
      "blizzard": 21689,
      "stabbing": 21690,
      "industrialist": 21691,
      "maximus": 21692,
      "##gm": 21693,
      "##orus": 21694,
      "groves": 21695,
      "maud": 21696,
      "clade": 21697,
      "oversized": 21698,
      "comedic": 21699,
      "##bella": 21700,
      "rosen": 21701,
      "nomadic": 21702,
      "fulham": 21703,
      "montane": 21704,
      "beverages": 21705,
      "galaxies": 21706,
      "redundant": 21707,
      "swarm": 21708,
      "##rot": 21709,
      "##folia": 21710,
      "##llis": 21711,
      "buckinghamshire": 21712,
      "fen": 21713,
      "bearings": 21714,
      "bahadur": 21715,
      "##rom": 21716,
      "gilles": 21717,
      "phased": 21718,
      "dynamite": 21719,
      "faber": 21720,
      "benoit": 21721,
      "vip": 21722,
      "##ount": 21723,
      "##wd": 21724,
      "booking": 21725,
      "fractured": 21726,
      "tailored": 21727,
      "anya": 21728,
      "spices": 21729,
      "westwood": 21730,
      "cairns": 21731,
      "auditions": 21732,
      "inflammation": 21733,
      "steamed": 21734,
      "##rocity": 21735,
      "##acion": 21736,
      "##urne": 21737,
      "skyla": 21738,
      "thereof": 21739,
      "watford": 21740,
      "torment": 21741,
      "archdeacon": 21742,
      "transforms": 21743,
      "lulu": 21744,
      "demeanor": 21745,
      "fucked": 21746,
      "serge": 21747,
      "##sor": 21748,
      "mckenna": 21749,
      "minas": 21750,
      "entertainer": 21751,
      "##icide": 21752,
      "caress": 21753,
      "originate": 21754,
      "residue": 21755,
      "##sty": 21756,
      "1740": 21757,
      "##ilised": 21758,
      "##org": 21759,
      "beech": 21760,
      "##wana": 21761,
      "subsidies": 21762,
      "##ghton": 21763,
      "emptied": 21764,
      "gladstone": 21765,
      "ru": 21766,
      "firefighters": 21767,
      "voodoo": 21768,
      "##rcle": 21769,
      "het": 21770,
      "nightingale": 21771,
      "tamara": 21772,
      "edmond": 21773,
      "ingredient": 21774,
      "weaknesses": 21775,
      "silhouette": 21776,
      "285": 21777,
      "compatibility": 21778,
      "withdrawing": 21779,
      "hampson": 21780,
      "##mona": 21781,
      "anguish": 21782,
      "giggling": 21783,
      "##mber": 21784,
      "bookstore": 21785,
      "##jiang": 21786,
      "southernmost": 21787,
      "tilting": 21788,
      "##vance": 21789,
      "bai": 21790,
      "economical": 21791,
      "rf": 21792,
      "briefcase": 21793,
      "dreadful": 21794,
      "hinted": 21795,
      "projections": 21796,
      "shattering": 21797,
      "totaling": 21798,
      "##rogate": 21799,
      "analogue": 21800,
      "indicted": 21801,
      "periodical": 21802,
      "fullback": 21803,
      "##dman": 21804,
      "haynes": 21805,
      "##tenberg": 21806,
      "##ffs": 21807,
      "##ishment": 21808,
      "1745": 21809,
      "thirst": 21810,
      "stumble": 21811,
      "penang": 21812,
      "vigorous": 21813,
      "##ddling": 21814,
      "##kor": 21815,
      "##lium": 21816,
      "octave": 21817,
      "##ove": 21818,
      "##enstein": 21819,
      "##inen": 21820,
      "##ones": 21821,
      "siberian": 21822,
      "##uti": 21823,
      "cbn": 21824,
      "repeal": 21825,
      "swaying": 21826,
      "##vington": 21827,
      "khalid": 21828,
      "tanaka": 21829,
      "unicorn": 21830,
      "otago": 21831,
      "plastered": 21832,
      "lobe": 21833,
      "riddle": 21834,
      "##rella": 21835,
      "perch": 21836,
      "##ishing": 21837,
      "croydon": 21838,
      "filtered": 21839,
      "graeme": 21840,
      "tripoli": 21841,
      "##ossa": 21842,
      "crocodile": 21843,
      "##chers": 21844,
      "sufi": 21845,
      "mined": 21846,
      "##tung": 21847,
      "inferno": 21848,
      "lsu": 21849,
      "##phi": 21850,
      "swelled": 21851,
      "utilizes": 21852,
      "£2": 21853,
      "cale": 21854,
      "periodicals": 21855,
      "styx": 21856,
      "hike": 21857,
      "informally": 21858,
      "coop": 21859,
      "lund": 21860,
      "##tidae": 21861,
      "ala": 21862,
      "hen": 21863,
      "qui": 21864,
      "transformations": 21865,
      "disposed": 21866,
      "sheath": 21867,
      "chickens": 21868,
      "##cade": 21869,
      "fitzroy": 21870,
      "sas": 21871,
      "silesia": 21872,
      "unacceptable": 21873,
      "odisha": 21874,
      "1650": 21875,
      "sabrina": 21876,
      "pe": 21877,
      "spokane": 21878,
      "ratios": 21879,
      "athena": 21880,
      "massage": 21881,
      "shen": 21882,
      "dilemma": 21883,
      "##drum": 21884,
      "##riz": 21885,
      "##hul": 21886,
      "corona": 21887,
      "doubtful": 21888,
      "niall": 21889,
      "##pha": 21890,
      "##bino": 21891,
      "fines": 21892,
      "cite": 21893,
      "acknowledging": 21894,
      "bangor": 21895,
      "ballard": 21896,
      "bathurst": 21897,
      "##resh": 21898,
      "huron": 21899,
      "mustered": 21900,
      "alzheimer": 21901,
      "garments": 21902,
      "kinase": 21903,
      "tyre": 21904,
      "warship": 21905,
      "##cp": 21906,
      "flashback": 21907,
      "pulmonary": 21908,
      "braun": 21909,
      "cheat": 21910,
      "kamal": 21911,
      "cyclists": 21912,
      "constructions": 21913,
      "grenades": 21914,
      "ndp": 21915,
      "traveller": 21916,
      "excuses": 21917,
      "stomped": 21918,
      "signalling": 21919,
      "trimmed": 21920,
      "futsal": 21921,
      "mosques": 21922,
      "relevance": 21923,
      "##wine": 21924,
      "wta": 21925,
      "##23": 21926,
      "##vah": 21927,
      "##lter": 21928,
      "hoc": 21929,
      "##riding": 21930,
      "optimistic": 21931,
      "##´s": 21932,
      "deco": 21933,
      "sim": 21934,
      "interacting": 21935,
      "rejecting": 21936,
      "moniker": 21937,
      "waterways": 21938,
      "##ieri": 21939,
      "##oku": 21940,
      "mayors": 21941,
      "gdansk": 21942,
      "outnumbered": 21943,
      "pearls": 21944,
      "##ended": 21945,
      "##hampton": 21946,
      "fairs": 21947,
      "totals": 21948,
      "dominating": 21949,
      "262": 21950,
      "notions": 21951,
      "stairway": 21952,
      "compiling": 21953,
      "pursed": 21954,
      "commodities": 21955,
      "grease": 21956,
      "yeast": 21957,
      "##jong": 21958,
      "carthage": 21959,
      "griffiths": 21960,
      "residual": 21961,
      "amc": 21962,
      "contraction": 21963,
      "laird": 21964,
      "sapphire": 21965,
      "##marine": 21966,
      "##ivated": 21967,
      "amalgamation": 21968,
      "dissolve": 21969,
      "inclination": 21970,
      "lyle": 21971,
      "packaged": 21972,
      "altitudes": 21973,
      "suez": 21974,
      "canons": 21975,
      "graded": 21976,
      "lurched": 21977,
      "narrowing": 21978,
      "boasts": 21979,
      "guise": 21980,
      "wed": 21981,
      "enrico": 21982,
      "##ovsky": 21983,
      "rower": 21984,
      "scarred": 21985,
      "bree": 21986,
      "cub": 21987,
      "iberian": 21988,
      "protagonists": 21989,
      "bargaining": 21990,
      "proposing": 21991,
      "trainers": 21992,
      "voyages": 21993,
      "vans": 21994,
      "fishes": 21995,
      "##aea": 21996,
      "##ivist": 21997,
      "##verance": 21998,
      "encryption": 21999,
      "artworks": 22000,
      "kazan": 22001,
      "sabre": 22002,
      "cleopatra": 22003,
      "hepburn": 22004,
      "rotting": 22005,
      "supremacy": 22006,
      "mecklenburg": 22007,
      "##brate": 22008,
      "burrows": 22009,
      "hazards": 22010,
      "outgoing": 22011,
      "flair": 22012,
      "organizes": 22013,
      "##ctions": 22014,
      "scorpion": 22015,
      "##usions": 22016,
      "boo": 22017,
      "234": 22018,
      "chevalier": 22019,
      "dunedin": 22020,
      "slapping": 22021,
      "##34": 22022,
      "ineligible": 22023,
      "pensions": 22024,
      "##38": 22025,
      "##omic": 22026,
      "manufactures": 22027,
      "emails": 22028,
      "bismarck": 22029,
      "238": 22030,
      "weakening": 22031,
      "blackish": 22032,
      "ding": 22033,
      "mcgee": 22034,
      "quo": 22035,
      "##rling": 22036,
      "northernmost": 22037,
      "xx": 22038,
      "manpower": 22039,
      "greed": 22040,
      "sampson": 22041,
      "clicking": 22042,
      "##ange": 22043,
      "##horpe": 22044,
      "##inations": 22045,
      "##roving": 22046,
      "torre": 22047,
      "##eptive": 22048,
      "##moral": 22049,
      "symbolism": 22050,
      "38th": 22051,
      "asshole": 22052,
      "meritorious": 22053,
      "outfits": 22054,
      "splashed": 22055,
      "biographies": 22056,
      "sprung": 22057,
      "astros": 22058,
      "##tale": 22059,
      "302": 22060,
      "737": 22061,
      "filly": 22062,
      "raoul": 22063,
      "nw": 22064,
      "tokugawa": 22065,
      "linden": 22066,
      "clubhouse": 22067,
      "##apa": 22068,
      "tracts": 22069,
      "romano": 22070,
      "##pio": 22071,
      "putin": 22072,
      "tags": 22073,
      "##note": 22074,
      "chained": 22075,
      "dickson": 22076,
      "gunshot": 22077,
      "moe": 22078,
      "gunn": 22079,
      "rashid": 22080,
      "##tails": 22081,
      "zipper": 22082,
      "##bas": 22083,
      "##nea": 22084,
      "contrasted": 22085,
      "##ply": 22086,
      "##udes": 22087,
      "plum": 22088,
      "pharaoh": 22089,
      "##pile": 22090,
      "aw": 22091,
      "comedies": 22092,
      "ingrid": 22093,
      "sandwiches": 22094,
      "subdivisions": 22095,
      "1100": 22096,
      "mariana": 22097,
      "nokia": 22098,
      "kamen": 22099,
      "hz": 22100,
      "delaney": 22101,
      "veto": 22102,
      "herring": 22103,
      "##words": 22104,
      "possessive": 22105,
      "outlines": 22106,
      "##roup": 22107,
      "siemens": 22108,
      "stairwell": 22109,
      "rc": 22110,
      "gallantry": 22111,
      "messiah": 22112,
      "palais": 22113,
      "yells": 22114,
      "233": 22115,
      "zeppelin": 22116,
      "##dm": 22117,
      "bolivar": 22118,
      "##cede": 22119,
      "smackdown": 22120,
      "mckinley": 22121,
      "##mora": 22122,
      "##yt": 22123,
      "muted": 22124,
      "geologic": 22125,
      "finely": 22126,
      "unitary": 22127,
      "avatar": 22128,
      "hamas": 22129,
      "maynard": 22130,
      "rees": 22131,
      "bog": 22132,
      "contrasting": 22133,
      "##rut": 22134,
      "liv": 22135,
      "chico": 22136,
      "disposition": 22137,
      "pixel": 22138,
      "##erate": 22139,
      "becca": 22140,
      "dmitry": 22141,
      "yeshiva": 22142,
      "narratives": 22143,
      "##lva": 22144,
      "##ulton": 22145,
      "mercenary": 22146,
      "sharpe": 22147,
      "tempered": 22148,
      "navigate": 22149,
      "stealth": 22150,
      "amassed": 22151,
      "keynes": 22152,
      "##lini": 22153,
      "untouched": 22154,
      "##rrie": 22155,
      "havoc": 22156,
      "lithium": 22157,
      "##fighting": 22158,
      "abyss": 22159,
      "graf": 22160,
      "southward": 22161,
      "wolverine": 22162,
      "balloons": 22163,
      "implements": 22164,
      "ngos": 22165,
      "transitions": 22166,
      "##icum": 22167,
      "ambushed": 22168,
      "concacaf": 22169,
      "dormant": 22170,
      "economists": 22171,
      "##dim": 22172,
      "costing": 22173,
      "csi": 22174,
      "rana": 22175,
      "universite": 22176,
      "boulders": 22177,
      "verity": 22178,
      "##llon": 22179,
      "collin": 22180,
      "mellon": 22181,
      "misses": 22182,
      "cypress": 22183,
      "fluorescent": 22184,
      "lifeless": 22185,
      "spence": 22186,
      "##ulla": 22187,
      "crewe": 22188,
      "shepard": 22189,
      "pak": 22190,
      "revelations": 22191,
      "##م": 22192,
      "jolly": 22193,
      "gibbons": 22194,
      "paw": 22195,
      "##dro": 22196,
      "##quel": 22197,
      "freeing": 22198,
      "##test": 22199,
      "shack": 22200,
      "fries": 22201,
      "palatine": 22202,
      "##51": 22203,
      "##hiko": 22204,
      "accompaniment": 22205,
      "cruising": 22206,
      "recycled": 22207,
      "##aver": 22208,
      "erwin": 22209,
      "sorting": 22210,
      "synthesizers": 22211,
      "dyke": 22212,
      "realities": 22213,
      "sg": 22214,
      "strides": 22215,
      "enslaved": 22216,
      "wetland": 22217,
      "##ghan": 22218,
      "competence": 22219,
      "gunpowder": 22220,
      "grassy": 22221,
      "maroon": 22222,
      "reactors": 22223,
      "objection": 22224,
      "##oms": 22225,
      "carlson": 22226,
      "gearbox": 22227,
      "macintosh": 22228,
      "radios": 22229,
      "shelton": 22230,
      "##sho": 22231,
      "clergyman": 22232,
      "prakash": 22233,
      "254": 22234,
      "mongols": 22235,
      "trophies": 22236,
      "oricon": 22237,
      "228": 22238,
      "stimuli": 22239,
      "twenty20": 22240,
      "cantonese": 22241,
      "cortes": 22242,
      "mirrored": 22243,
      "##saurus": 22244,
      "bhp": 22245,
      "cristina": 22246,
      "melancholy": 22247,
      "##lating": 22248,
      "enjoyable": 22249,
      "nuevo": 22250,
      "##wny": 22251,
      "downfall": 22252,
      "schumacher": 22253,
      "##ind": 22254,
      "banging": 22255,
      "lausanne": 22256,
      "rumbled": 22257,
      "paramilitary": 22258,
      "reflex": 22259,
      "ax": 22260,
      "amplitude": 22261,
      "migratory": 22262,
      "##gall": 22263,
      "##ups": 22264,
      "midi": 22265,
      "barnard": 22266,
      "lastly": 22267,
      "sherry": 22268,
      "##hp": 22269,
      "##nall": 22270,
      "keystone": 22271,
      "##kra": 22272,
      "carleton": 22273,
      "slippery": 22274,
      "##53": 22275,
      "coloring": 22276,
      "foe": 22277,
      "socket": 22278,
      "otter": 22279,
      "##rgos": 22280,
      "mats": 22281,
      "##tose": 22282,
      "consultants": 22283,
      "bafta": 22284,
      "bison": 22285,
      "topping": 22286,
      "##km": 22287,
      "490": 22288,
      "primal": 22289,
      "abandonment": 22290,
      "transplant": 22291,
      "atoll": 22292,
      "hideous": 22293,
      "mort": 22294,
      "pained": 22295,
      "reproduced": 22296,
      "tae": 22297,
      "howling": 22298,
      "##turn": 22299,
      "unlawful": 22300,
      "billionaire": 22301,
      "hotter": 22302,
      "poised": 22303,
      "lansing": 22304,
      "##chang": 22305,
      "dinamo": 22306,
      "retro": 22307,
      "messing": 22308,
      "nfc": 22309,
      "domesday": 22310,
      "##mina": 22311,
      "blitz": 22312,
      "timed": 22313,
      "##athing": 22314,
      "##kley": 22315,
      "ascending": 22316,
      "gesturing": 22317,
      "##izations": 22318,
      "signaled": 22319,
      "tis": 22320,
      "chinatown": 22321,
      "mermaid": 22322,
      "savanna": 22323,
      "jameson": 22324,
      "##aint": 22325,
      "catalina": 22326,
      "##pet": 22327,
      "##hers": 22328,
      "cochrane": 22329,
      "cy": 22330,
      "chatting": 22331,
      "##kus": 22332,
      "alerted": 22333,
      "computation": 22334,
      "mused": 22335,
      "noelle": 22336,
      "majestic": 22337,
      "mohawk": 22338,
      "campo": 22339,
      "octagonal": 22340,
      "##sant": 22341,
      "##hend": 22342,
      "241": 22343,
      "aspiring": 22344,
      "##mart": 22345,
      "comprehend": 22346,
      "iona": 22347,
      "paralyzed": 22348,
      "shimmering": 22349,
      "swindon": 22350,
      "rhone": 22351,
      "##eley": 22352,
      "reputed": 22353,
      "configurations": 22354,
      "pitchfork": 22355,
      "agitation": 22356,
      "francais": 22357,
      "gillian": 22358,
      "lipstick": 22359,
      "##ilo": 22360,
      "outsiders": 22361,
      "pontifical": 22362,
      "resisting": 22363,
      "bitterness": 22364,
      "sewer": 22365,
      "rockies": 22366,
      "##edd": 22367,
      "##ucher": 22368,
      "misleading": 22369,
      "1756": 22370,
      "exiting": 22371,
      "galloway": 22372,
      "##nging": 22373,
      "risked": 22374,
      "##heart": 22375,
      "246": 22376,
      "commemoration": 22377,
      "schultz": 22378,
      "##rka": 22379,
      "integrating": 22380,
      "##rsa": 22381,
      "poses": 22382,
      "shrieked": 22383,
      "##weiler": 22384,
      "guineas": 22385,
      "gladys": 22386,
      "jerking": 22387,
      "owls": 22388,
      "goldsmith": 22389,
      "nightly": 22390,
      "penetrating": 22391,
      "##unced": 22392,
      "lia": 22393,
      "##33": 22394,
      "ignited": 22395,
      "betsy": 22396,
      "##aring": 22397,
      "##thorpe": 22398,
      "follower": 22399,
      "vigorously": 22400,
      "##rave": 22401,
      "coded": 22402,
      "kiran": 22403,
      "knit": 22404,
      "zoology": 22405,
      "tbilisi": 22406,
      "##28": 22407,
      "##bered": 22408,
      "repository": 22409,
      "govt": 22410,
      "deciduous": 22411,
      "dino": 22412,
      "growling": 22413,
      "##bba": 22414,
      "enhancement": 22415,
      "unleashed": 22416,
      "chanting": 22417,
      "pussy": 22418,
      "biochemistry": 22419,
      "##eric": 22420,
      "kettle": 22421,
      "repression": 22422,
      "toxicity": 22423,
      "nrhp": 22424,
      "##arth": 22425,
      "##kko": 22426,
      "##bush": 22427,
      "ernesto": 22428,
      "commended": 22429,
      "outspoken": 22430,
      "242": 22431,
      "mca": 22432,
      "parchment": 22433,
      "sms": 22434,
      "kristen": 22435,
      "##aton": 22436,
      "bisexual": 22437,
      "raked": 22438,
      "glamour": 22439,
      "navajo": 22440,
      "a2": 22441,
      "conditioned": 22442,
      "showcased": 22443,
      "##hma": 22444,
      "spacious": 22445,
      "youthful": 22446,
      "##esa": 22447,
      "usl": 22448,
      "appliances": 22449,
      "junta": 22450,
      "brest": 22451,
      "layne": 22452,
      "conglomerate": 22453,
      "enchanted": 22454,
      "chao": 22455,
      "loosened": 22456,
      "picasso": 22457,
      "circulating": 22458,
      "inspect": 22459,
      "montevideo": 22460,
      "##centric": 22461,
      "##kti": 22462,
      "piazza": 22463,
      "spurred": 22464,
      "##aith": 22465,
      "bari": 22466,
      "freedoms": 22467,
      "poultry": 22468,
      "stamford": 22469,
      "lieu": 22470,
      "##ect": 22471,
      "indigo": 22472,
      "sarcastic": 22473,
      "bahia": 22474,
      "stump": 22475,
      "attach": 22476,
      "dvds": 22477,
      "frankenstein": 22478,
      "lille": 22479,
      "approx": 22480,
      "scriptures": 22481,
      "pollen": 22482,
      "##script": 22483,
      "nmi": 22484,
      "overseen": 22485,
      "##ivism": 22486,
      "tides": 22487,
      "proponent": 22488,
      "newmarket": 22489,
      "inherit": 22490,
      "milling": 22491,
      "##erland": 22492,
      "centralized": 22493,
      "##rou": 22494,
      "distributors": 22495,
      "credentials": 22496,
      "drawers": 22497,
      "abbreviation": 22498,
      "##lco": 22499,
      "##xon": 22500,
      "downing": 22501,
      "uncomfortably": 22502,
      "ripe": 22503,
      "##oes": 22504,
      "erase": 22505,
      "franchises": 22506,
      "##ever": 22507,
      "populace": 22508,
      "##bery": 22509,
      "##khar": 22510,
      "decomposition": 22511,
      "pleas": 22512,
      "##tet": 22513,
      "daryl": 22514,
      "sabah": 22515,
      "##stle": 22516,
      "##wide": 22517,
      "fearless": 22518,
      "genie": 22519,
      "lesions": 22520,
      "annette": 22521,
      "##ogist": 22522,
      "oboe": 22523,
      "appendix": 22524,
      "nair": 22525,
      "dripped": 22526,
      "petitioned": 22527,
      "maclean": 22528,
      "mosquito": 22529,
      "parrot": 22530,
      "rpg": 22531,
      "hampered": 22532,
      "1648": 22533,
      "operatic": 22534,
      "reservoirs": 22535,
      "##tham": 22536,
      "irrelevant": 22537,
      "jolt": 22538,
      "summarized": 22539,
      "##fp": 22540,
      "medallion": 22541,
      "##taff": 22542,
      "##−": 22543,
      "clawed": 22544,
      "harlow": 22545,
      "narrower": 22546,
      "goddard": 22547,
      "marcia": 22548,
      "bodied": 22549,
      "fremont": 22550,
      "suarez": 22551,
      "altering": 22552,
      "tempest": 22553,
      "mussolini": 22554,
      "porn": 22555,
      "##isms": 22556,
      "sweetly": 22557,
      "oversees": 22558,
      "walkers": 22559,
      "solitude": 22560,
      "grimly": 22561,
      "shrines": 22562,
      "hk": 22563,
      "ich": 22564,
      "supervisors": 22565,
      "hostess": 22566,
      "dietrich": 22567,
      "legitimacy": 22568,
      "brushes": 22569,
      "expressive": 22570,
      "##yp": 22571,
      "dissipated": 22572,
      "##rse": 22573,
      "localized": 22574,
      "systemic": 22575,
      "##nikov": 22576,
      "gettysburg": 22577,
      "##js": 22578,
      "##uaries": 22579,
      "dialogues": 22580,
      "muttering": 22581,
      "251": 22582,
      "housekeeper": 22583,
      "sicilian": 22584,
      "discouraged": 22585,
      "##frey": 22586,
      "beamed": 22587,
      "kaladin": 22588,
      "halftime": 22589,
      "kidnap": 22590,
      "##amo": 22591,
      "##llet": 22592,
      "1754": 22593,
      "synonymous": 22594,
      "depleted": 22595,
      "instituto": 22596,
      "insulin": 22597,
      "reprised": 22598,
      "##opsis": 22599,
      "clashed": 22600,
      "##ctric": 22601,
      "interrupting": 22602,
      "radcliffe": 22603,
      "insisting": 22604,
      "medici": 22605,
      "1715": 22606,
      "ejected": 22607,
      "playfully": 22608,
      "turbulent": 22609,
      "##47": 22610,
      "starvation": 22611,
      "##rini": 22612,
      "shipment": 22613,
      "rebellious": 22614,
      "petersen": 22615,
      "verification": 22616,
      "merits": 22617,
      "##rified": 22618,
      "cakes": 22619,
      "##charged": 22620,
      "1757": 22621,
      "milford": 22622,
      "shortages": 22623,
      "spying": 22624,
      "fidelity": 22625,
      "##aker": 22626,
      "emitted": 22627,
      "storylines": 22628,
      "harvested": 22629,
      "seismic": 22630,
      "##iform": 22631,
      "cheung": 22632,
      "kilda": 22633,
      "theoretically": 22634,
      "barbie": 22635,
      "lynx": 22636,
      "##rgy": 22637,
      "##tius": 22638,
      "goblin": 22639,
      "mata": 22640,
      "poisonous": 22641,
      "##nburg": 22642,
      "reactive": 22643,
      "residues": 22644,
      "obedience": 22645,
      "##евич": 22646,
      "conjecture": 22647,
      "##rac": 22648,
      "401": 22649,
      "hating": 22650,
      "sixties": 22651,
      "kicker": 22652,
      "moaning": 22653,
      "motown": 22654,
      "##bha": 22655,
      "emancipation": 22656,
      "neoclassical": 22657,
      "##hering": 22658,
      "consoles": 22659,
      "ebert": 22660,
      "professorship": 22661,
      "##tures": 22662,
      "sustaining": 22663,
      "assaults": 22664,
      "obeyed": 22665,
      "affluent": 22666,
      "incurred": 22667,
      "tornadoes": 22668,
      "##eber": 22669,
      "##zow": 22670,
      "emphasizing": 22671,
      "highlanders": 22672,
      "cheated": 22673,
      "helmets": 22674,
      "##ctus": 22675,
      "internship": 22676,
      "terence": 22677,
      "bony": 22678,
      "executions": 22679,
      "legislators": 22680,
      "berries": 22681,
      "peninsular": 22682,
      "tinged": 22683,
      "##aco": 22684,
      "1689": 22685,
      "amplifier": 22686,
      "corvette": 22687,
      "ribbons": 22688,
      "lavish": 22689,
      "pennant": 22690,
      "##lander": 22691,
      "worthless": 22692,
      "##chfield": 22693,
      "##forms": 22694,
      "mariano": 22695,
      "pyrenees": 22696,
      "expenditures": 22697,
      "##icides": 22698,
      "chesterfield": 22699,
      "mandir": 22700,
      "tailor": 22701,
      "39th": 22702,
      "sergey": 22703,
      "nestled": 22704,
      "willed": 22705,
      "aristocracy": 22706,
      "devotees": 22707,
      "goodnight": 22708,
      "raaf": 22709,
      "rumored": 22710,
      "weaponry": 22711,
      "remy": 22712,
      "appropriations": 22713,
      "harcourt": 22714,
      "burr": 22715,
      "riaa": 22716,
      "##lence": 22717,
      "limitation": 22718,
      "unnoticed": 22719,
      "guo": 22720,
      "soaking": 22721,
      "swamps": 22722,
      "##tica": 22723,
      "collapsing": 22724,
      "tatiana": 22725,
      "descriptive": 22726,
      "brigham": 22727,
      "psalm": 22728,
      "##chment": 22729,
      "maddox": 22730,
      "##lization": 22731,
      "patti": 22732,
      "caliph": 22733,
      "##aja": 22734,
      "akron": 22735,
      "injuring": 22736,
      "serra": 22737,
      "##ganj": 22738,
      "basins": 22739,
      "##sari": 22740,
      "astonished": 22741,
      "launcher": 22742,
      "##church": 22743,
      "hilary": 22744,
      "wilkins": 22745,
      "sewing": 22746,
      "##sf": 22747,
      "stinging": 22748,
      "##fia": 22749,
      "##ncia": 22750,
      "underwood": 22751,
      "startup": 22752,
      "##ition": 22753,
      "compilations": 22754,
      "vibrations": 22755,
      "embankment": 22756,
      "jurist": 22757,
      "##nity": 22758,
      "bard": 22759,
      "juventus": 22760,
      "groundwater": 22761,
      "kern": 22762,
      "palaces": 22763,
      "helium": 22764,
      "boca": 22765,
      "cramped": 22766,
      "marissa": 22767,
      "soto": 22768,
      "##worm": 22769,
      "jae": 22770,
      "princely": 22771,
      "##ggy": 22772,
      "faso": 22773,
      "bazaar": 22774,
      "warmly": 22775,
      "##voking": 22776,
      "229": 22777,
      "pairing": 22778,
      "##lite": 22779,
      "##grate": 22780,
      "##nets": 22781,
      "wien": 22782,
      "freaked": 22783,
      "ulysses": 22784,
      "rebirth": 22785,
      "##alia": 22786,
      "##rent": 22787,
      "mummy": 22788,
      "guzman": 22789,
      "jimenez": 22790,
      "stilled": 22791,
      "##nitz": 22792,
      "trajectory": 22793,
      "tha": 22794,
      "woken": 22795,
      "archival": 22796,
      "professions": 22797,
      "##pts": 22798,
      "##pta": 22799,
      "hilly": 22800,
      "shadowy": 22801,
      "shrink": 22802,
      "##bolt": 22803,
      "norwood": 22804,
      "glued": 22805,
      "migrate": 22806,
      "stereotypes": 22807,
      "devoid": 22808,
      "##pheus": 22809,
      "625": 22810,
      "evacuate": 22811,
      "horrors": 22812,
      "infancy": 22813,
      "gotham": 22814,
      "knowles": 22815,
      "optic": 22816,
      "downloaded": 22817,
      "sachs": 22818,
      "kingsley": 22819,
      "parramatta": 22820,
      "darryl": 22821,
      "mor": 22822,
      "##onale": 22823,
      "shady": 22824,
      "commence": 22825,
      "confesses": 22826,
      "kan": 22827,
      "##meter": 22828,
      "##placed": 22829,
      "marlborough": 22830,
      "roundabout": 22831,
      "regents": 22832,
      "frigates": 22833,
      "io": 22834,
      "##imating": 22835,
      "gothenburg": 22836,
      "revoked": 22837,
      "carvings": 22838,
      "clockwise": 22839,
      "convertible": 22840,
      "intruder": 22841,
      "##sche": 22842,
      "banged": 22843,
      "##ogo": 22844,
      "vicky": 22845,
      "bourgeois": 22846,
      "##mony": 22847,
      "dupont": 22848,
      "footing": 22849,
      "##gum": 22850,
      "pd": 22851,
      "##real": 22852,
      "buckle": 22853,
      "yun": 22854,
      "penthouse": 22855,
      "sane": 22856,
      "720": 22857,
      "serviced": 22858,
      "stakeholders": 22859,
      "neumann": 22860,
      "bb": 22861,
      "##eers": 22862,
      "comb": 22863,
      "##gam": 22864,
      "catchment": 22865,
      "pinning": 22866,
      "rallies": 22867,
      "typing": 22868,
      "##elles": 22869,
      "forefront": 22870,
      "freiburg": 22871,
      "sweetie": 22872,
      "giacomo": 22873,
      "widowed": 22874,
      "goodwill": 22875,
      "worshipped": 22876,
      "aspirations": 22877,
      "midday": 22878,
      "##vat": 22879,
      "fishery": 22880,
      "##trick": 22881,
      "bournemouth": 22882,
      "turk": 22883,
      "243": 22884,
      "hearth": 22885,
      "ethanol": 22886,
      "guadalajara": 22887,
      "murmurs": 22888,
      "sl": 22889,
      "##uge": 22890,
      "afforded": 22891,
      "scripted": 22892,
      "##hta": 22893,
      "wah": 22894,
      "##jn": 22895,
      "coroner": 22896,
      "translucent": 22897,
      "252": 22898,
      "memorials": 22899,
      "puck": 22900,
      "progresses": 22901,
      "clumsy": 22902,
      "##race": 22903,
      "315": 22904,
      "candace": 22905,
      "recounted": 22906,
      "##27": 22907,
      "##slin": 22908,
      "##uve": 22909,
      "filtering": 22910,
      "##mac": 22911,
      "howl": 22912,
      "strata": 22913,
      "heron": 22914,
      "leveled": 22915,
      "##ays": 22916,
      "dubious": 22917,
      "##oja": 22918,
      "##т": 22919,
      "##wheel": 22920,
      "citations": 22921,
      "exhibiting": 22922,
      "##laya": 22923,
      "##mics": 22924,
      "##pods": 22925,
      "turkic": 22926,
      "##lberg": 22927,
      "injunction": 22928,
      "##ennial": 22929,
      "##mit": 22930,
      "antibodies": 22931,
      "##44": 22932,
      "organise": 22933,
      "##rigues": 22934,
      "cardiovascular": 22935,
      "cushion": 22936,
      "inverness": 22937,
      "##zquez": 22938,
      "dia": 22939,
      "cocoa": 22940,
      "sibling": 22941,
      "##tman": 22942,
      "##roid": 22943,
      "expanse": 22944,
      "feasible": 22945,
      "tunisian": 22946,
      "algiers": 22947,
      "##relli": 22948,
      "rus": 22949,
      "bloomberg": 22950,
      "dso": 22951,
      "westphalia": 22952,
      "bro": 22953,
      "tacoma": 22954,
      "281": 22955,
      "downloads": 22956,
      "##ours": 22957,
      "konrad": 22958,
      "duran": 22959,
      "##hdi": 22960,
      "continuum": 22961,
      "jett": 22962,
      "compares": 22963,
      "legislator": 22964,
      "secession": 22965,
      "##nable": 22966,
      "##gues": 22967,
      "##zuka": 22968,
      "translating": 22969,
      "reacher": 22970,
      "##gley": 22971,
      "##ła": 22972,
      "aleppo": 22973,
      "##agi": 22974,
      "tc": 22975,
      "orchards": 22976,
      "trapping": 22977,
      "linguist": 22978,
      "versatile": 22979,
      "drumming": 22980,
      "postage": 22981,
      "calhoun": 22982,
      "superiors": 22983,
      "##mx": 22984,
      "barefoot": 22985,
      "leary": 22986,
      "##cis": 22987,
      "ignacio": 22988,
      "alfa": 22989,
      "kaplan": 22990,
      "##rogen": 22991,
      "bratislava": 22992,
      "mori": 22993,
      "##vot": 22994,
      "disturb": 22995,
      "haas": 22996,
      "313": 22997,
      "cartridges": 22998,
      "gilmore": 22999,
      "radiated": 23000,
      "salford": 23001,
      "tunic": 23002,
      "hades": 23003,
      "##ulsive": 23004,
      "archeological": 23005,
      "delilah": 23006,
      "magistrates": 23007,
      "auditioned": 23008,
      "brewster": 23009,
      "charters": 23010,
      "empowerment": 23011,
      "blogs": 23012,
      "cappella": 23013,
      "dynasties": 23014,
      "iroquois": 23015,
      "whipping": 23016,
      "##krishna": 23017,
      "raceway": 23018,
      "truths": 23019,
      "myra": 23020,
      "weaken": 23021,
      "judah": 23022,
      "mcgregor": 23023,
      "##horse": 23024,
      "mic": 23025,
      "refueling": 23026,
      "37th": 23027,
      "burnley": 23028,
      "bosses": 23029,
      "markus": 23030,
      "premio": 23031,
      "query": 23032,
      "##gga": 23033,
      "dunbar": 23034,
      "##economic": 23035,
      "darkest": 23036,
      "lyndon": 23037,
      "sealing": 23038,
      "commendation": 23039,
      "reappeared": 23040,
      "##mun": 23041,
      "addicted": 23042,
      "ezio": 23043,
      "slaughtered": 23044,
      "satisfactory": 23045,
      "shuffle": 23046,
      "##eves": 23047,
      "##thic": 23048,
      "##uj": 23049,
      "fortification": 23050,
      "warrington": 23051,
      "##otto": 23052,
      "resurrected": 23053,
      "fargo": 23054,
      "mane": 23055,
      "##utable": 23056,
      "##lei": 23057,
      "##space": 23058,
      "foreword": 23059,
      "ox": 23060,
      "##aris": 23061,
      "##vern": 23062,
      "abrams": 23063,
      "hua": 23064,
      "##mento": 23065,
      "sakura": 23066,
      "##alo": 23067,
      "uv": 23068,
      "sentimental": 23069,
      "##skaya": 23070,
      "midfield": 23071,
      "##eses": 23072,
      "sturdy": 23073,
      "scrolls": 23074,
      "macleod": 23075,
      "##kyu": 23076,
      "entropy": 23077,
      "##lance": 23078,
      "mitochondrial": 23079,
      "cicero": 23080,
      "excelled": 23081,
      "thinner": 23082,
      "convoys": 23083,
      "perceive": 23084,
      "##oslav": 23085,
      "##urable": 23086,
      "systematically": 23087,
      "grind": 23088,
      "burkina": 23089,
      "287": 23090,
      "##tagram": 23091,
      "ops": 23092,
      "##aman": 23093,
      "guantanamo": 23094,
      "##cloth": 23095,
      "##tite": 23096,
      "forcefully": 23097,
      "wavy": 23098,
      "##jou": 23099,
      "pointless": 23100,
      "##linger": 23101,
      "##tze": 23102,
      "layton": 23103,
      "portico": 23104,
      "superficial": 23105,
      "clerical": 23106,
      "outlaws": 23107,
      "##hism": 23108,
      "burials": 23109,
      "muir": 23110,
      "##inn": 23111,
      "creditors": 23112,
      "hauling": 23113,
      "rattle": 23114,
      "##leg": 23115,
      "calais": 23116,
      "monde": 23117,
      "archers": 23118,
      "reclaimed": 23119,
      "dwell": 23120,
      "wexford": 23121,
      "hellenic": 23122,
      "falsely": 23123,
      "remorse": 23124,
      "##tek": 23125,
      "dough": 23126,
      "furnishings": 23127,
      "##uttered": 23128,
      "gabon": 23129,
      "neurological": 23130,
      "novice": 23131,
      "##igraphy": 23132,
      "contemplated": 23133,
      "pulpit": 23134,
      "nightstand": 23135,
      "saratoga": 23136,
      "##istan": 23137,
      "documenting": 23138,
      "pulsing": 23139,
      "taluk": 23140,
      "##firmed": 23141,
      "busted": 23142,
      "marital": 23143,
      "##rien": 23144,
      "disagreements": 23145,
      "wasps": 23146,
      "##yes": 23147,
      "hodge": 23148,
      "mcdonnell": 23149,
      "mimic": 23150,
      "fran": 23151,
      "pendant": 23152,
      "dhabi": 23153,
      "musa": 23154,
      "##nington": 23155,
      "congratulations": 23156,
      "argent": 23157,
      "darrell": 23158,
      "concussion": 23159,
      "losers": 23160,
      "regrets": 23161,
      "thessaloniki": 23162,
      "reversal": 23163,
      "donaldson": 23164,
      "hardwood": 23165,
      "thence": 23166,
      "achilles": 23167,
      "ritter": 23168,
      "##eran": 23169,
      "demonic": 23170,
      "jurgen": 23171,
      "prophets": 23172,
      "goethe": 23173,
      "eki": 23174,
      "classmate": 23175,
      "buff": 23176,
      "##cking": 23177,
      "yank": 23178,
      "irrational": 23179,
      "##inging": 23180,
      "perished": 23181,
      "seductive": 23182,
      "qur": 23183,
      "sourced": 23184,
      "##crat": 23185,
      "##typic": 23186,
      "mustard": 23187,
      "ravine": 23188,
      "barre": 23189,
      "horizontally": 23190,
      "characterization": 23191,
      "phylogenetic": 23192,
      "boise": 23193,
      "##dit": 23194,
      "##runner": 23195,
      "##tower": 23196,
      "brutally": 23197,
      "intercourse": 23198,
      "seduce": 23199,
      "##bbing": 23200,
      "fay": 23201,
      "ferris": 23202,
      "ogden": 23203,
      "amar": 23204,
      "nik": 23205,
      "unarmed": 23206,
      "##inator": 23207,
      "evaluating": 23208,
      "kyrgyzstan": 23209,
      "sweetness": 23210,
      "##lford": 23211,
      "##oki": 23212,
      "mccormick": 23213,
      "meiji": 23214,
      "notoriety": 23215,
      "stimulate": 23216,
      "disrupt": 23217,
      "figuring": 23218,
      "instructional": 23219,
      "mcgrath": 23220,
      "##zoo": 23221,
      "groundbreaking": 23222,
      "##lto": 23223,
      "flinch": 23224,
      "khorasan": 23225,
      "agrarian": 23226,
      "bengals": 23227,
      "mixer": 23228,
      "radiating": 23229,
      "##sov": 23230,
      "ingram": 23231,
      "pitchers": 23232,
      "nad": 23233,
      "tariff": 23234,
      "##cript": 23235,
      "tata": 23236,
      "##codes": 23237,
      "##emi": 23238,
      "##ungen": 23239,
      "appellate": 23240,
      "lehigh": 23241,
      "##bled": 23242,
      "##giri": 23243,
      "brawl": 23244,
      "duct": 23245,
      "texans": 23246,
      "##ciation": 23247,
      "##ropolis": 23248,
      "skipper": 23249,
      "speculative": 23250,
      "vomit": 23251,
      "doctrines": 23252,
      "stresses": 23253,
      "253": 23254,
      "davy": 23255,
      "graders": 23256,
      "whitehead": 23257,
      "jozef": 23258,
      "timely": 23259,
      "cumulative": 23260,
      "haryana": 23261,
      "paints": 23262,
      "appropriately": 23263,
      "boon": 23264,
      "cactus": 23265,
      "##ales": 23266,
      "##pid": 23267,
      "dow": 23268,
      "legions": 23269,
      "##pit": 23270,
      "perceptions": 23271,
      "1730": 23272,
      "picturesque": 23273,
      "##yse": 23274,
      "periphery": 23275,
      "rune": 23276,
      "wr": 23277,
      "##aha": 23278,
      "celtics": 23279,
      "sentencing": 23280,
      "whoa": 23281,
      "##erin": 23282,
      "confirms": 23283,
      "variance": 23284,
      "425": 23285,
      "moines": 23286,
      "mathews": 23287,
      "spade": 23288,
      "rave": 23289,
      "m1": 23290,
      "fronted": 23291,
      "fx": 23292,
      "blending": 23293,
      "alleging": 23294,
      "reared": 23295,
      "##gl": 23296,
      "237": 23297,
      "##paper": 23298,
      "grassroots": 23299,
      "eroded": 23300,
      "##free": 23301,
      "##physical": 23302,
      "directs": 23303,
      "ordeal": 23304,
      "##sław": 23305,
      "accelerate": 23306,
      "hacker": 23307,
      "rooftop": 23308,
      "##inia": 23309,
      "lev": 23310,
      "buys": 23311,
      "cebu": 23312,
      "devote": 23313,
      "##lce": 23314,
      "specialising": 23315,
      "##ulsion": 23316,
      "choreographed": 23317,
      "repetition": 23318,
      "warehouses": 23319,
      "##ryl": 23320,
      "paisley": 23321,
      "tuscany": 23322,
      "analogy": 23323,
      "sorcerer": 23324,
      "hash": 23325,
      "huts": 23326,
      "shards": 23327,
      "descends": 23328,
      "exclude": 23329,
      "nix": 23330,
      "chaplin": 23331,
      "gaga": 23332,
      "ito": 23333,
      "vane": 23334,
      "##drich": 23335,
      "causeway": 23336,
      "misconduct": 23337,
      "limo": 23338,
      "orchestrated": 23339,
      "glands": 23340,
      "jana": 23341,
      "##kot": 23342,
      "u2": 23343,
      "##mple": 23344,
      "##sons": 23345,
      "branching": 23346,
      "contrasts": 23347,
      "scoop": 23348,
      "longed": 23349,
      "##virus": 23350,
      "chattanooga": 23351,
      "##75": 23352,
      "syrup": 23353,
      "cornerstone": 23354,
      "##tized": 23355,
      "##mind": 23356,
      "##iaceae": 23357,
      "careless": 23358,
      "precedence": 23359,
      "frescoes": 23360,
      "##uet": 23361,
      "chilled": 23362,
      "consult": 23363,
      "modelled": 23364,
      "snatch": 23365,
      "peat": 23366,
      "##thermal": 23367,
      "caucasian": 23368,
      "humane": 23369,
      "relaxation": 23370,
      "spins": 23371,
      "temperance": 23372,
      "##lbert": 23373,
      "occupations": 23374,
      "lambda": 23375,
      "hybrids": 23376,
      "moons": 23377,
      "mp3": 23378,
      "##oese": 23379,
      "247": 23380,
      "rolf": 23381,
      "societal": 23382,
      "yerevan": 23383,
      "ness": 23384,
      "##ssler": 23385,
      "befriended": 23386,
      "mechanized": 23387,
      "nominate": 23388,
      "trough": 23389,
      "boasted": 23390,
      "cues": 23391,
      "seater": 23392,
      "##hom": 23393,
      "bends": 23394,
      "##tangle": 23395,
      "conductors": 23396,
      "emptiness": 23397,
      "##lmer": 23398,
      "eurasian": 23399,
      "adriatic": 23400,
      "tian": 23401,
      "##cie": 23402,
      "anxiously": 23403,
      "lark": 23404,
      "propellers": 23405,
      "chichester": 23406,
      "jock": 23407,
      "ev": 23408,
      "2a": 23409,
      "##holding": 23410,
      "credible": 23411,
      "recounts": 23412,
      "tori": 23413,
      "loyalist": 23414,
      "abduction": 23415,
      "##hoot": 23416,
      "##redo": 23417,
      "nepali": 23418,
      "##mite": 23419,
      "ventral": 23420,
      "tempting": 23421,
      "##ango": 23422,
      "##crats": 23423,
      "steered": 23424,
      "##wice": 23425,
      "javelin": 23426,
      "dipping": 23427,
      "laborers": 23428,
      "prentice": 23429,
      "looming": 23430,
      "titanium": 23431,
      "##ː": 23432,
      "badges": 23433,
      "emir": 23434,
      "tensor": 23435,
      "##ntation": 23436,
      "egyptians": 23437,
      "rash": 23438,
      "denies": 23439,
      "hawthorne": 23440,
      "lombard": 23441,
      "showers": 23442,
      "wehrmacht": 23443,
      "dietary": 23444,
      "trojan": 23445,
      "##reus": 23446,
      "welles": 23447,
      "executing": 23448,
      "horseshoe": 23449,
      "lifeboat": 23450,
      "##lak": 23451,
      "elsa": 23452,
      "infirmary": 23453,
      "nearing": 23454,
      "roberta": 23455,
      "boyer": 23456,
      "mutter": 23457,
      "trillion": 23458,
      "joanne": 23459,
      "##fine": 23460,
      "##oked": 23461,
      "sinks": 23462,
      "vortex": 23463,
      "uruguayan": 23464,
      "clasp": 23465,
      "sirius": 23466,
      "##block": 23467,
      "accelerator": 23468,
      "prohibit": 23469,
      "sunken": 23470,
      "byu": 23471,
      "chronological": 23472,
      "diplomats": 23473,
      "ochreous": 23474,
      "510": 23475,
      "symmetrical": 23476,
      "1644": 23477,
      "maia": 23478,
      "##tology": 23479,
      "salts": 23480,
      "reigns": 23481,
      "atrocities": 23482,
      "##ия": 23483,
      "hess": 23484,
      "bared": 23485,
      "issn": 23486,
      "##vyn": 23487,
      "cater": 23488,
      "saturated": 23489,
      "##cycle": 23490,
      "##isse": 23491,
      "sable": 23492,
      "voyager": 23493,
      "dyer": 23494,
      "yusuf": 23495,
      "##inge": 23496,
      "fountains": 23497,
      "wolff": 23498,
      "##39": 23499,
      "##nni": 23500,
      "engraving": 23501,
      "rollins": 23502,
      "atheist": 23503,
      "ominous": 23504,
      "##ault": 23505,
      "herr": 23506,
      "chariot": 23507,
      "martina": 23508,
      "strung": 23509,
      "##fell": 23510,
      "##farlane": 23511,
      "horrific": 23512,
      "sahib": 23513,
      "gazes": 23514,
      "saetan": 23515,
      "erased": 23516,
      "ptolemy": 23517,
      "##olic": 23518,
      "flushing": 23519,
      "lauderdale": 23520,
      "analytic": 23521,
      "##ices": 23522,
      "530": 23523,
      "navarro": 23524,
      "beak": 23525,
      "gorilla": 23526,
      "herrera": 23527,
      "broom": 23528,
      "guadalupe": 23529,
      "raiding": 23530,
      "sykes": 23531,
      "311": 23532,
      "bsc": 23533,
      "deliveries": 23534,
      "1720": 23535,
      "invasions": 23536,
      "carmichael": 23537,
      "tajikistan": 23538,
      "thematic": 23539,
      "ecumenical": 23540,
      "sentiments": 23541,
      "onstage": 23542,
      "##rians": 23543,
      "##brand": 23544,
      "##sume": 23545,
      "catastrophic": 23546,
      "flanks": 23547,
      "molten": 23548,
      "##arns": 23549,
      "waller": 23550,
      "aimee": 23551,
      "terminating": 23552,
      "##icing": 23553,
      "alternately": 23554,
      "##oche": 23555,
      "nehru": 23556,
      "printers": 23557,
      "outraged": 23558,
      "##eving": 23559,
      "empires": 23560,
      "template": 23561,
      "banners": 23562,
      "repetitive": 23563,
      "za": 23564,
      "##oise": 23565,
      "vegetarian": 23566,
      "##tell": 23567,
      "guiana": 23568,
      "opt": 23569,
      "cavendish": 23570,
      "lucknow": 23571,
      "synthesized": 23572,
      "##hani": 23573,
      "##mada": 23574,
      "finalized": 23575,
      "##ctable": 23576,
      "fictitious": 23577,
      "mayoral": 23578,
      "unreliable": 23579,
      "##enham": 23580,
      "embracing": 23581,
      "peppers": 23582,
      "rbis": 23583,
      "##chio": 23584,
      "##neo": 23585,
      "inhibition": 23586,
      "slashed": 23587,
      "togo": 23588,
      "orderly": 23589,
      "embroidered": 23590,
      "safari": 23591,
      "salty": 23592,
      "236": 23593,
      "barron": 23594,
      "benito": 23595,
      "totaled": 23596,
      "##dak": 23597,
      "pubs": 23598,
      "simulated": 23599,
      "caden": 23600,
      "devin": 23601,
      "tolkien": 23602,
      "momma": 23603,
      "welding": 23604,
      "sesame": 23605,
      "##ept": 23606,
      "gottingen": 23607,
      "hardness": 23608,
      "630": 23609,
      "shaman": 23610,
      "temeraire": 23611,
      "620": 23612,
      "adequately": 23613,
      "pediatric": 23614,
      "##kit": 23615,
      "ck": 23616,
      "assertion": 23617,
      "radicals": 23618,
      "composure": 23619,
      "cadence": 23620,
      "seafood": 23621,
      "beaufort": 23622,
      "lazarus": 23623,
      "mani": 23624,
      "warily": 23625,
      "cunning": 23626,
      "kurdistan": 23627,
      "249": 23628,
      "cantata": 23629,
      "##kir": 23630,
      "ares": 23631,
      "##41": 23632,
      "##clusive": 23633,
      "nape": 23634,
      "townland": 23635,
      "geared": 23636,
      "insulted": 23637,
      "flutter": 23638,
      "boating": 23639,
      "violate": 23640,
      "draper": 23641,
      "dumping": 23642,
      "malmo": 23643,
      "##hh": 23644,
      "##romatic": 23645,
      "firearm": 23646,
      "alta": 23647,
      "bono": 23648,
      "obscured": 23649,
      "##clave": 23650,
      "exceeds": 23651,
      "panorama": 23652,
      "unbelievable": 23653,
      "##train": 23654,
      "preschool": 23655,
      "##essed": 23656,
      "disconnected": 23657,
      "installing": 23658,
      "rescuing": 23659,
      "secretaries": 23660,
      "accessibility": 23661,
      "##castle": 23662,
      "##drive": 23663,
      "##ifice": 23664,
      "##film": 23665,
      "bouts": 23666,
      "slug": 23667,
      "waterway": 23668,
      "mindanao": 23669,
      "##buro": 23670,
      "##ratic": 23671,
      "halves": 23672,
      "##ل": 23673,
      "calming": 23674,
      "liter": 23675,
      "maternity": 23676,
      "adorable": 23677,
      "bragg": 23678,
      "electrification": 23679,
      "mcc": 23680,
      "##dote": 23681,
      "roxy": 23682,
      "schizophrenia": 23683,
      "##body": 23684,
      "munoz": 23685,
      "kaye": 23686,
      "whaling": 23687,
      "239": 23688,
      "mil": 23689,
      "tingling": 23690,
      "tolerant": 23691,
      "##ago": 23692,
      "unconventional": 23693,
      "volcanoes": 23694,
      "##finder": 23695,
      "deportivo": 23696,
      "##llie": 23697,
      "robson": 23698,
      "kaufman": 23699,
      "neuroscience": 23700,
      "wai": 23701,
      "deportation": 23702,
      "masovian": 23703,
      "scraping": 23704,
      "converse": 23705,
      "##bh": 23706,
      "hacking": 23707,
      "bulge": 23708,
      "##oun": 23709,
      "administratively": 23710,
      "yao": 23711,
      "580": 23712,
      "amp": 23713,
      "mammoth": 23714,
      "booster": 23715,
      "claremont": 23716,
      "hooper": 23717,
      "nomenclature": 23718,
      "pursuits": 23719,
      "mclaughlin": 23720,
      "melinda": 23721,
      "##sul": 23722,
      "catfish": 23723,
      "barclay": 23724,
      "substrates": 23725,
      "taxa": 23726,
      "zee": 23727,
      "originals": 23728,
      "kimberly": 23729,
      "packets": 23730,
      "padma": 23731,
      "##ality": 23732,
      "borrowing": 23733,
      "ostensibly": 23734,
      "solvent": 23735,
      "##bri": 23736,
      "##genesis": 23737,
      "##mist": 23738,
      "lukas": 23739,
      "shreveport": 23740,
      "veracruz": 23741,
      "##ь": 23742,
      "##lou": 23743,
      "##wives": 23744,
      "cheney": 23745,
      "tt": 23746,
      "anatolia": 23747,
      "hobbs": 23748,
      "##zyn": 23749,
      "cyclic": 23750,
      "radiant": 23751,
      "alistair": 23752,
      "greenish": 23753,
      "siena": 23754,
      "dat": 23755,
      "independents": 23756,
      "##bation": 23757,
      "conform": 23758,
      "pieter": 23759,
      "hyper": 23760,
      "applicant": 23761,
      "bradshaw": 23762,
      "spores": 23763,
      "telangana": 23764,
      "vinci": 23765,
      "inexpensive": 23766,
      "nuclei": 23767,
      "322": 23768,
      "jang": 23769,
      "nme": 23770,
      "soho": 23771,
      "spd": 23772,
      "##ign": 23773,
      "cradled": 23774,
      "receptionist": 23775,
      "pow": 23776,
      "##43": 23777,
      "##rika": 23778,
      "fascism": 23779,
      "##ifer": 23780,
      "experimenting": 23781,
      "##ading": 23782,
      "##iec": 23783,
      "##region": 23784,
      "345": 23785,
      "jocelyn": 23786,
      "maris": 23787,
      "stair": 23788,
      "nocturnal": 23789,
      "toro": 23790,
      "constabulary": 23791,
      "elgin": 23792,
      "##kker": 23793,
      "msc": 23794,
      "##giving": 23795,
      "##schen": 23796,
      "##rase": 23797,
      "doherty": 23798,
      "doping": 23799,
      "sarcastically": 23800,
      "batter": 23801,
      "maneuvers": 23802,
      "##cano": 23803,
      "##apple": 23804,
      "##gai": 23805,
      "##git": 23806,
      "intrinsic": 23807,
      "##nst": 23808,
      "##stor": 23809,
      "1753": 23810,
      "showtime": 23811,
      "cafes": 23812,
      "gasps": 23813,
      "lviv": 23814,
      "ushered": 23815,
      "##thed": 23816,
      "fours": 23817,
      "restart": 23818,
      "astonishment": 23819,
      "transmitting": 23820,
      "flyer": 23821,
      "shrugs": 23822,
      "##sau": 23823,
      "intriguing": 23824,
      "cones": 23825,
      "dictated": 23826,
      "mushrooms": 23827,
      "medial": 23828,
      "##kovsky": 23829,
      "##elman": 23830,
      "escorting": 23831,
      "gaped": 23832,
      "##26": 23833,
      "godfather": 23834,
      "##door": 23835,
      "##sell": 23836,
      "djs": 23837,
      "recaptured": 23838,
      "timetable": 23839,
      "vila": 23840,
      "1710": 23841,
      "3a": 23842,
      "aerodrome": 23843,
      "mortals": 23844,
      "scientology": 23845,
      "##orne": 23846,
      "angelina": 23847,
      "mag": 23848,
      "convection": 23849,
      "unpaid": 23850,
      "insertion": 23851,
      "intermittent": 23852,
      "lego": 23853,
      "##nated": 23854,
      "endeavor": 23855,
      "kota": 23856,
      "pereira": 23857,
      "##lz": 23858,
      "304": 23859,
      "bwv": 23860,
      "glamorgan": 23861,
      "insults": 23862,
      "agatha": 23863,
      "fey": 23864,
      "##cend": 23865,
      "fleetwood": 23866,
      "mahogany": 23867,
      "protruding": 23868,
      "steamship": 23869,
      "zeta": 23870,
      "##arty": 23871,
      "mcguire": 23872,
      "suspense": 23873,
      "##sphere": 23874,
      "advising": 23875,
      "urges": 23876,
      "##wala": 23877,
      "hurriedly": 23878,
      "meteor": 23879,
      "gilded": 23880,
      "inline": 23881,
      "arroyo": 23882,
      "stalker": 23883,
      "##oge": 23884,
      "excitedly": 23885,
      "revered": 23886,
      "##cure": 23887,
      "earle": 23888,
      "introductory": 23889,
      "##break": 23890,
      "##ilde": 23891,
      "mutants": 23892,
      "puff": 23893,
      "pulses": 23894,
      "reinforcement": 23895,
      "##haling": 23896,
      "curses": 23897,
      "lizards": 23898,
      "stalk": 23899,
      "correlated": 23900,
      "##fixed": 23901,
      "fallout": 23902,
      "macquarie": 23903,
      "##unas": 23904,
      "bearded": 23905,
      "denton": 23906,
      "heaving": 23907,
      "802": 23908,
      "##ocation": 23909,
      "winery": 23910,
      "assign": 23911,
      "dortmund": 23912,
      "##lkirk": 23913,
      "everest": 23914,
      "invariant": 23915,
      "charismatic": 23916,
      "susie": 23917,
      "##elling": 23918,
      "bled": 23919,
      "lesley": 23920,
      "telegram": 23921,
      "sumner": 23922,
      "bk": 23923,
      "##ogen": 23924,
      "##к": 23925,
      "wilcox": 23926,
      "needy": 23927,
      "colbert": 23928,
      "duval": 23929,
      "##iferous": 23930,
      "##mbled": 23931,
      "allotted": 23932,
      "attends": 23933,
      "imperative": 23934,
      "##hita": 23935,
      "replacements": 23936,
      "hawker": 23937,
      "##inda": 23938,
      "insurgency": 23939,
      "##zee": 23940,
      "##eke": 23941,
      "casts": 23942,
      "##yla": 23943,
      "680": 23944,
      "ives": 23945,
      "transitioned": 23946,
      "##pack": 23947,
      "##powering": 23948,
      "authoritative": 23949,
      "baylor": 23950,
      "flex": 23951,
      "cringed": 23952,
      "plaintiffs": 23953,
      "woodrow": 23954,
      "##skie": 23955,
      "drastic": 23956,
      "ape": 23957,
      "aroma": 23958,
      "unfolded": 23959,
      "commotion": 23960,
      "nt": 23961,
      "preoccupied": 23962,
      "theta": 23963,
      "routines": 23964,
      "lasers": 23965,
      "privatization": 23966,
      "wand": 23967,
      "domino": 23968,
      "ek": 23969,
      "clenching": 23970,
      "nsa": 23971,
      "strategically": 23972,
      "showered": 23973,
      "bile": 23974,
      "handkerchief": 23975,
      "pere": 23976,
      "storing": 23977,
      "christophe": 23978,
      "insulting": 23979,
      "316": 23980,
      "nakamura": 23981,
      "romani": 23982,
      "asiatic": 23983,
      "magdalena": 23984,
      "palma": 23985,
      "cruises": 23986,
      "stripping": 23987,
      "405": 23988,
      "konstantin": 23989,
      "soaring": 23990,
      "##berman": 23991,
      "colloquially": 23992,
      "forerunner": 23993,
      "havilland": 23994,
      "incarcerated": 23995,
      "parasites": 23996,
      "sincerity": 23997,
      "##utus": 23998,
      "disks": 23999,
      "plank": 24000,
      "saigon": 24001,
      "##ining": 24002,
      "corbin": 24003,
      "homo": 24004,
      "ornaments": 24005,
      "powerhouse": 24006,
      "##tlement": 24007,
      "chong": 24008,
      "fastened": 24009,
      "feasibility": 24010,
      "idf": 24011,
      "morphological": 24012,
      "usable": 24013,
      "##nish": 24014,
      "##zuki": 24015,
      "aqueduct": 24016,
      "jaguars": 24017,
      "keepers": 24018,
      "##flies": 24019,
      "aleksandr": 24020,
      "faust": 24021,
      "assigns": 24022,
      "ewing": 24023,
      "bacterium": 24024,
      "hurled": 24025,
      "tricky": 24026,
      "hungarians": 24027,
      "integers": 24028,
      "wallis": 24029,
      "321": 24030,
      "yamaha": 24031,
      "##isha": 24032,
      "hushed": 24033,
      "oblivion": 24034,
      "aviator": 24035,
      "evangelist": 24036,
      "friars": 24037,
      "##eller": 24038,
      "monograph": 24039,
      "ode": 24040,
      "##nary": 24041,
      "airplanes": 24042,
      "labourers": 24043,
      "charms": 24044,
      "##nee": 24045,
      "1661": 24046,
      "hagen": 24047,
      "tnt": 24048,
      "rudder": 24049,
      "fiesta": 24050,
      "transcript": 24051,
      "dorothea": 24052,
      "ska": 24053,
      "inhibitor": 24054,
      "maccabi": 24055,
      "retorted": 24056,
      "raining": 24057,
      "encompassed": 24058,
      "clauses": 24059,
      "menacing": 24060,
      "1642": 24061,
      "lineman": 24062,
      "##gist": 24063,
      "vamps": 24064,
      "##ape": 24065,
      "##dick": 24066,
      "gloom": 24067,
      "##rera": 24068,
      "dealings": 24069,
      "easing": 24070,
      "seekers": 24071,
      "##nut": 24072,
      "##pment": 24073,
      "helens": 24074,
      "unmanned": 24075,
      "##anu": 24076,
      "##isson": 24077,
      "basics": 24078,
      "##amy": 24079,
      "##ckman": 24080,
      "adjustments": 24081,
      "1688": 24082,
      "brutality": 24083,
      "horne": 24084,
      "##zell": 24085,
      "sui": 24086,
      "##55": 24087,
      "##mable": 24088,
      "aggregator": 24089,
      "##thal": 24090,
      "rhino": 24091,
      "##drick": 24092,
      "##vira": 24093,
      "counters": 24094,
      "zoom": 24095,
      "##01": 24096,
      "##rting": 24097,
      "mn": 24098,
      "montenegrin": 24099,
      "packard": 24100,
      "##unciation": 24101,
      "##♭": 24102,
      "##kki": 24103,
      "reclaim": 24104,
      "scholastic": 24105,
      "thugs": 24106,
      "pulsed": 24107,
      "##icia": 24108,
      "syriac": 24109,
      "quan": 24110,
      "saddam": 24111,
      "banda": 24112,
      "kobe": 24113,
      "blaming": 24114,
      "buddies": 24115,
      "dissent": 24116,
      "##lusion": 24117,
      "##usia": 24118,
      "corbett": 24119,
      "jaya": 24120,
      "delle": 24121,
      "erratic": 24122,
      "lexie": 24123,
      "##hesis": 24124,
      "435": 24125,
      "amiga": 24126,
      "hermes": 24127,
      "##pressing": 24128,
      "##leen": 24129,
      "chapels": 24130,
      "gospels": 24131,
      "jamal": 24132,
      "##uating": 24133,
      "compute": 24134,
      "revolving": 24135,
      "warp": 24136,
      "##sso": 24137,
      "##thes": 24138,
      "armory": 24139,
      "##eras": 24140,
      "##gol": 24141,
      "antrim": 24142,
      "loki": 24143,
      "##kow": 24144,
      "##asian": 24145,
      "##good": 24146,
      "##zano": 24147,
      "braid": 24148,
      "handwriting": 24149,
      "subdistrict": 24150,
      "funky": 24151,
      "pantheon": 24152,
      "##iculate": 24153,
      "concurrency": 24154,
      "estimation": 24155,
      "improper": 24156,
      "juliana": 24157,
      "##his": 24158,
      "newcomers": 24159,
      "johnstone": 24160,
      "staten": 24161,
      "communicated": 24162,
      "##oco": 24163,
      "##alle": 24164,
      "sausage": 24165,
      "stormy": 24166,
      "##stered": 24167,
      "##tters": 24168,
      "superfamily": 24169,
      "##grade": 24170,
      "acidic": 24171,
      "collateral": 24172,
      "tabloid": 24173,
      "##oped": 24174,
      "##rza": 24175,
      "bladder": 24176,
      "austen": 24177,
      "##ellant": 24178,
      "mcgraw": 24179,
      "##hay": 24180,
      "hannibal": 24181,
      "mein": 24182,
      "aquino": 24183,
      "lucifer": 24184,
      "wo": 24185,
      "badger": 24186,
      "boar": 24187,
      "cher": 24188,
      "christensen": 24189,
      "greenberg": 24190,
      "interruption": 24191,
      "##kken": 24192,
      "jem": 24193,
      "244": 24194,
      "mocked": 24195,
      "bottoms": 24196,
      "cambridgeshire": 24197,
      "##lide": 24198,
      "sprawling": 24199,
      "##bbly": 24200,
      "eastwood": 24201,
      "ghent": 24202,
      "synth": 24203,
      "##buck": 24204,
      "advisers": 24205,
      "##bah": 24206,
      "nominally": 24207,
      "hapoel": 24208,
      "qu": 24209,
      "daggers": 24210,
      "estranged": 24211,
      "fabricated": 24212,
      "towels": 24213,
      "vinnie": 24214,
      "wcw": 24215,
      "misunderstanding": 24216,
      "anglia": 24217,
      "nothin": 24218,
      "unmistakable": 24219,
      "##dust": 24220,
      "##lova": 24221,
      "chilly": 24222,
      "marquette": 24223,
      "truss": 24224,
      "##edge": 24225,
      "##erine": 24226,
      "reece": 24227,
      "##lty": 24228,
      "##chemist": 24229,
      "##connected": 24230,
      "272": 24231,
      "308": 24232,
      "41st": 24233,
      "bash": 24234,
      "raion": 24235,
      "waterfalls": 24236,
      "##ump": 24237,
      "##main": 24238,
      "labyrinth": 24239,
      "queue": 24240,
      "theorist": 24241,
      "##istle": 24242,
      "bharatiya": 24243,
      "flexed": 24244,
      "soundtracks": 24245,
      "rooney": 24246,
      "leftist": 24247,
      "patrolling": 24248,
      "wharton": 24249,
      "plainly": 24250,
      "alleviate": 24251,
      "eastman": 24252,
      "schuster": 24253,
      "topographic": 24254,
      "engages": 24255,
      "immensely": 24256,
      "unbearable": 24257,
      "fairchild": 24258,
      "1620": 24259,
      "dona": 24260,
      "lurking": 24261,
      "parisian": 24262,
      "oliveira": 24263,
      "ia": 24264,
      "indictment": 24265,
      "hahn": 24266,
      "bangladeshi": 24267,
      "##aster": 24268,
      "vivo": 24269,
      "##uming": 24270,
      "##ential": 24271,
      "antonia": 24272,
      "expects": 24273,
      "indoors": 24274,
      "kildare": 24275,
      "harlan": 24276,
      "##logue": 24277,
      "##ogenic": 24278,
      "##sities": 24279,
      "forgiven": 24280,
      "##wat": 24281,
      "childish": 24282,
      "tavi": 24283,
      "##mide": 24284,
      "##orra": 24285,
      "plausible": 24286,
      "grimm": 24287,
      "successively": 24288,
      "scooted": 24289,
      "##bola": 24290,
      "##dget": 24291,
      "##rith": 24292,
      "spartans": 24293,
      "emery": 24294,
      "flatly": 24295,
      "azure": 24296,
      "epilogue": 24297,
      "##wark": 24298,
      "flourish": 24299,
      "##iny": 24300,
      "##tracted": 24301,
      "##overs": 24302,
      "##oshi": 24303,
      "bestseller": 24304,
      "distressed": 24305,
      "receipt": 24306,
      "spitting": 24307,
      "hermit": 24308,
      "topological": 24309,
      "##cot": 24310,
      "drilled": 24311,
      "subunit": 24312,
      "francs": 24313,
      "##layer": 24314,
      "eel": 24315,
      "##fk": 24316,
      "##itas": 24317,
      "octopus": 24318,
      "footprint": 24319,
      "petitions": 24320,
      "ufo": 24321,
      "##say": 24322,
      "##foil": 24323,
      "interfering": 24324,
      "leaking": 24325,
      "palo": 24326,
      "##metry": 24327,
      "thistle": 24328,
      "valiant": 24329,
      "##pic": 24330,
      "narayan": 24331,
      "mcpherson": 24332,
      "##fast": 24333,
      "gonzales": 24334,
      "##ym": 24335,
      "##enne": 24336,
      "dustin": 24337,
      "novgorod": 24338,
      "solos": 24339,
      "##zman": 24340,
      "doin": 24341,
      "##raph": 24342,
      "##patient": 24343,
      "##meyer": 24344,
      "soluble": 24345,
      "ashland": 24346,
      "cuffs": 24347,
      "carole": 24348,
      "pendleton": 24349,
      "whistling": 24350,
      "vassal": 24351,
      "##river": 24352,
      "deviation": 24353,
      "revisited": 24354,
      "constituents": 24355,
      "rallied": 24356,
      "rotate": 24357,
      "loomed": 24358,
      "##eil": 24359,
      "##nting": 24360,
      "amateurs": 24361,
      "augsburg": 24362,
      "auschwitz": 24363,
      "crowns": 24364,
      "skeletons": 24365,
      "##cona": 24366,
      "bonnet": 24367,
      "257": 24368,
      "dummy": 24369,
      "globalization": 24370,
      "simeon": 24371,
      "sleeper": 24372,
      "mandal": 24373,
      "differentiated": 24374,
      "##crow": 24375,
      "##mare": 24376,
      "milne": 24377,
      "bundled": 24378,
      "exasperated": 24379,
      "talmud": 24380,
      "owes": 24381,
      "segregated": 24382,
      "##feng": 24383,
      "##uary": 24384,
      "dentist": 24385,
      "piracy": 24386,
      "props": 24387,
      "##rang": 24388,
      "devlin": 24389,
      "##torium": 24390,
      "malicious": 24391,
      "paws": 24392,
      "##laid": 24393,
      "dependency": 24394,
      "##ergy": 24395,
      "##fers": 24396,
      "##enna": 24397,
      "258": 24398,
      "pistons": 24399,
      "rourke": 24400,
      "jed": 24401,
      "grammatical": 24402,
      "tres": 24403,
      "maha": 24404,
      "wig": 24405,
      "512": 24406,
      "ghostly": 24407,
      "jayne": 24408,
      "##achal": 24409,
      "##creen": 24410,
      "##ilis": 24411,
      "##lins": 24412,
      "##rence": 24413,
      "designate": 24414,
      "##with": 24415,
      "arrogance": 24416,
      "cambodian": 24417,
      "clones": 24418,
      "showdown": 24419,
      "throttle": 24420,
      "twain": 24421,
      "##ception": 24422,
      "lobes": 24423,
      "metz": 24424,
      "nagoya": 24425,
      "335": 24426,
      "braking": 24427,
      "##furt": 24428,
      "385": 24429,
      "roaming": 24430,
      "##minster": 24431,
      "amin": 24432,
      "crippled": 24433,
      "##37": 24434,
      "##llary": 24435,
      "indifferent": 24436,
      "hoffmann": 24437,
      "idols": 24438,
      "intimidating": 24439,
      "1751": 24440,
      "261": 24441,
      "influenza": 24442,
      "memo": 24443,
      "onions": 24444,
      "1748": 24445,
      "bandage": 24446,
      "consciously": 24447,
      "##landa": 24448,
      "##rage": 24449,
      "clandestine": 24450,
      "observes": 24451,
      "swiped": 24452,
      "tangle": 24453,
      "##ener": 24454,
      "##jected": 24455,
      "##trum": 24456,
      "##bill": 24457,
      "##lta": 24458,
      "hugs": 24459,
      "congresses": 24460,
      "josiah": 24461,
      "spirited": 24462,
      "##dek": 24463,
      "humanist": 24464,
      "managerial": 24465,
      "filmmaking": 24466,
      "inmate": 24467,
      "rhymes": 24468,
      "debuting": 24469,
      "grimsby": 24470,
      "ur": 24471,
      "##laze": 24472,
      "duplicate": 24473,
      "vigor": 24474,
      "##tf": 24475,
      "republished": 24476,
      "bolshevik": 24477,
      "refurbishment": 24478,
      "antibiotics": 24479,
      "martini": 24480,
      "methane": 24481,
      "newscasts": 24482,
      "royale": 24483,
      "horizons": 24484,
      "levant": 24485,
      "iain": 24486,
      "visas": 24487,
      "##ischen": 24488,
      "paler": 24489,
      "##around": 24490,
      "manifestation": 24491,
      "snuck": 24492,
      "alf": 24493,
      "chop": 24494,
      "futile": 24495,
      "pedestal": 24496,
      "rehab": 24497,
      "##kat": 24498,
      "bmg": 24499,
      "kerman": 24500,
      "res": 24501,
      "fairbanks": 24502,
      "jarrett": 24503,
      "abstraction": 24504,
      "saharan": 24505,
      "##zek": 24506,
      "1746": 24507,
      "procedural": 24508,
      "clearer": 24509,
      "kincaid": 24510,
      "sash": 24511,
      "luciano": 24512,
      "##ffey": 24513,
      "crunch": 24514,
      "helmut": 24515,
      "##vara": 24516,
      "revolutionaries": 24517,
      "##tute": 24518,
      "creamy": 24519,
      "leach": 24520,
      "##mmon": 24521,
      "1747": 24522,
      "permitting": 24523,
      "nes": 24524,
      "plight": 24525,
      "wendell": 24526,
      "##lese": 24527,
      "contra": 24528,
      "ts": 24529,
      "clancy": 24530,
      "ipa": 24531,
      "mach": 24532,
      "staples": 24533,
      "autopsy": 24534,
      "disturbances": 24535,
      "nueva": 24536,
      "karin": 24537,
      "pontiac": 24538,
      "##uding": 24539,
      "proxy": 24540,
      "venerable": 24541,
      "haunt": 24542,
      "leto": 24543,
      "bergman": 24544,
      "expands": 24545,
      "##helm": 24546,
      "wal": 24547,
      "##pipe": 24548,
      "canning": 24549,
      "celine": 24550,
      "cords": 24551,
      "obesity": 24552,
      "##enary": 24553,
      "intrusion": 24554,
      "planner": 24555,
      "##phate": 24556,
      "reasoned": 24557,
      "sequencing": 24558,
      "307": 24559,
      "harrow": 24560,
      "##chon": 24561,
      "##dora": 24562,
      "marred": 24563,
      "mcintyre": 24564,
      "repay": 24565,
      "tarzan": 24566,
      "darting": 24567,
      "248": 24568,
      "harrisburg": 24569,
      "margarita": 24570,
      "repulsed": 24571,
      "##hur": 24572,
      "##lding": 24573,
      "belinda": 24574,
      "hamburger": 24575,
      "novo": 24576,
      "compliant": 24577,
      "runways": 24578,
      "bingham": 24579,
      "registrar": 24580,
      "skyscraper": 24581,
      "ic": 24582,
      "cuthbert": 24583,
      "improvisation": 24584,
      "livelihood": 24585,
      "##corp": 24586,
      "##elial": 24587,
      "admiring": 24588,
      "##dened": 24589,
      "sporadic": 24590,
      "believer": 24591,
      "casablanca": 24592,
      "popcorn": 24593,
      "##29": 24594,
      "asha": 24595,
      "shovel": 24596,
      "##bek": 24597,
      "##dice": 24598,
      "coiled": 24599,
      "tangible": 24600,
      "##dez": 24601,
      "casper": 24602,
      "elsie": 24603,
      "resin": 24604,
      "tenderness": 24605,
      "rectory": 24606,
      "##ivision": 24607,
      "avail": 24608,
      "sonar": 24609,
      "##mori": 24610,
      "boutique": 24611,
      "##dier": 24612,
      "guerre": 24613,
      "bathed": 24614,
      "upbringing": 24615,
      "vaulted": 24616,
      "sandals": 24617,
      "blessings": 24618,
      "##naut": 24619,
      "##utnant": 24620,
      "1680": 24621,
      "306": 24622,
      "foxes": 24623,
      "pia": 24624,
      "corrosion": 24625,
      "hesitantly": 24626,
      "confederates": 24627,
      "crystalline": 24628,
      "footprints": 24629,
      "shapiro": 24630,
      "tirana": 24631,
      "valentin": 24632,
      "drones": 24633,
      "45th": 24634,
      "microscope": 24635,
      "shipments": 24636,
      "texted": 24637,
      "inquisition": 24638,
      "wry": 24639,
      "guernsey": 24640,
      "unauthorized": 24641,
      "resigning": 24642,
      "760": 24643,
      "ripple": 24644,
      "schubert": 24645,
      "stu": 24646,
      "reassure": 24647,
      "felony": 24648,
      "##ardo": 24649,
      "brittle": 24650,
      "koreans": 24651,
      "##havan": 24652,
      "##ives": 24653,
      "dun": 24654,
      "implicit": 24655,
      "tyres": 24656,
      "##aldi": 24657,
      "##lth": 24658,
      "magnolia": 24659,
      "##ehan": 24660,
      "##puri": 24661,
      "##poulos": 24662,
      "aggressively": 24663,
      "fei": 24664,
      "gr": 24665,
      "familiarity": 24666,
      "##poo": 24667,
      "indicative": 24668,
      "##trust": 24669,
      "fundamentally": 24670,
      "jimmie": 24671,
      "overrun": 24672,
      "395": 24673,
      "anchors": 24674,
      "moans": 24675,
      "##opus": 24676,
      "britannia": 24677,
      "armagh": 24678,
      "##ggle": 24679,
      "purposely": 24680,
      "seizing": 24681,
      "##vao": 24682,
      "bewildered": 24683,
      "mundane": 24684,
      "avoidance": 24685,
      "cosmopolitan": 24686,
      "geometridae": 24687,
      "quartermaster": 24688,
      "caf": 24689,
      "415": 24690,
      "chatter": 24691,
      "engulfed": 24692,
      "gleam": 24693,
      "purge": 24694,
      "##icate": 24695,
      "juliette": 24696,
      "jurisprudence": 24697,
      "guerra": 24698,
      "revisions": 24699,
      "##bn": 24700,
      "casimir": 24701,
      "brew": 24702,
      "##jm": 24703,
      "1749": 24704,
      "clapton": 24705,
      "cloudy": 24706,
      "conde": 24707,
      "hermitage": 24708,
      "278": 24709,
      "simulations": 24710,
      "torches": 24711,
      "vincenzo": 24712,
      "matteo": 24713,
      "##rill": 24714,
      "hidalgo": 24715,
      "booming": 24716,
      "westbound": 24717,
      "accomplishment": 24718,
      "tentacles": 24719,
      "unaffected": 24720,
      "##sius": 24721,
      "annabelle": 24722,
      "flopped": 24723,
      "sloping": 24724,
      "##litz": 24725,
      "dreamer": 24726,
      "interceptor": 24727,
      "vu": 24728,
      "##loh": 24729,
      "consecration": 24730,
      "copying": 24731,
      "messaging": 24732,
      "breaker": 24733,
      "climates": 24734,
      "hospitalized": 24735,
      "1752": 24736,
      "torino": 24737,
      "afternoons": 24738,
      "winfield": 24739,
      "witnessing": 24740,
      "##teacher": 24741,
      "breakers": 24742,
      "choirs": 24743,
      "sawmill": 24744,
      "coldly": 24745,
      "##ege": 24746,
      "sipping": 24747,
      "haste": 24748,
      "uninhabited": 24749,
      "conical": 24750,
      "bibliography": 24751,
      "pamphlets": 24752,
      "severn": 24753,
      "edict": 24754,
      "##oca": 24755,
      "deux": 24756,
      "illnesses": 24757,
      "grips": 24758,
      "##pl": 24759,
      "rehearsals": 24760,
      "sis": 24761,
      "thinkers": 24762,
      "tame": 24763,
      "##keepers": 24764,
      "1690": 24765,
      "acacia": 24766,
      "reformer": 24767,
      "##osed": 24768,
      "##rys": 24769,
      "shuffling": 24770,
      "##iring": 24771,
      "##shima": 24772,
      "eastbound": 24773,
      "ionic": 24774,
      "rhea": 24775,
      "flees": 24776,
      "littered": 24777,
      "##oum": 24778,
      "rocker": 24779,
      "vomiting": 24780,
      "groaning": 24781,
      "champ": 24782,
      "overwhelmingly": 24783,
      "civilizations": 24784,
      "paces": 24785,
      "sloop": 24786,
      "adoptive": 24787,
      "##tish": 24788,
      "skaters": 24789,
      "##vres": 24790,
      "aiding": 24791,
      "mango": 24792,
      "##joy": 24793,
      "nikola": 24794,
      "shriek": 24795,
      "##ignon": 24796,
      "pharmaceuticals": 24797,
      "##mg": 24798,
      "tuna": 24799,
      "calvert": 24800,
      "gustavo": 24801,
      "stocked": 24802,
      "yearbook": 24803,
      "##urai": 24804,
      "##mana": 24805,
      "computed": 24806,
      "subsp": 24807,
      "riff": 24808,
      "hanoi": 24809,
      "kelvin": 24810,
      "hamid": 24811,
      "moors": 24812,
      "pastures": 24813,
      "summons": 24814,
      "jihad": 24815,
      "nectar": 24816,
      "##ctors": 24817,
      "bayou": 24818,
      "untitled": 24819,
      "pleasing": 24820,
      "vastly": 24821,
      "republics": 24822,
      "intellect": 24823,
      "##η": 24824,
      "##ulio": 24825,
      "##tou": 24826,
      "crumbling": 24827,
      "stylistic": 24828,
      "sb": 24829,
      "##ی": 24830,
      "consolation": 24831,
      "frequented": 24832,
      "h₂o": 24833,
      "walden": 24834,
      "widows": 24835,
      "##iens": 24836,
      "404": 24837,
      "##ignment": 24838,
      "chunks": 24839,
      "improves": 24840,
      "288": 24841,
      "grit": 24842,
      "recited": 24843,
      "##dev": 24844,
      "snarl": 24845,
      "sociological": 24846,
      "##arte": 24847,
      "##gul": 24848,
      "inquired": 24849,
      "##held": 24850,
      "bruise": 24851,
      "clube": 24852,
      "consultancy": 24853,
      "homogeneous": 24854,
      "hornets": 24855,
      "multiplication": 24856,
      "pasta": 24857,
      "prick": 24858,
      "savior": 24859,
      "##grin": 24860,
      "##kou": 24861,
      "##phile": 24862,
      "yoon": 24863,
      "##gara": 24864,
      "grimes": 24865,
      "vanishing": 24866,
      "cheering": 24867,
      "reacting": 24868,
      "bn": 24869,
      "distillery": 24870,
      "##quisite": 24871,
      "##vity": 24872,
      "coe": 24873,
      "dockyard": 24874,
      "massif": 24875,
      "##jord": 24876,
      "escorts": 24877,
      "voss": 24878,
      "##valent": 24879,
      "byte": 24880,
      "chopped": 24881,
      "hawke": 24882,
      "illusions": 24883,
      "workings": 24884,
      "floats": 24885,
      "##koto": 24886,
      "##vac": 24887,
      "kv": 24888,
      "annapolis": 24889,
      "madden": 24890,
      "##onus": 24891,
      "alvaro": 24892,
      "noctuidae": 24893,
      "##cum": 24894,
      "##scopic": 24895,
      "avenge": 24896,
      "steamboat": 24897,
      "forte": 24898,
      "illustrates": 24899,
      "erika": 24900,
      "##trip": 24901,
      "570": 24902,
      "dew": 24903,
      "nationalities": 24904,
      "bran": 24905,
      "manifested": 24906,
      "thirsty": 24907,
      "diversified": 24908,
      "muscled": 24909,
      "reborn": 24910,
      "##standing": 24911,
      "arson": 24912,
      "##lessness": 24913,
      "##dran": 24914,
      "##logram": 24915,
      "##boys": 24916,
      "##kushima": 24917,
      "##vious": 24918,
      "willoughby": 24919,
      "##phobia": 24920,
      "286": 24921,
      "alsace": 24922,
      "dashboard": 24923,
      "yuki": 24924,
      "##chai": 24925,
      "granville": 24926,
      "myspace": 24927,
      "publicized": 24928,
      "tricked": 24929,
      "##gang": 24930,
      "adjective": 24931,
      "##ater": 24932,
      "relic": 24933,
      "reorganisation": 24934,
      "enthusiastically": 24935,
      "indications": 24936,
      "saxe": 24937,
      "##lassified": 24938,
      "consolidate": 24939,
      "iec": 24940,
      "padua": 24941,
      "helplessly": 24942,
      "ramps": 24943,
      "renaming": 24944,
      "regulars": 24945,
      "pedestrians": 24946,
      "accents": 24947,
      "convicts": 24948,
      "inaccurate": 24949,
      "lowers": 24950,
      "mana": 24951,
      "##pati": 24952,
      "barrie": 24953,
      "bjp": 24954,
      "outta": 24955,
      "someplace": 24956,
      "berwick": 24957,
      "flanking": 24958,
      "invoked": 24959,
      "marrow": 24960,
      "sparsely": 24961,
      "excerpts": 24962,
      "clothed": 24963,
      "rei": 24964,
      "##ginal": 24965,
      "wept": 24966,
      "##straße": 24967,
      "##vish": 24968,
      "alexa": 24969,
      "excel": 24970,
      "##ptive": 24971,
      "membranes": 24972,
      "aquitaine": 24973,
      "creeks": 24974,
      "cutler": 24975,
      "sheppard": 24976,
      "implementations": 24977,
      "ns": 24978,
      "##dur": 24979,
      "fragrance": 24980,
      "budge": 24981,
      "concordia": 24982,
      "magnesium": 24983,
      "marcelo": 24984,
      "##antes": 24985,
      "gladly": 24986,
      "vibrating": 24987,
      "##rral": 24988,
      "##ggles": 24989,
      "montrose": 24990,
      "##omba": 24991,
      "lew": 24992,
      "seamus": 24993,
      "1630": 24994,
      "cocky": 24995,
      "##ament": 24996,
      "##uen": 24997,
      "bjorn": 24998,
      "##rrick": 24999,
      "fielder": 25000,
      "fluttering": 25001,
      "##lase": 25002,
      "methyl": 25003,
      "kimberley": 25004,
      "mcdowell": 25005,
      "reductions": 25006,
      "barbed": 25007,
      "##jic": 25008,
      "##tonic": 25009,
      "aeronautical": 25010,
      "condensed": 25011,
      "distracting": 25012,
      "##promising": 25013,
      "huffed": 25014,
      "##cala": 25015,
      "##sle": 25016,
      "claudius": 25017,
      "invincible": 25018,
      "missy": 25019,
      "pious": 25020,
      "balthazar": 25021,
      "ci": 25022,
      "##lang": 25023,
      "butte": 25024,
      "combo": 25025,
      "orson": 25026,
      "##dication": 25027,
      "myriad": 25028,
      "1707": 25029,
      "silenced": 25030,
      "##fed": 25031,
      "##rh": 25032,
      "coco": 25033,
      "netball": 25034,
      "yourselves": 25035,
      "##oza": 25036,
      "clarify": 25037,
      "heller": 25038,
      "peg": 25039,
      "durban": 25040,
      "etudes": 25041,
      "offender": 25042,
      "roast": 25043,
      "blackmail": 25044,
      "curvature": 25045,
      "##woods": 25046,
      "vile": 25047,
      "309": 25048,
      "illicit": 25049,
      "suriname": 25050,
      "##linson": 25051,
      "overture": 25052,
      "1685": 25053,
      "bubbling": 25054,
      "gymnast": 25055,
      "tucking": 25056,
      "##mming": 25057,
      "##ouin": 25058,
      "maldives": 25059,
      "##bala": 25060,
      "gurney": 25061,
      "##dda": 25062,
      "##eased": 25063,
      "##oides": 25064,
      "backside": 25065,
      "pinto": 25066,
      "jars": 25067,
      "racehorse": 25068,
      "tending": 25069,
      "##rdial": 25070,
      "baronetcy": 25071,
      "wiener": 25072,
      "duly": 25073,
      "##rke": 25074,
      "barbarian": 25075,
      "cupping": 25076,
      "flawed": 25077,
      "##thesis": 25078,
      "bertha": 25079,
      "pleistocene": 25080,
      "puddle": 25081,
      "swearing": 25082,
      "##nob": 25083,
      "##tically": 25084,
      "fleeting": 25085,
      "prostate": 25086,
      "amulet": 25087,
      "educating": 25088,
      "##mined": 25089,
      "##iti": 25090,
      "##tler": 25091,
      "75th": 25092,
      "jens": 25093,
      "respondents": 25094,
      "analytics": 25095,
      "cavaliers": 25096,
      "papacy": 25097,
      "raju": 25098,
      "##iente": 25099,
      "##ulum": 25100,
      "##tip": 25101,
      "funnel": 25102,
      "271": 25103,
      "disneyland": 25104,
      "##lley": 25105,
      "sociologist": 25106,
      "##iam": 25107,
      "2500": 25108,
      "faulkner": 25109,
      "louvre": 25110,
      "menon": 25111,
      "##dson": 25112,
      "276": 25113,
      "##ower": 25114,
      "afterlife": 25115,
      "mannheim": 25116,
      "peptide": 25117,
      "referees": 25118,
      "comedians": 25119,
      "meaningless": 25120,
      "##anger": 25121,
      "##laise": 25122,
      "fabrics": 25123,
      "hurley": 25124,
      "renal": 25125,
      "sleeps": 25126,
      "##bour": 25127,
      "##icle": 25128,
      "breakout": 25129,
      "kristin": 25130,
      "roadside": 25131,
      "animator": 25132,
      "clover": 25133,
      "disdain": 25134,
      "unsafe": 25135,
      "redesign": 25136,
      "##urity": 25137,
      "firth": 25138,
      "barnsley": 25139,
      "portage": 25140,
      "reset": 25141,
      "narrows": 25142,
      "268": 25143,
      "commandos": 25144,
      "expansive": 25145,
      "speechless": 25146,
      "tubular": 25147,
      "##lux": 25148,
      "essendon": 25149,
      "eyelashes": 25150,
      "smashwords": 25151,
      "##yad": 25152,
      "##bang": 25153,
      "##claim": 25154,
      "craved": 25155,
      "sprinted": 25156,
      "chet": 25157,
      "somme": 25158,
      "astor": 25159,
      "wrocław": 25160,
      "orton": 25161,
      "266": 25162,
      "bane": 25163,
      "##erving": 25164,
      "##uing": 25165,
      "mischief": 25166,
      "##amps": 25167,
      "##sund": 25168,
      "scaling": 25169,
      "terre": 25170,
      "##xious": 25171,
      "impairment": 25172,
      "offenses": 25173,
      "undermine": 25174,
      "moi": 25175,
      "soy": 25176,
      "contiguous": 25177,
      "arcadia": 25178,
      "inuit": 25179,
      "seam": 25180,
      "##tops": 25181,
      "macbeth": 25182,
      "rebelled": 25183,
      "##icative": 25184,
      "##iot": 25185,
      "590": 25186,
      "elaborated": 25187,
      "frs": 25188,
      "uniformed": 25189,
      "##dberg": 25190,
      "259": 25191,
      "powerless": 25192,
      "priscilla": 25193,
      "stimulated": 25194,
      "980": 25195,
      "qc": 25196,
      "arboretum": 25197,
      "frustrating": 25198,
      "trieste": 25199,
      "bullock": 25200,
      "##nified": 25201,
      "enriched": 25202,
      "glistening": 25203,
      "intern": 25204,
      "##adia": 25205,
      "locus": 25206,
      "nouvelle": 25207,
      "ollie": 25208,
      "ike": 25209,
      "lash": 25210,
      "starboard": 25211,
      "ee": 25212,
      "tapestry": 25213,
      "headlined": 25214,
      "hove": 25215,
      "rigged": 25216,
      "##vite": 25217,
      "pollock": 25218,
      "##yme": 25219,
      "thrive": 25220,
      "clustered": 25221,
      "cas": 25222,
      "roi": 25223,
      "gleamed": 25224,
      "olympiad": 25225,
      "##lino": 25226,
      "pressured": 25227,
      "regimes": 25228,
      "##hosis": 25229,
      "##lick": 25230,
      "ripley": 25231,
      "##ophone": 25232,
      "kickoff": 25233,
      "gallon": 25234,
      "rockwell": 25235,
      "##arable": 25236,
      "crusader": 25237,
      "glue": 25238,
      "revolutions": 25239,
      "scrambling": 25240,
      "1714": 25241,
      "grover": 25242,
      "##jure": 25243,
      "englishman": 25244,
      "aztec": 25245,
      "263": 25246,
      "contemplating": 25247,
      "coven": 25248,
      "ipad": 25249,
      "preach": 25250,
      "triumphant": 25251,
      "tufts": 25252,
      "##esian": 25253,
      "rotational": 25254,
      "##phus": 25255,
      "328": 25256,
      "falkland": 25257,
      "##brates": 25258,
      "strewn": 25259,
      "clarissa": 25260,
      "rejoin": 25261,
      "environmentally": 25262,
      "glint": 25263,
      "banded": 25264,
      "drenched": 25265,
      "moat": 25266,
      "albanians": 25267,
      "johor": 25268,
      "rr": 25269,
      "maestro": 25270,
      "malley": 25271,
      "nouveau": 25272,
      "shaded": 25273,
      "taxonomy": 25274,
      "v6": 25275,
      "adhere": 25276,
      "bunk": 25277,
      "airfields": 25278,
      "##ritan": 25279,
      "1741": 25280,
      "encompass": 25281,
      "remington": 25282,
      "tran": 25283,
      "##erative": 25284,
      "amelie": 25285,
      "mazda": 25286,
      "friar": 25287,
      "morals": 25288,
      "passions": 25289,
      "##zai": 25290,
      "breadth": 25291,
      "vis": 25292,
      "##hae": 25293,
      "argus": 25294,
      "burnham": 25295,
      "caressing": 25296,
      "insider": 25297,
      "rudd": 25298,
      "##imov": 25299,
      "##mini": 25300,
      "##rso": 25301,
      "italianate": 25302,
      "murderous": 25303,
      "textual": 25304,
      "wainwright": 25305,
      "armada": 25306,
      "bam": 25307,
      "weave": 25308,
      "timer": 25309,
      "##taken": 25310,
      "##nh": 25311,
      "fra": 25312,
      "##crest": 25313,
      "ardent": 25314,
      "salazar": 25315,
      "taps": 25316,
      "tunis": 25317,
      "##ntino": 25318,
      "allegro": 25319,
      "gland": 25320,
      "philanthropic": 25321,
      "##chester": 25322,
      "implication": 25323,
      "##optera": 25324,
      "esq": 25325,
      "judas": 25326,
      "noticeably": 25327,
      "wynn": 25328,
      "##dara": 25329,
      "inched": 25330,
      "indexed": 25331,
      "crises": 25332,
      "villiers": 25333,
      "bandit": 25334,
      "royalties": 25335,
      "patterned": 25336,
      "cupboard": 25337,
      "interspersed": 25338,
      "accessory": 25339,
      "isla": 25340,
      "kendrick": 25341,
      "entourage": 25342,
      "stitches": 25343,
      "##esthesia": 25344,
      "headwaters": 25345,
      "##ior": 25346,
      "interlude": 25347,
      "distraught": 25348,
      "draught": 25349,
      "1727": 25350,
      "##basket": 25351,
      "biased": 25352,
      "sy": 25353,
      "transient": 25354,
      "triad": 25355,
      "subgenus": 25356,
      "adapting": 25357,
      "kidd": 25358,
      "shortstop": 25359,
      "##umatic": 25360,
      "dimly": 25361,
      "spiked": 25362,
      "mcleod": 25363,
      "reprint": 25364,
      "nellie": 25365,
      "pretoria": 25366,
      "windmill": 25367,
      "##cek": 25368,
      "singled": 25369,
      "##mps": 25370,
      "273": 25371,
      "reunite": 25372,
      "##orous": 25373,
      "747": 25374,
      "bankers": 25375,
      "outlying": 25376,
      "##omp": 25377,
      "##ports": 25378,
      "##tream": 25379,
      "apologies": 25380,
      "cosmetics": 25381,
      "patsy": 25382,
      "##deh": 25383,
      "##ocks": 25384,
      "##yson": 25385,
      "bender": 25386,
      "nantes": 25387,
      "serene": 25388,
      "##nad": 25389,
      "lucha": 25390,
      "mmm": 25391,
      "323": 25392,
      "##cius": 25393,
      "##gli": 25394,
      "cmll": 25395,
      "coinage": 25396,
      "nestor": 25397,
      "juarez": 25398,
      "##rook": 25399,
      "smeared": 25400,
      "sprayed": 25401,
      "twitching": 25402,
      "sterile": 25403,
      "irina": 25404,
      "embodied": 25405,
      "juveniles": 25406,
      "enveloped": 25407,
      "miscellaneous": 25408,
      "cancers": 25409,
      "dq": 25410,
      "gulped": 25411,
      "luisa": 25412,
      "crested": 25413,
      "swat": 25414,
      "donegal": 25415,
      "ref": 25416,
      "##anov": 25417,
      "##acker": 25418,
      "hearst": 25419,
      "mercantile": 25420,
      "##lika": 25421,
      "doorbell": 25422,
      "ua": 25423,
      "vicki": 25424,
      "##alla": 25425,
      "##som": 25426,
      "bilbao": 25427,
      "psychologists": 25428,
      "stryker": 25429,
      "sw": 25430,
      "horsemen": 25431,
      "turkmenistan": 25432,
      "wits": 25433,
      "##national": 25434,
      "anson": 25435,
      "mathew": 25436,
      "screenings": 25437,
      "##umb": 25438,
      "rihanna": 25439,
      "##agne": 25440,
      "##nessy": 25441,
      "aisles": 25442,
      "##iani": 25443,
      "##osphere": 25444,
      "hines": 25445,
      "kenton": 25446,
      "saskatoon": 25447,
      "tasha": 25448,
      "truncated": 25449,
      "##champ": 25450,
      "##itan": 25451,
      "mildred": 25452,
      "advises": 25453,
      "fredrik": 25454,
      "interpreting": 25455,
      "inhibitors": 25456,
      "##athi": 25457,
      "spectroscopy": 25458,
      "##hab": 25459,
      "##kong": 25460,
      "karim": 25461,
      "panda": 25462,
      "##oia": 25463,
      "##nail": 25464,
      "##vc": 25465,
      "conqueror": 25466,
      "kgb": 25467,
      "leukemia": 25468,
      "##dity": 25469,
      "arrivals": 25470,
      "cheered": 25471,
      "pisa": 25472,
      "phosphorus": 25473,
      "shielded": 25474,
      "##riated": 25475,
      "mammal": 25476,
      "unitarian": 25477,
      "urgently": 25478,
      "chopin": 25479,
      "sanitary": 25480,
      "##mission": 25481,
      "spicy": 25482,
      "drugged": 25483,
      "hinges": 25484,
      "##tort": 25485,
      "tipping": 25486,
      "trier": 25487,
      "impoverished": 25488,
      "westchester": 25489,
      "##caster": 25490,
      "267": 25491,
      "epoch": 25492,
      "nonstop": 25493,
      "##gman": 25494,
      "##khov": 25495,
      "aromatic": 25496,
      "centrally": 25497,
      "cerro": 25498,
      "##tively": 25499,
      "##vio": 25500,
      "billions": 25501,
      "modulation": 25502,
      "sedimentary": 25503,
      "283": 25504,
      "facilitating": 25505,
      "outrageous": 25506,
      "goldstein": 25507,
      "##eak": 25508,
      "##kt": 25509,
      "ld": 25510,
      "maitland": 25511,
      "penultimate": 25512,
      "pollard": 25513,
      "##dance": 25514,
      "fleets": 25515,
      "spaceship": 25516,
      "vertebrae": 25517,
      "##nig": 25518,
      "alcoholism": 25519,
      "als": 25520,
      "recital": 25521,
      "##bham": 25522,
      "##ference": 25523,
      "##omics": 25524,
      "m2": 25525,
      "##bm": 25526,
      "trois": 25527,
      "##tropical": 25528,
      "##в": 25529,
      "commemorates": 25530,
      "##meric": 25531,
      "marge": 25532,
      "##raction": 25533,
      "1643": 25534,
      "670": 25535,
      "cosmetic": 25536,
      "ravaged": 25537,
      "##ige": 25538,
      "catastrophe": 25539,
      "eng": 25540,
      "##shida": 25541,
      "albrecht": 25542,
      "arterial": 25543,
      "bellamy": 25544,
      "decor": 25545,
      "harmon": 25546,
      "##rde": 25547,
      "bulbs": 25548,
      "synchronized": 25549,
      "vito": 25550,
      "easiest": 25551,
      "shetland": 25552,
      "shielding": 25553,
      "wnba": 25554,
      "##glers": 25555,
      "##ssar": 25556,
      "##riam": 25557,
      "brianna": 25558,
      "cumbria": 25559,
      "##aceous": 25560,
      "##rard": 25561,
      "cores": 25562,
      "thayer": 25563,
      "##nsk": 25564,
      "brood": 25565,
      "hilltop": 25566,
      "luminous": 25567,
      "carts": 25568,
      "keynote": 25569,
      "larkin": 25570,
      "logos": 25571,
      "##cta": 25572,
      "##ا": 25573,
      "##mund": 25574,
      "##quay": 25575,
      "lilith": 25576,
      "tinted": 25577,
      "277": 25578,
      "wrestle": 25579,
      "mobilization": 25580,
      "##uses": 25581,
      "sequential": 25582,
      "siam": 25583,
      "bloomfield": 25584,
      "takahashi": 25585,
      "274": 25586,
      "##ieving": 25587,
      "presenters": 25588,
      "ringo": 25589,
      "blazed": 25590,
      "witty": 25591,
      "##oven": 25592,
      "##ignant": 25593,
      "devastation": 25594,
      "haydn": 25595,
      "harmed": 25596,
      "newt": 25597,
      "therese": 25598,
      "##peed": 25599,
      "gershwin": 25600,
      "molina": 25601,
      "rabbis": 25602,
      "sudanese": 25603,
      "001": 25604,
      "innate": 25605,
      "restarted": 25606,
      "##sack": 25607,
      "##fus": 25608,
      "slices": 25609,
      "wb": 25610,
      "##shah": 25611,
      "enroll": 25612,
      "hypothetical": 25613,
      "hysterical": 25614,
      "1743": 25615,
      "fabio": 25616,
      "indefinite": 25617,
      "warped": 25618,
      "##hg": 25619,
      "exchanging": 25620,
      "525": 25621,
      "unsuitable": 25622,
      "##sboro": 25623,
      "gallo": 25624,
      "1603": 25625,
      "bret": 25626,
      "cobalt": 25627,
      "homemade": 25628,
      "##hunter": 25629,
      "mx": 25630,
      "operatives": 25631,
      "##dhar": 25632,
      "terraces": 25633,
      "durable": 25634,
      "latch": 25635,
      "pens": 25636,
      "whorls": 25637,
      "##ctuated": 25638,
      "##eaux": 25639,
      "billing": 25640,
      "ligament": 25641,
      "succumbed": 25642,
      "##gly": 25643,
      "regulators": 25644,
      "spawn": 25645,
      "##brick": 25646,
      "##stead": 25647,
      "filmfare": 25648,
      "rochelle": 25649,
      "##nzo": 25650,
      "1725": 25651,
      "circumstance": 25652,
      "saber": 25653,
      "supplements": 25654,
      "##nsky": 25655,
      "##tson": 25656,
      "crowe": 25657,
      "wellesley": 25658,
      "carrot": 25659,
      "##9th": 25660,
      "##movable": 25661,
      "primate": 25662,
      "drury": 25663,
      "sincerely": 25664,
      "topical": 25665,
      "##mad": 25666,
      "##rao": 25667,
      "callahan": 25668,
      "kyiv": 25669,
      "smarter": 25670,
      "tits": 25671,
      "undo": 25672,
      "##yeh": 25673,
      "announcements": 25674,
      "anthologies": 25675,
      "barrio": 25676,
      "nebula": 25677,
      "##islaus": 25678,
      "##shaft": 25679,
      "##tyn": 25680,
      "bodyguards": 25681,
      "2021": 25682,
      "assassinate": 25683,
      "barns": 25684,
      "emmett": 25685,
      "scully": 25686,
      "##mah": 25687,
      "##yd": 25688,
      "##eland": 25689,
      "##tino": 25690,
      "##itarian": 25691,
      "demoted": 25692,
      "gorman": 25693,
      "lashed": 25694,
      "prized": 25695,
      "adventist": 25696,
      "writ": 25697,
      "##gui": 25698,
      "alla": 25699,
      "invertebrates": 25700,
      "##ausen": 25701,
      "1641": 25702,
      "amman": 25703,
      "1742": 25704,
      "align": 25705,
      "healy": 25706,
      "redistribution": 25707,
      "##gf": 25708,
      "##rize": 25709,
      "insulation": 25710,
      "##drop": 25711,
      "adherents": 25712,
      "hezbollah": 25713,
      "vitro": 25714,
      "ferns": 25715,
      "yanking": 25716,
      "269": 25717,
      "php": 25718,
      "registering": 25719,
      "uppsala": 25720,
      "cheerleading": 25721,
      "confines": 25722,
      "mischievous": 25723,
      "tully": 25724,
      "##ross": 25725,
      "49th": 25726,
      "docked": 25727,
      "roam": 25728,
      "stipulated": 25729,
      "pumpkin": 25730,
      "##bry": 25731,
      "prompt": 25732,
      "##ezer": 25733,
      "blindly": 25734,
      "shuddering": 25735,
      "craftsmen": 25736,
      "frail": 25737,
      "scented": 25738,
      "katharine": 25739,
      "scramble": 25740,
      "shaggy": 25741,
      "sponge": 25742,
      "helix": 25743,
      "zaragoza": 25744,
      "279": 25745,
      "##52": 25746,
      "43rd": 25747,
      "backlash": 25748,
      "fontaine": 25749,
      "seizures": 25750,
      "posse": 25751,
      "cowan": 25752,
      "nonfiction": 25753,
      "telenovela": 25754,
      "wwii": 25755,
      "hammered": 25756,
      "undone": 25757,
      "##gpur": 25758,
      "encircled": 25759,
      "irs": 25760,
      "##ivation": 25761,
      "artefacts": 25762,
      "oneself": 25763,
      "searing": 25764,
      "smallpox": 25765,
      "##belle": 25766,
      "##osaurus": 25767,
      "shandong": 25768,
      "breached": 25769,
      "upland": 25770,
      "blushing": 25771,
      "rankin": 25772,
      "infinitely": 25773,
      "psyche": 25774,
      "tolerated": 25775,
      "docking": 25776,
      "evicted": 25777,
      "##col": 25778,
      "unmarked": 25779,
      "##lving": 25780,
      "gnome": 25781,
      "lettering": 25782,
      "litres": 25783,
      "musique": 25784,
      "##oint": 25785,
      "benevolent": 25786,
      "##jal": 25787,
      "blackened": 25788,
      "##anna": 25789,
      "mccall": 25790,
      "racers": 25791,
      "tingle": 25792,
      "##ocene": 25793,
      "##orestation": 25794,
      "introductions": 25795,
      "radically": 25796,
      "292": 25797,
      "##hiff": 25798,
      "##باد": 25799,
      "1610": 25800,
      "1739": 25801,
      "munchen": 25802,
      "plead": 25803,
      "##nka": 25804,
      "condo": 25805,
      "scissors": 25806,
      "##sight": 25807,
      "##tens": 25808,
      "apprehension": 25809,
      "##cey": 25810,
      "##yin": 25811,
      "hallmark": 25812,
      "watering": 25813,
      "formulas": 25814,
      "sequels": 25815,
      "##llas": 25816,
      "aggravated": 25817,
      "bae": 25818,
      "commencing": 25819,
      "##building": 25820,
      "enfield": 25821,
      "prohibits": 25822,
      "marne": 25823,
      "vedic": 25824,
      "civilized": 25825,
      "euclidean": 25826,
      "jagger": 25827,
      "beforehand": 25828,
      "blasts": 25829,
      "dumont": 25830,
      "##arney": 25831,
      "##nem": 25832,
      "740": 25833,
      "conversions": 25834,
      "hierarchical": 25835,
      "rios": 25836,
      "simulator": 25837,
      "##dya": 25838,
      "##lellan": 25839,
      "hedges": 25840,
      "oleg": 25841,
      "thrusts": 25842,
      "shadowed": 25843,
      "darby": 25844,
      "maximize": 25845,
      "1744": 25846,
      "gregorian": 25847,
      "##nded": 25848,
      "##routed": 25849,
      "sham": 25850,
      "unspecified": 25851,
      "##hog": 25852,
      "emory": 25853,
      "factual": 25854,
      "##smo": 25855,
      "##tp": 25856,
      "fooled": 25857,
      "##rger": 25858,
      "ortega": 25859,
      "wellness": 25860,
      "marlon": 25861,
      "##oton": 25862,
      "##urance": 25863,
      "casket": 25864,
      "keating": 25865,
      "ley": 25866,
      "enclave": 25867,
      "##ayan": 25868,
      "char": 25869,
      "influencing": 25870,
      "jia": 25871,
      "##chenko": 25872,
      "412": 25873,
      "ammonia": 25874,
      "erebidae": 25875,
      "incompatible": 25876,
      "violins": 25877,
      "cornered": 25878,
      "##arat": 25879,
      "grooves": 25880,
      "astronauts": 25881,
      "columbian": 25882,
      "rampant": 25883,
      "fabrication": 25884,
      "kyushu": 25885,
      "mahmud": 25886,
      "vanish": 25887,
      "##dern": 25888,
      "mesopotamia": 25889,
      "##lete": 25890,
      "ict": 25891,
      "##rgen": 25892,
      "caspian": 25893,
      "kenji": 25894,
      "pitted": 25895,
      "##vered": 25896,
      "999": 25897,
      "grimace": 25898,
      "roanoke": 25899,
      "tchaikovsky": 25900,
      "twinned": 25901,
      "##analysis": 25902,
      "##awan": 25903,
      "xinjiang": 25904,
      "arias": 25905,
      "clemson": 25906,
      "kazakh": 25907,
      "sizable": 25908,
      "1662": 25909,
      "##khand": 25910,
      "##vard": 25911,
      "plunge": 25912,
      "tatum": 25913,
      "vittorio": 25914,
      "##nden": 25915,
      "cholera": 25916,
      "##dana": 25917,
      "##oper": 25918,
      "bracing": 25919,
      "indifference": 25920,
      "projectile": 25921,
      "superliga": 25922,
      "##chee": 25923,
      "realises": 25924,
      "upgrading": 25925,
      "299": 25926,
      "porte": 25927,
      "retribution": 25928,
      "##vies": 25929,
      "nk": 25930,
      "stil": 25931,
      "##resses": 25932,
      "ama": 25933,
      "bureaucracy": 25934,
      "blackberry": 25935,
      "bosch": 25936,
      "testosterone": 25937,
      "collapses": 25938,
      "greer": 25939,
      "##pathic": 25940,
      "ioc": 25941,
      "fifties": 25942,
      "malls": 25943,
      "##erved": 25944,
      "bao": 25945,
      "baskets": 25946,
      "adolescents": 25947,
      "siegfried": 25948,
      "##osity": 25949,
      "##tosis": 25950,
      "mantra": 25951,
      "detecting": 25952,
      "existent": 25953,
      "fledgling": 25954,
      "##cchi": 25955,
      "dissatisfied": 25956,
      "gan": 25957,
      "telecommunication": 25958,
      "mingled": 25959,
      "sobbed": 25960,
      "6000": 25961,
      "controversies": 25962,
      "outdated": 25963,
      "taxis": 25964,
      "##raus": 25965,
      "fright": 25966,
      "slams": 25967,
      "##lham": 25968,
      "##fect": 25969,
      "##tten": 25970,
      "detectors": 25971,
      "fetal": 25972,
      "tanned": 25973,
      "##uw": 25974,
      "fray": 25975,
      "goth": 25976,
      "olympian": 25977,
      "skipping": 25978,
      "mandates": 25979,
      "scratches": 25980,
      "sheng": 25981,
      "unspoken": 25982,
      "hyundai": 25983,
      "tracey": 25984,
      "hotspur": 25985,
      "restrictive": 25986,
      "##buch": 25987,
      "americana": 25988,
      "mundo": 25989,
      "##bari": 25990,
      "burroughs": 25991,
      "diva": 25992,
      "vulcan": 25993,
      "##6th": 25994,
      "distinctions": 25995,
      "thumping": 25996,
      "##ngen": 25997,
      "mikey": 25998,
      "sheds": 25999,
      "fide": 26000,
      "rescues": 26001,
      "springsteen": 26002,
      "vested": 26003,
      "valuation": 26004,
      "##ece": 26005,
      "##ely": 26006,
      "pinnacle": 26007,
      "rake": 26008,
      "sylvie": 26009,
      "##edo": 26010,
      "almond": 26011,
      "quivering": 26012,
      "##irus": 26013,
      "alteration": 26014,
      "faltered": 26015,
      "##wad": 26016,
      "51st": 26017,
      "hydra": 26018,
      "ticked": 26019,
      "##kato": 26020,
      "recommends": 26021,
      "##dicated": 26022,
      "antigua": 26023,
      "arjun": 26024,
      "stagecoach": 26025,
      "wilfred": 26026,
      "trickle": 26027,
      "pronouns": 26028,
      "##pon": 26029,
      "aryan": 26030,
      "nighttime": 26031,
      "##anian": 26032,
      "gall": 26033,
      "pea": 26034,
      "stitch": 26035,
      "##hei": 26036,
      "leung": 26037,
      "milos": 26038,
      "##dini": 26039,
      "eritrea": 26040,
      "nexus": 26041,
      "starved": 26042,
      "snowfall": 26043,
      "kant": 26044,
      "parasitic": 26045,
      "cot": 26046,
      "discus": 26047,
      "hana": 26048,
      "strikers": 26049,
      "appleton": 26050,
      "kitchens": 26051,
      "##erina": 26052,
      "##partisan": 26053,
      "##itha": 26054,
      "##vius": 26055,
      "disclose": 26056,
      "metis": 26057,
      "##channel": 26058,
      "1701": 26059,
      "tesla": 26060,
      "##vera": 26061,
      "fitch": 26062,
      "1735": 26063,
      "blooded": 26064,
      "##tila": 26065,
      "decimal": 26066,
      "##tang": 26067,
      "##bai": 26068,
      "cyclones": 26069,
      "eun": 26070,
      "bottled": 26071,
      "peas": 26072,
      "pensacola": 26073,
      "basha": 26074,
      "bolivian": 26075,
      "crabs": 26076,
      "boil": 26077,
      "lanterns": 26078,
      "partridge": 26079,
      "roofed": 26080,
      "1645": 26081,
      "necks": 26082,
      "##phila": 26083,
      "opined": 26084,
      "patting": 26085,
      "##kla": 26086,
      "##lland": 26087,
      "chuckles": 26088,
      "volta": 26089,
      "whereupon": 26090,
      "##nche": 26091,
      "devout": 26092,
      "euroleague": 26093,
      "suicidal": 26094,
      "##dee": 26095,
      "inherently": 26096,
      "involuntary": 26097,
      "knitting": 26098,
      "nasser": 26099,
      "##hide": 26100,
      "puppets": 26101,
      "colourful": 26102,
      "courageous": 26103,
      "southend": 26104,
      "stills": 26105,
      "miraculous": 26106,
      "hodgson": 26107,
      "richer": 26108,
      "rochdale": 26109,
      "ethernet": 26110,
      "greta": 26111,
      "uniting": 26112,
      "prism": 26113,
      "umm": 26114,
      "##haya": 26115,
      "##itical": 26116,
      "##utation": 26117,
      "deterioration": 26118,
      "pointe": 26119,
      "prowess": 26120,
      "##ropriation": 26121,
      "lids": 26122,
      "scranton": 26123,
      "billings": 26124,
      "subcontinent": 26125,
      "##koff": 26126,
      "##scope": 26127,
      "brute": 26128,
      "kellogg": 26129,
      "psalms": 26130,
      "degraded": 26131,
      "##vez": 26132,
      "stanisław": 26133,
      "##ructured": 26134,
      "ferreira": 26135,
      "pun": 26136,
      "astonishing": 26137,
      "gunnar": 26138,
      "##yat": 26139,
      "arya": 26140,
      "prc": 26141,
      "gottfried": 26142,
      "##tight": 26143,
      "excursion": 26144,
      "##ographer": 26145,
      "dina": 26146,
      "##quil": 26147,
      "##nare": 26148,
      "huffington": 26149,
      "illustrious": 26150,
      "wilbur": 26151,
      "gundam": 26152,
      "verandah": 26153,
      "##zard": 26154,
      "naacp": 26155,
      "##odle": 26156,
      "constructive": 26157,
      "fjord": 26158,
      "kade": 26159,
      "##naud": 26160,
      "generosity": 26161,
      "thrilling": 26162,
      "baseline": 26163,
      "cayman": 26164,
      "frankish": 26165,
      "plastics": 26166,
      "accommodations": 26167,
      "zoological": 26168,
      "##fting": 26169,
      "cedric": 26170,
      "qb": 26171,
      "motorized": 26172,
      "##dome": 26173,
      "##otted": 26174,
      "squealed": 26175,
      "tackled": 26176,
      "canucks": 26177,
      "budgets": 26178,
      "situ": 26179,
      "asthma": 26180,
      "dail": 26181,
      "gabled": 26182,
      "grasslands": 26183,
      "whimpered": 26184,
      "writhing": 26185,
      "judgments": 26186,
      "##65": 26187,
      "minnie": 26188,
      "pv": 26189,
      "##carbon": 26190,
      "bananas": 26191,
      "grille": 26192,
      "domes": 26193,
      "monique": 26194,
      "odin": 26195,
      "maguire": 26196,
      "markham": 26197,
      "tierney": 26198,
      "##estra": 26199,
      "##chua": 26200,
      "libel": 26201,
      "poke": 26202,
      "speedy": 26203,
      "atrium": 26204,
      "laval": 26205,
      "notwithstanding": 26206,
      "##edly": 26207,
      "fai": 26208,
      "kala": 26209,
      "##sur": 26210,
      "robb": 26211,
      "##sma": 26212,
      "listings": 26213,
      "luz": 26214,
      "supplementary": 26215,
      "tianjin": 26216,
      "##acing": 26217,
      "enzo": 26218,
      "jd": 26219,
      "ric": 26220,
      "scanner": 26221,
      "croats": 26222,
      "transcribed": 26223,
      "##49": 26224,
      "arden": 26225,
      "cv": 26226,
      "##hair": 26227,
      "##raphy": 26228,
      "##lver": 26229,
      "##uy": 26230,
      "357": 26231,
      "seventies": 26232,
      "staggering": 26233,
      "alam": 26234,
      "horticultural": 26235,
      "hs": 26236,
      "regression": 26237,
      "timbers": 26238,
      "blasting": 26239,
      "##ounded": 26240,
      "montagu": 26241,
      "manipulating": 26242,
      "##cit": 26243,
      "catalytic": 26244,
      "1550": 26245,
      "troopers": 26246,
      "##meo": 26247,
      "condemnation": 26248,
      "fitzpatrick": 26249,
      "##oire": 26250,
      "##roved": 26251,
      "inexperienced": 26252,
      "1670": 26253,
      "castes": 26254,
      "##lative": 26255,
      "outing": 26256,
      "314": 26257,
      "dubois": 26258,
      "flicking": 26259,
      "quarrel": 26260,
      "ste": 26261,
      "learners": 26262,
      "1625": 26263,
      "iq": 26264,
      "whistled": 26265,
      "##class": 26266,
      "282": 26267,
      "classify": 26268,
      "tariffs": 26269,
      "temperament": 26270,
      "355": 26271,
      "folly": 26272,
      "liszt": 26273,
      "##yles": 26274,
      "immersed": 26275,
      "jordanian": 26276,
      "ceasefire": 26277,
      "apparel": 26278,
      "extras": 26279,
      "maru": 26280,
      "fished": 26281,
      "##bio": 26282,
      "harta": 26283,
      "stockport": 26284,
      "assortment": 26285,
      "craftsman": 26286,
      "paralysis": 26287,
      "transmitters": 26288,
      "##cola": 26289,
      "blindness": 26290,
      "##wk": 26291,
      "fatally": 26292,
      "proficiency": 26293,
      "solemnly": 26294,
      "##orno": 26295,
      "repairing": 26296,
      "amore": 26297,
      "groceries": 26298,
      "ultraviolet": 26299,
      "##chase": 26300,
      "schoolhouse": 26301,
      "##tua": 26302,
      "resurgence": 26303,
      "nailed": 26304,
      "##otype": 26305,
      "##×": 26306,
      "ruse": 26307,
      "saliva": 26308,
      "diagrams": 26309,
      "##tructing": 26310,
      "albans": 26311,
      "rann": 26312,
      "thirties": 26313,
      "1b": 26314,
      "antennas": 26315,
      "hilarious": 26316,
      "cougars": 26317,
      "paddington": 26318,
      "stats": 26319,
      "##eger": 26320,
      "breakaway": 26321,
      "ipod": 26322,
      "reza": 26323,
      "authorship": 26324,
      "prohibiting": 26325,
      "scoffed": 26326,
      "##etz": 26327,
      "##ttle": 26328,
      "conscription": 26329,
      "defected": 26330,
      "trondheim": 26331,
      "##fires": 26332,
      "ivanov": 26333,
      "keenan": 26334,
      "##adan": 26335,
      "##ciful": 26336,
      "##fb": 26337,
      "##slow": 26338,
      "locating": 26339,
      "##ials": 26340,
      "##tford": 26341,
      "cadiz": 26342,
      "basalt": 26343,
      "blankly": 26344,
      "interned": 26345,
      "rags": 26346,
      "rattling": 26347,
      "##tick": 26348,
      "carpathian": 26349,
      "reassured": 26350,
      "sync": 26351,
      "bum": 26352,
      "guildford": 26353,
      "iss": 26354,
      "staunch": 26355,
      "##onga": 26356,
      "astronomers": 26357,
      "sera": 26358,
      "sofie": 26359,
      "emergencies": 26360,
      "susquehanna": 26361,
      "##heard": 26362,
      "duc": 26363,
      "mastery": 26364,
      "vh1": 26365,
      "williamsburg": 26366,
      "bayer": 26367,
      "buckled": 26368,
      "craving": 26369,
      "##khan": 26370,
      "##rdes": 26371,
      "bloomington": 26372,
      "##write": 26373,
      "alton": 26374,
      "barbecue": 26375,
      "##bians": 26376,
      "justine": 26377,
      "##hri": 26378,
      "##ndt": 26379,
      "delightful": 26380,
      "smartphone": 26381,
      "newtown": 26382,
      "photon": 26383,
      "retrieval": 26384,
      "peugeot": 26385,
      "hissing": 26386,
      "##monium": 26387,
      "##orough": 26388,
      "flavors": 26389,
      "lighted": 26390,
      "relaunched": 26391,
      "tainted": 26392,
      "##games": 26393,
      "##lysis": 26394,
      "anarchy": 26395,
      "microscopic": 26396,
      "hopping": 26397,
      "adept": 26398,
      "evade": 26399,
      "evie": 26400,
      "##beau": 26401,
      "inhibit": 26402,
      "sinn": 26403,
      "adjustable": 26404,
      "hurst": 26405,
      "intuition": 26406,
      "wilton": 26407,
      "cisco": 26408,
      "44th": 26409,
      "lawful": 26410,
      "lowlands": 26411,
      "stockings": 26412,
      "thierry": 26413,
      "##dalen": 26414,
      "##hila": 26415,
      "##nai": 26416,
      "fates": 26417,
      "prank": 26418,
      "tb": 26419,
      "maison": 26420,
      "lobbied": 26421,
      "provocative": 26422,
      "1724": 26423,
      "4a": 26424,
      "utopia": 26425,
      "##qual": 26426,
      "carbonate": 26427,
      "gujarati": 26428,
      "purcell": 26429,
      "##rford": 26430,
      "curtiss": 26431,
      "##mei": 26432,
      "overgrown": 26433,
      "arenas": 26434,
      "mediation": 26435,
      "swallows": 26436,
      "##rnik": 26437,
      "respectful": 26438,
      "turnbull": 26439,
      "##hedron": 26440,
      "##hope": 26441,
      "alyssa": 26442,
      "ozone": 26443,
      "##ʻi": 26444,
      "ami": 26445,
      "gestapo": 26446,
      "johansson": 26447,
      "snooker": 26448,
      "canteen": 26449,
      "cuff": 26450,
      "declines": 26451,
      "empathy": 26452,
      "stigma": 26453,
      "##ags": 26454,
      "##iner": 26455,
      "##raine": 26456,
      "taxpayers": 26457,
      "gui": 26458,
      "volga": 26459,
      "##wright": 26460,
      "##copic": 26461,
      "lifespan": 26462,
      "overcame": 26463,
      "tattooed": 26464,
      "enactment": 26465,
      "giggles": 26466,
      "##ador": 26467,
      "##camp": 26468,
      "barrington": 26469,
      "bribe": 26470,
      "obligatory": 26471,
      "orbiting": 26472,
      "peng": 26473,
      "##enas": 26474,
      "elusive": 26475,
      "sucker": 26476,
      "##vating": 26477,
      "cong": 26478,
      "hardship": 26479,
      "empowered": 26480,
      "anticipating": 26481,
      "estrada": 26482,
      "cryptic": 26483,
      "greasy": 26484,
      "detainees": 26485,
      "planck": 26486,
      "sudbury": 26487,
      "plaid": 26488,
      "dod": 26489,
      "marriott": 26490,
      "kayla": 26491,
      "##ears": 26492,
      "##vb": 26493,
      "##zd": 26494,
      "mortally": 26495,
      "##hein": 26496,
      "cognition": 26497,
      "radha": 26498,
      "319": 26499,
      "liechtenstein": 26500,
      "meade": 26501,
      "richly": 26502,
      "argyle": 26503,
      "harpsichord": 26504,
      "liberalism": 26505,
      "trumpets": 26506,
      "lauded": 26507,
      "tyrant": 26508,
      "salsa": 26509,
      "tiled": 26510,
      "lear": 26511,
      "promoters": 26512,
      "reused": 26513,
      "slicing": 26514,
      "trident": 26515,
      "##chuk": 26516,
      "##gami": 26517,
      "##lka": 26518,
      "cantor": 26519,
      "checkpoint": 26520,
      "##points": 26521,
      "gaul": 26522,
      "leger": 26523,
      "mammalian": 26524,
      "##tov": 26525,
      "##aar": 26526,
      "##schaft": 26527,
      "doha": 26528,
      "frenchman": 26529,
      "nirvana": 26530,
      "##vino": 26531,
      "delgado": 26532,
      "headlining": 26533,
      "##eron": 26534,
      "##iography": 26535,
      "jug": 26536,
      "tko": 26537,
      "1649": 26538,
      "naga": 26539,
      "intersections": 26540,
      "##jia": 26541,
      "benfica": 26542,
      "nawab": 26543,
      "##suka": 26544,
      "ashford": 26545,
      "gulp": 26546,
      "##deck": 26547,
      "##vill": 26548,
      "##rug": 26549,
      "brentford": 26550,
      "frazier": 26551,
      "pleasures": 26552,
      "dunne": 26553,
      "potsdam": 26554,
      "shenzhen": 26555,
      "dentistry": 26556,
      "##tec": 26557,
      "flanagan": 26558,
      "##dorff": 26559,
      "##hear": 26560,
      "chorale": 26561,
      "dinah": 26562,
      "prem": 26563,
      "quezon": 26564,
      "##rogated": 26565,
      "relinquished": 26566,
      "sutra": 26567,
      "terri": 26568,
      "##pani": 26569,
      "flaps": 26570,
      "##rissa": 26571,
      "poly": 26572,
      "##rnet": 26573,
      "homme": 26574,
      "aback": 26575,
      "##eki": 26576,
      "linger": 26577,
      "womb": 26578,
      "##kson": 26579,
      "##lewood": 26580,
      "doorstep": 26581,
      "orthodoxy": 26582,
      "threaded": 26583,
      "westfield": 26584,
      "##rval": 26585,
      "dioceses": 26586,
      "fridays": 26587,
      "subsided": 26588,
      "##gata": 26589,
      "loyalists": 26590,
      "##biotic": 26591,
      "##ettes": 26592,
      "letterman": 26593,
      "lunatic": 26594,
      "prelate": 26595,
      "tenderly": 26596,
      "invariably": 26597,
      "souza": 26598,
      "thug": 26599,
      "winslow": 26600,
      "##otide": 26601,
      "furlongs": 26602,
      "gogh": 26603,
      "jeopardy": 26604,
      "##runa": 26605,
      "pegasus": 26606,
      "##umble": 26607,
      "humiliated": 26608,
      "standalone": 26609,
      "tagged": 26610,
      "##roller": 26611,
      "freshmen": 26612,
      "klan": 26613,
      "##bright": 26614,
      "attaining": 26615,
      "initiating": 26616,
      "transatlantic": 26617,
      "logged": 26618,
      "viz": 26619,
      "##uance": 26620,
      "1723": 26621,
      "combatants": 26622,
      "intervening": 26623,
      "stephane": 26624,
      "chieftain": 26625,
      "despised": 26626,
      "grazed": 26627,
      "317": 26628,
      "cdc": 26629,
      "galveston": 26630,
      "godzilla": 26631,
      "macro": 26632,
      "simulate": 26633,
      "##planes": 26634,
      "parades": 26635,
      "##esses": 26636,
      "960": 26637,
      "##ductive": 26638,
      "##unes": 26639,
      "equator": 26640,
      "overdose": 26641,
      "##cans": 26642,
      "##hosh": 26643,
      "##lifting": 26644,
      "joshi": 26645,
      "epstein": 26646,
      "sonora": 26647,
      "treacherous": 26648,
      "aquatics": 26649,
      "manchu": 26650,
      "responsive": 26651,
      "##sation": 26652,
      "supervisory": 26653,
      "##christ": 26654,
      "##llins": 26655,
      "##ibar": 26656,
      "##balance": 26657,
      "##uso": 26658,
      "kimball": 26659,
      "karlsruhe": 26660,
      "mab": 26661,
      "##emy": 26662,
      "ignores": 26663,
      "phonetic": 26664,
      "reuters": 26665,
      "spaghetti": 26666,
      "820": 26667,
      "almighty": 26668,
      "danzig": 26669,
      "rumbling": 26670,
      "tombstone": 26671,
      "designations": 26672,
      "lured": 26673,
      "outset": 26674,
      "##felt": 26675,
      "supermarkets": 26676,
      "##wt": 26677,
      "grupo": 26678,
      "kei": 26679,
      "kraft": 26680,
      "susanna": 26681,
      "##blood": 26682,
      "comprehension": 26683,
      "genealogy": 26684,
      "##aghan": 26685,
      "##verted": 26686,
      "redding": 26687,
      "##ythe": 26688,
      "1722": 26689,
      "bowing": 26690,
      "##pore": 26691,
      "##roi": 26692,
      "lest": 26693,
      "sharpened": 26694,
      "fulbright": 26695,
      "valkyrie": 26696,
      "sikhs": 26697,
      "##unds": 26698,
      "swans": 26699,
      "bouquet": 26700,
      "merritt": 26701,
      "##tage": 26702,
      "##venting": 26703,
      "commuted": 26704,
      "redhead": 26705,
      "clerks": 26706,
      "leasing": 26707,
      "cesare": 26708,
      "dea": 26709,
      "hazy": 26710,
      "##vances": 26711,
      "fledged": 26712,
      "greenfield": 26713,
      "servicemen": 26714,
      "##gical": 26715,
      "armando": 26716,
      "blackout": 26717,
      "dt": 26718,
      "sagged": 26719,
      "downloadable": 26720,
      "intra": 26721,
      "potion": 26722,
      "pods": 26723,
      "##4th": 26724,
      "##mism": 26725,
      "xp": 26726,
      "attendants": 26727,
      "gambia": 26728,
      "stale": 26729,
      "##ntine": 26730,
      "plump": 26731,
      "asteroids": 26732,
      "rediscovered": 26733,
      "buds": 26734,
      "flea": 26735,
      "hive": 26736,
      "##neas": 26737,
      "1737": 26738,
      "classifications": 26739,
      "debuts": 26740,
      "##eles": 26741,
      "olympus": 26742,
      "scala": 26743,
      "##eurs": 26744,
      "##gno": 26745,
      "##mute": 26746,
      "hummed": 26747,
      "sigismund": 26748,
      "visuals": 26749,
      "wiggled": 26750,
      "await": 26751,
      "pilasters": 26752,
      "clench": 26753,
      "sulfate": 26754,
      "##ances": 26755,
      "bellevue": 26756,
      "enigma": 26757,
      "trainee": 26758,
      "snort": 26759,
      "##sw": 26760,
      "clouded": 26761,
      "denim": 26762,
      "##rank": 26763,
      "##rder": 26764,
      "churning": 26765,
      "hartman": 26766,
      "lodges": 26767,
      "riches": 26768,
      "sima": 26769,
      "##missible": 26770,
      "accountable": 26771,
      "socrates": 26772,
      "regulates": 26773,
      "mueller": 26774,
      "##cr": 26775,
      "1702": 26776,
      "avoids": 26777,
      "solids": 26778,
      "himalayas": 26779,
      "nutrient": 26780,
      "pup": 26781,
      "##jevic": 26782,
      "squat": 26783,
      "fades": 26784,
      "nec": 26785,
      "##lates": 26786,
      "##pina": 26787,
      "##rona": 26788,
      "##ου": 26789,
      "privateer": 26790,
      "tequila": 26791,
      "##gative": 26792,
      "##mpton": 26793,
      "apt": 26794,
      "hornet": 26795,
      "immortals": 26796,
      "##dou": 26797,
      "asturias": 26798,
      "cleansing": 26799,
      "dario": 26800,
      "##rries": 26801,
      "##anta": 26802,
      "etymology": 26803,
      "servicing": 26804,
      "zhejiang": 26805,
      "##venor": 26806,
      "##nx": 26807,
      "horned": 26808,
      "erasmus": 26809,
      "rayon": 26810,
      "relocating": 26811,
      "£10": 26812,
      "##bags": 26813,
      "escalated": 26814,
      "promenade": 26815,
      "stubble": 26816,
      "2010s": 26817,
      "artisans": 26818,
      "axial": 26819,
      "liquids": 26820,
      "mora": 26821,
      "sho": 26822,
      "yoo": 26823,
      "##tsky": 26824,
      "bundles": 26825,
      "oldies": 26826,
      "##nally": 26827,
      "notification": 26828,
      "bastion": 26829,
      "##ths": 26830,
      "sparkle": 26831,
      "##lved": 26832,
      "1728": 26833,
      "leash": 26834,
      "pathogen": 26835,
      "highs": 26836,
      "##hmi": 26837,
      "immature": 26838,
      "880": 26839,
      "gonzaga": 26840,
      "ignatius": 26841,
      "mansions": 26842,
      "monterrey": 26843,
      "sweets": 26844,
      "bryson": 26845,
      "##loe": 26846,
      "polled": 26847,
      "regatta": 26848,
      "brightest": 26849,
      "pei": 26850,
      "rosy": 26851,
      "squid": 26852,
      "hatfield": 26853,
      "payroll": 26854,
      "addict": 26855,
      "meath": 26856,
      "cornerback": 26857,
      "heaviest": 26858,
      "lodging": 26859,
      "##mage": 26860,
      "capcom": 26861,
      "rippled": 26862,
      "##sily": 26863,
      "barnet": 26864,
      "mayhem": 26865,
      "ymca": 26866,
      "snuggled": 26867,
      "rousseau": 26868,
      "##cute": 26869,
      "blanchard": 26870,
      "284": 26871,
      "fragmented": 26872,
      "leighton": 26873,
      "chromosomes": 26874,
      "risking": 26875,
      "##md": 26876,
      "##strel": 26877,
      "##utter": 26878,
      "corinne": 26879,
      "coyotes": 26880,
      "cynical": 26881,
      "hiroshi": 26882,
      "yeomanry": 26883,
      "##ractive": 26884,
      "ebook": 26885,
      "grading": 26886,
      "mandela": 26887,
      "plume": 26888,
      "agustin": 26889,
      "magdalene": 26890,
      "##rkin": 26891,
      "bea": 26892,
      "femme": 26893,
      "trafford": 26894,
      "##coll": 26895,
      "##lun": 26896,
      "##tance": 26897,
      "52nd": 26898,
      "fourier": 26899,
      "upton": 26900,
      "##mental": 26901,
      "camilla": 26902,
      "gust": 26903,
      "iihf": 26904,
      "islamabad": 26905,
      "longevity": 26906,
      "##kala": 26907,
      "feldman": 26908,
      "netting": 26909,
      "##rization": 26910,
      "endeavour": 26911,
      "foraging": 26912,
      "mfa": 26913,
      "orr": 26914,
      "##open": 26915,
      "greyish": 26916,
      "contradiction": 26917,
      "graz": 26918,
      "##ruff": 26919,
      "handicapped": 26920,
      "marlene": 26921,
      "tweed": 26922,
      "oaxaca": 26923,
      "spp": 26924,
      "campos": 26925,
      "miocene": 26926,
      "pri": 26927,
      "configured": 26928,
      "cooks": 26929,
      "pluto": 26930,
      "cozy": 26931,
      "pornographic": 26932,
      "##entes": 26933,
      "70th": 26934,
      "fairness": 26935,
      "glided": 26936,
      "jonny": 26937,
      "lynne": 26938,
      "rounding": 26939,
      "sired": 26940,
      "##emon": 26941,
      "##nist": 26942,
      "remade": 26943,
      "uncover": 26944,
      "##mack": 26945,
      "complied": 26946,
      "lei": 26947,
      "newsweek": 26948,
      "##jured": 26949,
      "##parts": 26950,
      "##enting": 26951,
      "##pg": 26952,
      "293": 26953,
      "finer": 26954,
      "guerrillas": 26955,
      "athenian": 26956,
      "deng": 26957,
      "disused": 26958,
      "stepmother": 26959,
      "accuse": 26960,
      "gingerly": 26961,
      "seduction": 26962,
      "521": 26963,
      "confronting": 26964,
      "##walker": 26965,
      "##going": 26966,
      "gora": 26967,
      "nostalgia": 26968,
      "sabres": 26969,
      "virginity": 26970,
      "wrenched": 26971,
      "##minated": 26972,
      "syndication": 26973,
      "wielding": 26974,
      "eyre": 26975,
      "##56": 26976,
      "##gnon": 26977,
      "##igny": 26978,
      "behaved": 26979,
      "taxpayer": 26980,
      "sweeps": 26981,
      "##growth": 26982,
      "childless": 26983,
      "gallant": 26984,
      "##ywood": 26985,
      "amplified": 26986,
      "geraldine": 26987,
      "scrape": 26988,
      "##ffi": 26989,
      "babylonian": 26990,
      "fresco": 26991,
      "##rdan": 26992,
      "##kney": 26993,
      "##position": 26994,
      "1718": 26995,
      "restricting": 26996,
      "tack": 26997,
      "fukuoka": 26998,
      "osborn": 26999,
      "selector": 27000,
      "partnering": 27001,
      "##dlow": 27002,
      "318": 27003,
      "gnu": 27004,
      "kia": 27005,
      "tak": 27006,
      "whitley": 27007,
      "gables": 27008,
      "##54": 27009,
      "##mania": 27010,
      "mri": 27011,
      "softness": 27012,
      "immersion": 27013,
      "##bots": 27014,
      "##evsky": 27015,
      "1713": 27016,
      "chilling": 27017,
      "insignificant": 27018,
      "pcs": 27019,
      "##uis": 27020,
      "elites": 27021,
      "lina": 27022,
      "purported": 27023,
      "supplemental": 27024,
      "teaming": 27025,
      "##americana": 27026,
      "##dding": 27027,
      "##inton": 27028,
      "proficient": 27029,
      "rouen": 27030,
      "##nage": 27031,
      "##rret": 27032,
      "niccolo": 27033,
      "selects": 27034,
      "##bread": 27035,
      "fluffy": 27036,
      "1621": 27037,
      "gruff": 27038,
      "knotted": 27039,
      "mukherjee": 27040,
      "polgara": 27041,
      "thrash": 27042,
      "nicholls": 27043,
      "secluded": 27044,
      "smoothing": 27045,
      "thru": 27046,
      "corsica": 27047,
      "loaf": 27048,
      "whitaker": 27049,
      "inquiries": 27050,
      "##rrier": 27051,
      "##kam": 27052,
      "indochina": 27053,
      "289": 27054,
      "marlins": 27055,
      "myles": 27056,
      "peking": 27057,
      "##tea": 27058,
      "extracts": 27059,
      "pastry": 27060,
      "superhuman": 27061,
      "connacht": 27062,
      "vogel": 27063,
      "##ditional": 27064,
      "##het": 27065,
      "##udged": 27066,
      "##lash": 27067,
      "gloss": 27068,
      "quarries": 27069,
      "refit": 27070,
      "teaser": 27071,
      "##alic": 27072,
      "##gaon": 27073,
      "20s": 27074,
      "materialized": 27075,
      "sling": 27076,
      "camped": 27077,
      "pickering": 27078,
      "tung": 27079,
      "tracker": 27080,
      "pursuant": 27081,
      "##cide": 27082,
      "cranes": 27083,
      "soc": 27084,
      "##cini": 27085,
      "##typical": 27086,
      "##viere": 27087,
      "anhalt": 27088,
      "overboard": 27089,
      "workout": 27090,
      "chores": 27091,
      "fares": 27092,
      "orphaned": 27093,
      "stains": 27094,
      "##logie": 27095,
      "fenton": 27096,
      "surpassing": 27097,
      "joyah": 27098,
      "triggers": 27099,
      "##itte": 27100,
      "grandmaster": 27101,
      "##lass": 27102,
      "##lists": 27103,
      "clapping": 27104,
      "fraudulent": 27105,
      "ledger": 27106,
      "nagasaki": 27107,
      "##cor": 27108,
      "##nosis": 27109,
      "##tsa": 27110,
      "eucalyptus": 27111,
      "tun": 27112,
      "##icio": 27113,
      "##rney": 27114,
      "##tara": 27115,
      "dax": 27116,
      "heroism": 27117,
      "ina": 27118,
      "wrexham": 27119,
      "onboard": 27120,
      "unsigned": 27121,
      "##dates": 27122,
      "moshe": 27123,
      "galley": 27124,
      "winnie": 27125,
      "droplets": 27126,
      "exiles": 27127,
      "praises": 27128,
      "watered": 27129,
      "noodles": 27130,
      "##aia": 27131,
      "fein": 27132,
      "adi": 27133,
      "leland": 27134,
      "multicultural": 27135,
      "stink": 27136,
      "bingo": 27137,
      "comets": 27138,
      "erskine": 27139,
      "modernized": 27140,
      "canned": 27141,
      "constraint": 27142,
      "domestically": 27143,
      "chemotherapy": 27144,
      "featherweight": 27145,
      "stifled": 27146,
      "##mum": 27147,
      "darkly": 27148,
      "irresistible": 27149,
      "refreshing": 27150,
      "hasty": 27151,
      "isolate": 27152,
      "##oys": 27153,
      "kitchener": 27154,
      "planners": 27155,
      "##wehr": 27156,
      "cages": 27157,
      "yarn": 27158,
      "implant": 27159,
      "toulon": 27160,
      "elects": 27161,
      "childbirth": 27162,
      "yue": 27163,
      "##lind": 27164,
      "##lone": 27165,
      "cn": 27166,
      "rightful": 27167,
      "sportsman": 27168,
      "junctions": 27169,
      "remodeled": 27170,
      "specifies": 27171,
      "##rgh": 27172,
      "291": 27173,
      "##oons": 27174,
      "complimented": 27175,
      "##urgent": 27176,
      "lister": 27177,
      "ot": 27178,
      "##logic": 27179,
      "bequeathed": 27180,
      "cheekbones": 27181,
      "fontana": 27182,
      "gabby": 27183,
      "##dial": 27184,
      "amadeus": 27185,
      "corrugated": 27186,
      "maverick": 27187,
      "resented": 27188,
      "triangles": 27189,
      "##hered": 27190,
      "##usly": 27191,
      "nazareth": 27192,
      "tyrol": 27193,
      "1675": 27194,
      "assent": 27195,
      "poorer": 27196,
      "sectional": 27197,
      "aegean": 27198,
      "##cous": 27199,
      "296": 27200,
      "nylon": 27201,
      "ghanaian": 27202,
      "##egorical": 27203,
      "##weig": 27204,
      "cushions": 27205,
      "forbid": 27206,
      "fusiliers": 27207,
      "obstruction": 27208,
      "somerville": 27209,
      "##scia": 27210,
      "dime": 27211,
      "earrings": 27212,
      "elliptical": 27213,
      "leyte": 27214,
      "oder": 27215,
      "polymers": 27216,
      "timmy": 27217,
      "atm": 27218,
      "midtown": 27219,
      "piloted": 27220,
      "settles": 27221,
      "continual": 27222,
      "externally": 27223,
      "mayfield": 27224,
      "##uh": 27225,
      "enrichment": 27226,
      "henson": 27227,
      "keane": 27228,
      "persians": 27229,
      "1733": 27230,
      "benji": 27231,
      "braden": 27232,
      "pep": 27233,
      "324": 27234,
      "##efe": 27235,
      "contenders": 27236,
      "pepsi": 27237,
      "valet": 27238,
      "##isches": 27239,
      "298": 27240,
      "##asse": 27241,
      "##earing": 27242,
      "goofy": 27243,
      "stroll": 27244,
      "##amen": 27245,
      "authoritarian": 27246,
      "occurrences": 27247,
      "adversary": 27248,
      "ahmedabad": 27249,
      "tangent": 27250,
      "toppled": 27251,
      "dorchester": 27252,
      "1672": 27253,
      "modernism": 27254,
      "marxism": 27255,
      "islamist": 27256,
      "charlemagne": 27257,
      "exponential": 27258,
      "racks": 27259,
      "unicode": 27260,
      "brunette": 27261,
      "mbc": 27262,
      "pic": 27263,
      "skirmish": 27264,
      "##bund": 27265,
      "##lad": 27266,
      "##powered": 27267,
      "##yst": 27268,
      "hoisted": 27269,
      "messina": 27270,
      "shatter": 27271,
      "##ctum": 27272,
      "jedi": 27273,
      "vantage": 27274,
      "##music": 27275,
      "##neil": 27276,
      "clemens": 27277,
      "mahmoud": 27278,
      "corrupted": 27279,
      "authentication": 27280,
      "lowry": 27281,
      "nils": 27282,
      "##washed": 27283,
      "omnibus": 27284,
      "wounding": 27285,
      "jillian": 27286,
      "##itors": 27287,
      "##opped": 27288,
      "serialized": 27289,
      "narcotics": 27290,
      "handheld": 27291,
      "##arm": 27292,
      "##plicity": 27293,
      "intersecting": 27294,
      "stimulating": 27295,
      "##onis": 27296,
      "crate": 27297,
      "fellowships": 27298,
      "hemingway": 27299,
      "casinos": 27300,
      "climatic": 27301,
      "fordham": 27302,
      "copeland": 27303,
      "drip": 27304,
      "beatty": 27305,
      "leaflets": 27306,
      "robber": 27307,
      "brothel": 27308,
      "madeira": 27309,
      "##hedral": 27310,
      "sphinx": 27311,
      "ultrasound": 27312,
      "##vana": 27313,
      "valor": 27314,
      "forbade": 27315,
      "leonid": 27316,
      "villas": 27317,
      "##aldo": 27318,
      "duane": 27319,
      "marquez": 27320,
      "##cytes": 27321,
      "disadvantaged": 27322,
      "forearms": 27323,
      "kawasaki": 27324,
      "reacts": 27325,
      "consular": 27326,
      "lax": 27327,
      "uncles": 27328,
      "uphold": 27329,
      "##hopper": 27330,
      "concepcion": 27331,
      "dorsey": 27332,
      "lass": 27333,
      "##izan": 27334,
      "arching": 27335,
      "passageway": 27336,
      "1708": 27337,
      "researches": 27338,
      "tia": 27339,
      "internationals": 27340,
      "##graphs": 27341,
      "##opers": 27342,
      "distinguishes": 27343,
      "javanese": 27344,
      "divert": 27345,
      "##uven": 27346,
      "plotted": 27347,
      "##listic": 27348,
      "##rwin": 27349,
      "##erik": 27350,
      "##tify": 27351,
      "affirmative": 27352,
      "signifies": 27353,
      "validation": 27354,
      "##bson": 27355,
      "kari": 27356,
      "felicity": 27357,
      "georgina": 27358,
      "zulu": 27359,
      "##eros": 27360,
      "##rained": 27361,
      "##rath": 27362,
      "overcoming": 27363,
      "##dot": 27364,
      "argyll": 27365,
      "##rbin": 27366,
      "1734": 27367,
      "chiba": 27368,
      "ratification": 27369,
      "windy": 27370,
      "earls": 27371,
      "parapet": 27372,
      "##marks": 27373,
      "hunan": 27374,
      "pristine": 27375,
      "astrid": 27376,
      "punta": 27377,
      "##gart": 27378,
      "brodie": 27379,
      "##kota": 27380,
      "##oder": 27381,
      "malaga": 27382,
      "minerva": 27383,
      "rouse": 27384,
      "##phonic": 27385,
      "bellowed": 27386,
      "pagoda": 27387,
      "portals": 27388,
      "reclamation": 27389,
      "##gur": 27390,
      "##odies": 27391,
      "##⁄₄": 27392,
      "parentheses": 27393,
      "quoting": 27394,
      "allergic": 27395,
      "palette": 27396,
      "showcases": 27397,
      "benefactor": 27398,
      "heartland": 27399,
      "nonlinear": 27400,
      "##tness": 27401,
      "bladed": 27402,
      "cheerfully": 27403,
      "scans": 27404,
      "##ety": 27405,
      "##hone": 27406,
      "1666": 27407,
      "girlfriends": 27408,
      "pedersen": 27409,
      "hiram": 27410,
      "sous": 27411,
      "##liche": 27412,
      "##nator": 27413,
      "1683": 27414,
      "##nery": 27415,
      "##orio": 27416,
      "##umen": 27417,
      "bobo": 27418,
      "primaries": 27419,
      "smiley": 27420,
      "##cb": 27421,
      "unearthed": 27422,
      "uniformly": 27423,
      "fis": 27424,
      "metadata": 27425,
      "1635": 27426,
      "ind": 27427,
      "##oted": 27428,
      "recoil": 27429,
      "##titles": 27430,
      "##tura": 27431,
      "##ια": 27432,
      "406": 27433,
      "hilbert": 27434,
      "jamestown": 27435,
      "mcmillan": 27436,
      "tulane": 27437,
      "seychelles": 27438,
      "##frid": 27439,
      "antics": 27440,
      "coli": 27441,
      "fated": 27442,
      "stucco": 27443,
      "##grants": 27444,
      "1654": 27445,
      "bulky": 27446,
      "accolades": 27447,
      "arrays": 27448,
      "caledonian": 27449,
      "carnage": 27450,
      "optimism": 27451,
      "puebla": 27452,
      "##tative": 27453,
      "##cave": 27454,
      "enforcing": 27455,
      "rotherham": 27456,
      "seo": 27457,
      "dunlop": 27458,
      "aeronautics": 27459,
      "chimed": 27460,
      "incline": 27461,
      "zoning": 27462,
      "archduke": 27463,
      "hellenistic": 27464,
      "##oses": 27465,
      "##sions": 27466,
      "candi": 27467,
      "thong": 27468,
      "##ople": 27469,
      "magnate": 27470,
      "rustic": 27471,
      "##rsk": 27472,
      "projective": 27473,
      "slant": 27474,
      "##offs": 27475,
      "danes": 27476,
      "hollis": 27477,
      "vocalists": 27478,
      "##ammed": 27479,
      "congenital": 27480,
      "contend": 27481,
      "gesellschaft": 27482,
      "##ocating": 27483,
      "##pressive": 27484,
      "douglass": 27485,
      "quieter": 27486,
      "##cm": 27487,
      "##kshi": 27488,
      "howled": 27489,
      "salim": 27490,
      "spontaneously": 27491,
      "townsville": 27492,
      "buena": 27493,
      "southport": 27494,
      "##bold": 27495,
      "kato": 27496,
      "1638": 27497,
      "faerie": 27498,
      "stiffly": 27499,
      "##vus": 27500,
      "##rled": 27501,
      "297": 27502,
      "flawless": 27503,
      "realising": 27504,
      "taboo": 27505,
      "##7th": 27506,
      "bytes": 27507,
      "straightening": 27508,
      "356": 27509,
      "jena": 27510,
      "##hid": 27511,
      "##rmin": 27512,
      "cartwright": 27513,
      "berber": 27514,
      "bertram": 27515,
      "soloists": 27516,
      "411": 27517,
      "noses": 27518,
      "417": 27519,
      "coping": 27520,
      "fission": 27521,
      "hardin": 27522,
      "inca": 27523,
      "##cen": 27524,
      "1717": 27525,
      "mobilized": 27526,
      "vhf": 27527,
      "##raf": 27528,
      "biscuits": 27529,
      "curate": 27530,
      "##85": 27531,
      "##anial": 27532,
      "331": 27533,
      "gaunt": 27534,
      "neighbourhoods": 27535,
      "1540": 27536,
      "##abas": 27537,
      "blanca": 27538,
      "bypassed": 27539,
      "sockets": 27540,
      "behold": 27541,
      "coincidentally": 27542,
      "##bane": 27543,
      "nara": 27544,
      "shave": 27545,
      "splinter": 27546,
      "terrific": 27547,
      "##arion": 27548,
      "##erian": 27549,
      "commonplace": 27550,
      "juris": 27551,
      "redwood": 27552,
      "waistband": 27553,
      "boxed": 27554,
      "caitlin": 27555,
      "fingerprints": 27556,
      "jennie": 27557,
      "naturalized": 27558,
      "##ired": 27559,
      "balfour": 27560,
      "craters": 27561,
      "jody": 27562,
      "bungalow": 27563,
      "hugely": 27564,
      "quilt": 27565,
      "glitter": 27566,
      "pigeons": 27567,
      "undertaker": 27568,
      "bulging": 27569,
      "constrained": 27570,
      "goo": 27571,
      "##sil": 27572,
      "##akh": 27573,
      "assimilation": 27574,
      "reworked": 27575,
      "##person": 27576,
      "persuasion": 27577,
      "##pants": 27578,
      "felicia": 27579,
      "##cliff": 27580,
      "##ulent": 27581,
      "1732": 27582,
      "explodes": 27583,
      "##dun": 27584,
      "##inium": 27585,
      "##zic": 27586,
      "lyman": 27587,
      "vulture": 27588,
      "hog": 27589,
      "overlook": 27590,
      "begs": 27591,
      "northwards": 27592,
      "ow": 27593,
      "spoil": 27594,
      "##urer": 27595,
      "fatima": 27596,
      "favorably": 27597,
      "accumulate": 27598,
      "sargent": 27599,
      "sorority": 27600,
      "corresponded": 27601,
      "dispersal": 27602,
      "kochi": 27603,
      "toned": 27604,
      "##imi": 27605,
      "##lita": 27606,
      "internacional": 27607,
      "newfound": 27608,
      "##agger": 27609,
      "##lynn": 27610,
      "##rigue": 27611,
      "booths": 27612,
      "peanuts": 27613,
      "##eborg": 27614,
      "medicare": 27615,
      "muriel": 27616,
      "nur": 27617,
      "##uram": 27618,
      "crates": 27619,
      "millennia": 27620,
      "pajamas": 27621,
      "worsened": 27622,
      "##breakers": 27623,
      "jimi": 27624,
      "vanuatu": 27625,
      "yawned": 27626,
      "##udeau": 27627,
      "carousel": 27628,
      "##hony": 27629,
      "hurdle": 27630,
      "##ccus": 27631,
      "##mounted": 27632,
      "##pod": 27633,
      "rv": 27634,
      "##eche": 27635,
      "airship": 27636,
      "ambiguity": 27637,
      "compulsion": 27638,
      "recapture": 27639,
      "##claiming": 27640,
      "arthritis": 27641,
      "##osomal": 27642,
      "1667": 27643,
      "asserting": 27644,
      "ngc": 27645,
      "sniffing": 27646,
      "dade": 27647,
      "discontent": 27648,
      "glendale": 27649,
      "ported": 27650,
      "##amina": 27651,
      "defamation": 27652,
      "rammed": 27653,
      "##scent": 27654,
      "fling": 27655,
      "livingstone": 27656,
      "##fleet": 27657,
      "875": 27658,
      "##ppy": 27659,
      "apocalyptic": 27660,
      "comrade": 27661,
      "lcd": 27662,
      "##lowe": 27663,
      "cessna": 27664,
      "eine": 27665,
      "persecuted": 27666,
      "subsistence": 27667,
      "demi": 27668,
      "hoop": 27669,
      "reliefs": 27670,
      "710": 27671,
      "coptic": 27672,
      "progressing": 27673,
      "stemmed": 27674,
      "perpetrators": 27675,
      "1665": 27676,
      "priestess": 27677,
      "##nio": 27678,
      "dobson": 27679,
      "ebony": 27680,
      "rooster": 27681,
      "itf": 27682,
      "tortricidae": 27683,
      "##bbon": 27684,
      "##jian": 27685,
      "cleanup": 27686,
      "##jean": 27687,
      "##øy": 27688,
      "1721": 27689,
      "eighties": 27690,
      "taxonomic": 27691,
      "holiness": 27692,
      "##hearted": 27693,
      "##spar": 27694,
      "antilles": 27695,
      "showcasing": 27696,
      "stabilized": 27697,
      "##nb": 27698,
      "gia": 27699,
      "mascara": 27700,
      "michelangelo": 27701,
      "dawned": 27702,
      "##uria": 27703,
      "##vinsky": 27704,
      "extinguished": 27705,
      "fitz": 27706,
      "grotesque": 27707,
      "£100": 27708,
      "##fera": 27709,
      "##loid": 27710,
      "##mous": 27711,
      "barges": 27712,
      "neue": 27713,
      "throbbed": 27714,
      "cipher": 27715,
      "johnnie": 27716,
      "##a1": 27717,
      "##mpt": 27718,
      "outburst": 27719,
      "##swick": 27720,
      "spearheaded": 27721,
      "administrations": 27722,
      "c1": 27723,
      "heartbreak": 27724,
      "pixels": 27725,
      "pleasantly": 27726,
      "##enay": 27727,
      "lombardy": 27728,
      "plush": 27729,
      "##nsed": 27730,
      "bobbie": 27731,
      "##hly": 27732,
      "reapers": 27733,
      "tremor": 27734,
      "xiang": 27735,
      "minogue": 27736,
      "substantive": 27737,
      "hitch": 27738,
      "barak": 27739,
      "##wyl": 27740,
      "kwan": 27741,
      "##encia": 27742,
      "910": 27743,
      "obscene": 27744,
      "elegance": 27745,
      "indus": 27746,
      "surfer": 27747,
      "bribery": 27748,
      "conserve": 27749,
      "##hyllum": 27750,
      "##masters": 27751,
      "horatio": 27752,
      "##fat": 27753,
      "apes": 27754,
      "rebound": 27755,
      "psychotic": 27756,
      "##pour": 27757,
      "iteration": 27758,
      "##mium": 27759,
      "##vani": 27760,
      "botanic": 27761,
      "horribly": 27762,
      "antiques": 27763,
      "dispose": 27764,
      "paxton": 27765,
      "##hli": 27766,
      "##wg": 27767,
      "timeless": 27768,
      "1704": 27769,
      "disregard": 27770,
      "engraver": 27771,
      "hounds": 27772,
      "##bau": 27773,
      "##version": 27774,
      "looted": 27775,
      "uno": 27776,
      "facilitates": 27777,
      "groans": 27778,
      "masjid": 27779,
      "rutland": 27780,
      "antibody": 27781,
      "disqualification": 27782,
      "decatur": 27783,
      "footballers": 27784,
      "quake": 27785,
      "slacks": 27786,
      "48th": 27787,
      "rein": 27788,
      "scribe": 27789,
      "stabilize": 27790,
      "commits": 27791,
      "exemplary": 27792,
      "tho": 27793,
      "##hort": 27794,
      "##chison": 27795,
      "pantry": 27796,
      "traversed": 27797,
      "##hiti": 27798,
      "disrepair": 27799,
      "identifiable": 27800,
      "vibrated": 27801,
      "baccalaureate": 27802,
      "##nnis": 27803,
      "csa": 27804,
      "interviewing": 27805,
      "##iensis": 27806,
      "##raße": 27807,
      "greaves": 27808,
      "wealthiest": 27809,
      "343": 27810,
      "classed": 27811,
      "jogged": 27812,
      "£5": 27813,
      "##58": 27814,
      "##atal": 27815,
      "illuminating": 27816,
      "knicks": 27817,
      "respecting": 27818,
      "##uno": 27819,
      "scrubbed": 27820,
      "##iji": 27821,
      "##dles": 27822,
      "kruger": 27823,
      "moods": 27824,
      "growls": 27825,
      "raider": 27826,
      "silvia": 27827,
      "chefs": 27828,
      "kam": 27829,
      "vr": 27830,
      "cree": 27831,
      "percival": 27832,
      "##terol": 27833,
      "gunter": 27834,
      "counterattack": 27835,
      "defiant": 27836,
      "henan": 27837,
      "ze": 27838,
      "##rasia": 27839,
      "##riety": 27840,
      "equivalence": 27841,
      "submissions": 27842,
      "##fra": 27843,
      "##thor": 27844,
      "bautista": 27845,
      "mechanically": 27846,
      "##heater": 27847,
      "cornice": 27848,
      "herbal": 27849,
      "templar": 27850,
      "##mering": 27851,
      "outputs": 27852,
      "ruining": 27853,
      "ligand": 27854,
      "renumbered": 27855,
      "extravagant": 27856,
      "mika": 27857,
      "blockbuster": 27858,
      "eta": 27859,
      "insurrection": 27860,
      "##ilia": 27861,
      "darkening": 27862,
      "ferocious": 27863,
      "pianos": 27864,
      "strife": 27865,
      "kinship": 27866,
      "##aer": 27867,
      "melee": 27868,
      "##anor": 27869,
      "##iste": 27870,
      "##may": 27871,
      "##oue": 27872,
      "decidedly": 27873,
      "weep": 27874,
      "##jad": 27875,
      "##missive": 27876,
      "##ppel": 27877,
      "354": 27878,
      "puget": 27879,
      "unease": 27880,
      "##gnant": 27881,
      "1629": 27882,
      "hammering": 27883,
      "kassel": 27884,
      "ob": 27885,
      "wessex": 27886,
      "##lga": 27887,
      "bromwich": 27888,
      "egan": 27889,
      "paranoia": 27890,
      "utilization": 27891,
      "##atable": 27892,
      "##idad": 27893,
      "contradictory": 27894,
      "provoke": 27895,
      "##ols": 27896,
      "##ouring": 27897,
      "##tangled": 27898,
      "knesset": 27899,
      "##very": 27900,
      "##lette": 27901,
      "plumbing": 27902,
      "##sden": 27903,
      "##¹": 27904,
      "greensboro": 27905,
      "occult": 27906,
      "sniff": 27907,
      "338": 27908,
      "zev": 27909,
      "beaming": 27910,
      "gamer": 27911,
      "haggard": 27912,
      "mahal": 27913,
      "##olt": 27914,
      "##pins": 27915,
      "mendes": 27916,
      "utmost": 27917,
      "briefing": 27918,
      "gunnery": 27919,
      "##gut": 27920,
      "##pher": 27921,
      "##zh": 27922,
      "##rok": 27923,
      "1679": 27924,
      "khalifa": 27925,
      "sonya": 27926,
      "##boot": 27927,
      "principals": 27928,
      "urbana": 27929,
      "wiring": 27930,
      "##liffe": 27931,
      "##minating": 27932,
      "##rrado": 27933,
      "dahl": 27934,
      "nyu": 27935,
      "skepticism": 27936,
      "np": 27937,
      "townspeople": 27938,
      "ithaca": 27939,
      "lobster": 27940,
      "somethin": 27941,
      "##fur": 27942,
      "##arina": 27943,
      "##−1": 27944,
      "freighter": 27945,
      "zimmerman": 27946,
      "biceps": 27947,
      "contractual": 27948,
      "##herton": 27949,
      "amend": 27950,
      "hurrying": 27951,
      "subconscious": 27952,
      "##anal": 27953,
      "336": 27954,
      "meng": 27955,
      "clermont": 27956,
      "spawning": 27957,
      "##eia": 27958,
      "##lub": 27959,
      "dignitaries": 27960,
      "impetus": 27961,
      "snacks": 27962,
      "spotting": 27963,
      "twigs": 27964,
      "##bilis": 27965,
      "##cz": 27966,
      "##ouk": 27967,
      "libertadores": 27968,
      "nic": 27969,
      "skylar": 27970,
      "##aina": 27971,
      "##firm": 27972,
      "gustave": 27973,
      "asean": 27974,
      "##anum": 27975,
      "dieter": 27976,
      "legislatures": 27977,
      "flirt": 27978,
      "bromley": 27979,
      "trolls": 27980,
      "umar": 27981,
      "##bbies": 27982,
      "##tyle": 27983,
      "blah": 27984,
      "parc": 27985,
      "bridgeport": 27986,
      "crank": 27987,
      "negligence": 27988,
      "##nction": 27989,
      "46th": 27990,
      "constantin": 27991,
      "molded": 27992,
      "bandages": 27993,
      "seriousness": 27994,
      "00pm": 27995,
      "siegel": 27996,
      "carpets": 27997,
      "compartments": 27998,
      "upbeat": 27999,
      "statehood": 28000,
      "##dner": 28001,
      "##edging": 28002,
      "marko": 28003,
      "730": 28004,
      "platt": 28005,
      "##hane": 28006,
      "paving": 28007,
      "##iy": 28008,
      "1738": 28009,
      "abbess": 28010,
      "impatience": 28011,
      "limousine": 28012,
      "nbl": 28013,
      "##talk": 28014,
      "441": 28015,
      "lucille": 28016,
      "mojo": 28017,
      "nightfall": 28018,
      "robbers": 28019,
      "##nais": 28020,
      "karel": 28021,
      "brisk": 28022,
      "calves": 28023,
      "replicate": 28024,
      "ascribed": 28025,
      "telescopes": 28026,
      "##olf": 28027,
      "intimidated": 28028,
      "##reen": 28029,
      "ballast": 28030,
      "specialization": 28031,
      "##sit": 28032,
      "aerodynamic": 28033,
      "caliphate": 28034,
      "rainer": 28035,
      "visionary": 28036,
      "##arded": 28037,
      "epsilon": 28038,
      "##aday": 28039,
      "##onte": 28040,
      "aggregation": 28041,
      "auditory": 28042,
      "boosted": 28043,
      "reunification": 28044,
      "kathmandu": 28045,
      "loco": 28046,
      "robyn": 28047,
      "402": 28048,
      "acknowledges": 28049,
      "appointing": 28050,
      "humanoid": 28051,
      "newell": 28052,
      "redeveloped": 28053,
      "restraints": 28054,
      "##tained": 28055,
      "barbarians": 28056,
      "chopper": 28057,
      "1609": 28058,
      "italiana": 28059,
      "##lez": 28060,
      "##lho": 28061,
      "investigates": 28062,
      "wrestlemania": 28063,
      "##anies": 28064,
      "##bib": 28065,
      "690": 28066,
      "##falls": 28067,
      "creaked": 28068,
      "dragoons": 28069,
      "gravely": 28070,
      "minions": 28071,
      "stupidity": 28072,
      "volley": 28073,
      "##harat": 28074,
      "##week": 28075,
      "musik": 28076,
      "##eries": 28077,
      "##uously": 28078,
      "fungal": 28079,
      "massimo": 28080,
      "semantics": 28081,
      "malvern": 28082,
      "##ahl": 28083,
      "##pee": 28084,
      "discourage": 28085,
      "embryo": 28086,
      "imperialism": 28087,
      "1910s": 28088,
      "profoundly": 28089,
      "##ddled": 28090,
      "jiangsu": 28091,
      "sparkled": 28092,
      "stat": 28093,
      "##holz": 28094,
      "sweatshirt": 28095,
      "tobin": 28096,
      "##iction": 28097,
      "sneered": 28098,
      "##cheon": 28099,
      "##oit": 28100,
      "brit": 28101,
      "causal": 28102,
      "smyth": 28103,
      "##neuve": 28104,
      "diffuse": 28105,
      "perrin": 28106,
      "silvio": 28107,
      "##ipes": 28108,
      "##recht": 28109,
      "detonated": 28110,
      "iqbal": 28111,
      "selma": 28112,
      "##nism": 28113,
      "##zumi": 28114,
      "roasted": 28115,
      "##riders": 28116,
      "tay": 28117,
      "##ados": 28118,
      "##mament": 28119,
      "##mut": 28120,
      "##rud": 28121,
      "840": 28122,
      "completes": 28123,
      "nipples": 28124,
      "cfa": 28125,
      "flavour": 28126,
      "hirsch": 28127,
      "##laus": 28128,
      "calderon": 28129,
      "sneakers": 28130,
      "moravian": 28131,
      "##ksha": 28132,
      "1622": 28133,
      "rq": 28134,
      "294": 28135,
      "##imeters": 28136,
      "bodo": 28137,
      "##isance": 28138,
      "##pre": 28139,
      "##ronia": 28140,
      "anatomical": 28141,
      "excerpt": 28142,
      "##lke": 28143,
      "dh": 28144,
      "kunst": 28145,
      "##tablished": 28146,
      "##scoe": 28147,
      "biomass": 28148,
      "panted": 28149,
      "unharmed": 28150,
      "gael": 28151,
      "housemates": 28152,
      "montpellier": 28153,
      "##59": 28154,
      "coa": 28155,
      "rodents": 28156,
      "tonic": 28157,
      "hickory": 28158,
      "singleton": 28159,
      "##taro": 28160,
      "451": 28161,
      "1719": 28162,
      "aldo": 28163,
      "breaststroke": 28164,
      "dempsey": 28165,
      "och": 28166,
      "rocco": 28167,
      "##cuit": 28168,
      "merton": 28169,
      "dissemination": 28170,
      "midsummer": 28171,
      "serials": 28172,
      "##idi": 28173,
      "haji": 28174,
      "polynomials": 28175,
      "##rdon": 28176,
      "gs": 28177,
      "enoch": 28178,
      "prematurely": 28179,
      "shutter": 28180,
      "taunton": 28181,
      "£3": 28182,
      "##grating": 28183,
      "##inates": 28184,
      "archangel": 28185,
      "harassed": 28186,
      "##asco": 28187,
      "326": 28188,
      "archway": 28189,
      "dazzling": 28190,
      "##ecin": 28191,
      "1736": 28192,
      "sumo": 28193,
      "wat": 28194,
      "##kovich": 28195,
      "1086": 28196,
      "honneur": 28197,
      "##ently": 28198,
      "##nostic": 28199,
      "##ttal": 28200,
      "##idon": 28201,
      "1605": 28202,
      "403": 28203,
      "1716": 28204,
      "blogger": 28205,
      "rents": 28206,
      "##gnan": 28207,
      "hires": 28208,
      "##ikh": 28209,
      "##dant": 28210,
      "howie": 28211,
      "##rons": 28212,
      "handler": 28213,
      "retracted": 28214,
      "shocks": 28215,
      "1632": 28216,
      "arun": 28217,
      "duluth": 28218,
      "kepler": 28219,
      "trumpeter": 28220,
      "##lary": 28221,
      "peeking": 28222,
      "seasoned": 28223,
      "trooper": 28224,
      "##mara": 28225,
      "laszlo": 28226,
      "##iciencies": 28227,
      "##rti": 28228,
      "heterosexual": 28229,
      "##inatory": 28230,
      "##ssion": 28231,
      "indira": 28232,
      "jogging": 28233,
      "##inga": 28234,
      "##lism": 28235,
      "beit": 28236,
      "dissatisfaction": 28237,
      "malice": 28238,
      "##ately": 28239,
      "nedra": 28240,
      "peeling": 28241,
      "##rgeon": 28242,
      "47th": 28243,
      "stadiums": 28244,
      "475": 28245,
      "vertigo": 28246,
      "##ains": 28247,
      "iced": 28248,
      "restroom": 28249,
      "##plify": 28250,
      "##tub": 28251,
      "illustrating": 28252,
      "pear": 28253,
      "##chner": 28254,
      "##sibility": 28255,
      "inorganic": 28256,
      "rappers": 28257,
      "receipts": 28258,
      "watery": 28259,
      "##kura": 28260,
      "lucinda": 28261,
      "##oulos": 28262,
      "reintroduced": 28263,
      "##8th": 28264,
      "##tched": 28265,
      "gracefully": 28266,
      "saxons": 28267,
      "nutritional": 28268,
      "wastewater": 28269,
      "rained": 28270,
      "favourites": 28271,
      "bedrock": 28272,
      "fisted": 28273,
      "hallways": 28274,
      "likeness": 28275,
      "upscale": 28276,
      "##lateral": 28277,
      "1580": 28278,
      "blinds": 28279,
      "prequel": 28280,
      "##pps": 28281,
      "##tama": 28282,
      "deter": 28283,
      "humiliating": 28284,
      "restraining": 28285,
      "tn": 28286,
      "vents": 28287,
      "1659": 28288,
      "laundering": 28289,
      "recess": 28290,
      "rosary": 28291,
      "tractors": 28292,
      "coulter": 28293,
      "federer": 28294,
      "##ifiers": 28295,
      "##plin": 28296,
      "persistence": 28297,
      "##quitable": 28298,
      "geschichte": 28299,
      "pendulum": 28300,
      "quakers": 28301,
      "##beam": 28302,
      "bassett": 28303,
      "pictorial": 28304,
      "buffet": 28305,
      "koln": 28306,
      "##sitor": 28307,
      "drills": 28308,
      "reciprocal": 28309,
      "shooters": 28310,
      "##57": 28311,
      "##cton": 28312,
      "##tees": 28313,
      "converge": 28314,
      "pip": 28315,
      "dmitri": 28316,
      "donnelly": 28317,
      "yamamoto": 28318,
      "aqua": 28319,
      "azores": 28320,
      "demographics": 28321,
      "hypnotic": 28322,
      "spitfire": 28323,
      "suspend": 28324,
      "wryly": 28325,
      "roderick": 28326,
      "##rran": 28327,
      "sebastien": 28328,
      "##asurable": 28329,
      "mavericks": 28330,
      "##fles": 28331,
      "##200": 28332,
      "himalayan": 28333,
      "prodigy": 28334,
      "##iance": 28335,
      "transvaal": 28336,
      "demonstrators": 28337,
      "handcuffs": 28338,
      "dodged": 28339,
      "mcnamara": 28340,
      "sublime": 28341,
      "1726": 28342,
      "crazed": 28343,
      "##efined": 28344,
      "##till": 28345,
      "ivo": 28346,
      "pondered": 28347,
      "reconciled": 28348,
      "shrill": 28349,
      "sava": 28350,
      "##duk": 28351,
      "bal": 28352,
      "cad": 28353,
      "heresy": 28354,
      "jaipur": 28355,
      "goran": 28356,
      "##nished": 28357,
      "341": 28358,
      "lux": 28359,
      "shelly": 28360,
      "whitehall": 28361,
      "##hre": 28362,
      "israelis": 28363,
      "peacekeeping": 28364,
      "##wled": 28365,
      "1703": 28366,
      "demetrius": 28367,
      "ousted": 28368,
      "##arians": 28369,
      "##zos": 28370,
      "beale": 28371,
      "anwar": 28372,
      "backstroke": 28373,
      "raged": 28374,
      "shrinking": 28375,
      "cremated": 28376,
      "##yck": 28377,
      "benign": 28378,
      "towing": 28379,
      "wadi": 28380,
      "darmstadt": 28381,
      "landfill": 28382,
      "parana": 28383,
      "soothe": 28384,
      "colleen": 28385,
      "sidewalks": 28386,
      "mayfair": 28387,
      "tumble": 28388,
      "hepatitis": 28389,
      "ferrer": 28390,
      "superstructure": 28391,
      "##gingly": 28392,
      "##urse": 28393,
      "##wee": 28394,
      "anthropological": 28395,
      "translators": 28396,
      "##mies": 28397,
      "closeness": 28398,
      "hooves": 28399,
      "##pw": 28400,
      "mondays": 28401,
      "##roll": 28402,
      "##vita": 28403,
      "landscaping": 28404,
      "##urized": 28405,
      "purification": 28406,
      "sock": 28407,
      "thorns": 28408,
      "thwarted": 28409,
      "jalan": 28410,
      "tiberius": 28411,
      "##taka": 28412,
      "saline": 28413,
      "##rito": 28414,
      "confidently": 28415,
      "khyber": 28416,
      "sculptors": 28417,
      "##ij": 28418,
      "brahms": 28419,
      "hammersmith": 28420,
      "inspectors": 28421,
      "battista": 28422,
      "fivb": 28423,
      "fragmentation": 28424,
      "hackney": 28425,
      "##uls": 28426,
      "arresting": 28427,
      "exercising": 28428,
      "antoinette": 28429,
      "bedfordshire": 28430,
      "##zily": 28431,
      "dyed": 28432,
      "##hema": 28433,
      "1656": 28434,
      "racetrack": 28435,
      "variability": 28436,
      "##tique": 28437,
      "1655": 28438,
      "austrians": 28439,
      "deteriorating": 28440,
      "madman": 28441,
      "theorists": 28442,
      "aix": 28443,
      "lehman": 28444,
      "weathered": 28445,
      "1731": 28446,
      "decreed": 28447,
      "eruptions": 28448,
      "1729": 28449,
      "flaw": 28450,
      "quinlan": 28451,
      "sorbonne": 28452,
      "flutes": 28453,
      "nunez": 28454,
      "1711": 28455,
      "adored": 28456,
      "downwards": 28457,
      "fable": 28458,
      "rasped": 28459,
      "1712": 28460,
      "moritz": 28461,
      "mouthful": 28462,
      "renegade": 28463,
      "shivers": 28464,
      "stunts": 28465,
      "dysfunction": 28466,
      "restrain": 28467,
      "translit": 28468,
      "327": 28469,
      "pancakes": 28470,
      "##avio": 28471,
      "##cision": 28472,
      "##tray": 28473,
      "351": 28474,
      "vial": 28475,
      "##lden": 28476,
      "bain": 28477,
      "##maid": 28478,
      "##oxide": 28479,
      "chihuahua": 28480,
      "malacca": 28481,
      "vimes": 28482,
      "##rba": 28483,
      "##rnier": 28484,
      "1664": 28485,
      "donnie": 28486,
      "plaques": 28487,
      "##ually": 28488,
      "337": 28489,
      "bangs": 28490,
      "floppy": 28491,
      "huntsville": 28492,
      "loretta": 28493,
      "nikolay": 28494,
      "##otte": 28495,
      "eater": 28496,
      "handgun": 28497,
      "ubiquitous": 28498,
      "##hett": 28499,
      "eras": 28500,
      "zodiac": 28501,
      "1634": 28502,
      "##omorphic": 28503,
      "1820s": 28504,
      "##zog": 28505,
      "cochran": 28506,
      "##bula": 28507,
      "##lithic": 28508,
      "warring": 28509,
      "##rada": 28510,
      "dalai": 28511,
      "excused": 28512,
      "blazers": 28513,
      "mcconnell": 28514,
      "reeling": 28515,
      "bot": 28516,
      "este": 28517,
      "##abi": 28518,
      "geese": 28519,
      "hoax": 28520,
      "taxon": 28521,
      "##bla": 28522,
      "guitarists": 28523,
      "##icon": 28524,
      "condemning": 28525,
      "hunts": 28526,
      "inversion": 28527,
      "moffat": 28528,
      "taekwondo": 28529,
      "##lvis": 28530,
      "1624": 28531,
      "stammered": 28532,
      "##rest": 28533,
      "##rzy": 28534,
      "sousa": 28535,
      "fundraiser": 28536,
      "marylebone": 28537,
      "navigable": 28538,
      "uptown": 28539,
      "cabbage": 28540,
      "daniela": 28541,
      "salman": 28542,
      "shitty": 28543,
      "whimper": 28544,
      "##kian": 28545,
      "##utive": 28546,
      "programmers": 28547,
      "protections": 28548,
      "rm": 28549,
      "##rmi": 28550,
      "##rued": 28551,
      "forceful": 28552,
      "##enes": 28553,
      "fuss": 28554,
      "##tao": 28555,
      "##wash": 28556,
      "brat": 28557,
      "oppressive": 28558,
      "reykjavik": 28559,
      "spartak": 28560,
      "ticking": 28561,
      "##inkles": 28562,
      "##kiewicz": 28563,
      "adolph": 28564,
      "horst": 28565,
      "maui": 28566,
      "protege": 28567,
      "straighten": 28568,
      "cpc": 28569,
      "landau": 28570,
      "concourse": 28571,
      "clements": 28572,
      "resultant": 28573,
      "##ando": 28574,
      "imaginative": 28575,
      "joo": 28576,
      "reactivated": 28577,
      "##rem": 28578,
      "##ffled": 28579,
      "##uising": 28580,
      "consultative": 28581,
      "##guide": 28582,
      "flop": 28583,
      "kaitlyn": 28584,
      "mergers": 28585,
      "parenting": 28586,
      "somber": 28587,
      "##vron": 28588,
      "supervise": 28589,
      "vidhan": 28590,
      "##imum": 28591,
      "courtship": 28592,
      "exemplified": 28593,
      "harmonies": 28594,
      "medallist": 28595,
      "refining": 28596,
      "##rrow": 28597,
      "##ка": 28598,
      "amara": 28599,
      "##hum": 28600,
      "780": 28601,
      "goalscorer": 28602,
      "sited": 28603,
      "overshadowed": 28604,
      "rohan": 28605,
      "displeasure": 28606,
      "secretive": 28607,
      "multiplied": 28608,
      "osman": 28609,
      "##orth": 28610,
      "engravings": 28611,
      "padre": 28612,
      "##kali": 28613,
      "##veda": 28614,
      "miniatures": 28615,
      "mis": 28616,
      "##yala": 28617,
      "clap": 28618,
      "pali": 28619,
      "rook": 28620,
      "##cana": 28621,
      "1692": 28622,
      "57th": 28623,
      "antennae": 28624,
      "astro": 28625,
      "oskar": 28626,
      "1628": 28627,
      "bulldog": 28628,
      "crotch": 28629,
      "hackett": 28630,
      "yucatan": 28631,
      "##sure": 28632,
      "amplifiers": 28633,
      "brno": 28634,
      "ferrara": 28635,
      "migrating": 28636,
      "##gree": 28637,
      "thanking": 28638,
      "turing": 28639,
      "##eza": 28640,
      "mccann": 28641,
      "ting": 28642,
      "andersson": 28643,
      "onslaught": 28644,
      "gaines": 28645,
      "ganga": 28646,
      "incense": 28647,
      "standardization": 28648,
      "##mation": 28649,
      "sentai": 28650,
      "scuba": 28651,
      "stuffing": 28652,
      "turquoise": 28653,
      "waivers": 28654,
      "alloys": 28655,
      "##vitt": 28656,
      "regaining": 28657,
      "vaults": 28658,
      "##clops": 28659,
      "##gizing": 28660,
      "digger": 28661,
      "furry": 28662,
      "memorabilia": 28663,
      "probing": 28664,
      "##iad": 28665,
      "payton": 28666,
      "rec": 28667,
      "deutschland": 28668,
      "filippo": 28669,
      "opaque": 28670,
      "seamen": 28671,
      "zenith": 28672,
      "afrikaans": 28673,
      "##filtration": 28674,
      "disciplined": 28675,
      "inspirational": 28676,
      "##merie": 28677,
      "banco": 28678,
      "confuse": 28679,
      "grafton": 28680,
      "tod": 28681,
      "##dgets": 28682,
      "championed": 28683,
      "simi": 28684,
      "anomaly": 28685,
      "biplane": 28686,
      "##ceptive": 28687,
      "electrode": 28688,
      "##para": 28689,
      "1697": 28690,
      "cleavage": 28691,
      "crossbow": 28692,
      "swirl": 28693,
      "informant": 28694,
      "##lars": 28695,
      "##osta": 28696,
      "afi": 28697,
      "bonfire": 28698,
      "spec": 28699,
      "##oux": 28700,
      "lakeside": 28701,
      "slump": 28702,
      "##culus": 28703,
      "##lais": 28704,
      "##qvist": 28705,
      "##rrigan": 28706,
      "1016": 28707,
      "facades": 28708,
      "borg": 28709,
      "inwardly": 28710,
      "cervical": 28711,
      "xl": 28712,
      "pointedly": 28713,
      "050": 28714,
      "stabilization": 28715,
      "##odon": 28716,
      "chests": 28717,
      "1699": 28718,
      "hacked": 28719,
      "ctv": 28720,
      "orthogonal": 28721,
      "suzy": 28722,
      "##lastic": 28723,
      "gaulle": 28724,
      "jacobite": 28725,
      "rearview": 28726,
      "##cam": 28727,
      "##erted": 28728,
      "ashby": 28729,
      "##drik": 28730,
      "##igate": 28731,
      "##mise": 28732,
      "##zbek": 28733,
      "affectionately": 28734,
      "canine": 28735,
      "disperse": 28736,
      "latham": 28737,
      "##istles": 28738,
      "##ivar": 28739,
      "spielberg": 28740,
      "##orin": 28741,
      "##idium": 28742,
      "ezekiel": 28743,
      "cid": 28744,
      "##sg": 28745,
      "durga": 28746,
      "middletown": 28747,
      "##cina": 28748,
      "customized": 28749,
      "frontiers": 28750,
      "harden": 28751,
      "##etano": 28752,
      "##zzy": 28753,
      "1604": 28754,
      "bolsheviks": 28755,
      "##66": 28756,
      "coloration": 28757,
      "yoko": 28758,
      "##bedo": 28759,
      "briefs": 28760,
      "slabs": 28761,
      "debra": 28762,
      "liquidation": 28763,
      "plumage": 28764,
      "##oin": 28765,
      "blossoms": 28766,
      "dementia": 28767,
      "subsidy": 28768,
      "1611": 28769,
      "proctor": 28770,
      "relational": 28771,
      "jerseys": 28772,
      "parochial": 28773,
      "ter": 28774,
      "##ici": 28775,
      "esa": 28776,
      "peshawar": 28777,
      "cavalier": 28778,
      "loren": 28779,
      "cpi": 28780,
      "idiots": 28781,
      "shamrock": 28782,
      "1646": 28783,
      "dutton": 28784,
      "malabar": 28785,
      "mustache": 28786,
      "##endez": 28787,
      "##ocytes": 28788,
      "referencing": 28789,
      "terminates": 28790,
      "marche": 28791,
      "yarmouth": 28792,
      "##sop": 28793,
      "acton": 28794,
      "mated": 28795,
      "seton": 28796,
      "subtly": 28797,
      "baptised": 28798,
      "beige": 28799,
      "extremes": 28800,
      "jolted": 28801,
      "kristina": 28802,
      "telecast": 28803,
      "##actic": 28804,
      "safeguard": 28805,
      "waldo": 28806,
      "##baldi": 28807,
      "##bular": 28808,
      "endeavors": 28809,
      "sloppy": 28810,
      "subterranean": 28811,
      "##ensburg": 28812,
      "##itung": 28813,
      "delicately": 28814,
      "pigment": 28815,
      "tq": 28816,
      "##scu": 28817,
      "1626": 28818,
      "##ound": 28819,
      "collisions": 28820,
      "coveted": 28821,
      "herds": 28822,
      "##personal": 28823,
      "##meister": 28824,
      "##nberger": 28825,
      "chopra": 28826,
      "##ricting": 28827,
      "abnormalities": 28828,
      "defective": 28829,
      "galician": 28830,
      "lucie": 28831,
      "##dilly": 28832,
      "alligator": 28833,
      "likened": 28834,
      "##genase": 28835,
      "burundi": 28836,
      "clears": 28837,
      "complexion": 28838,
      "derelict": 28839,
      "deafening": 28840,
      "diablo": 28841,
      "fingered": 28842,
      "champaign": 28843,
      "dogg": 28844,
      "enlist": 28845,
      "isotope": 28846,
      "labeling": 28847,
      "mrna": 28848,
      "##erre": 28849,
      "brilliance": 28850,
      "marvelous": 28851,
      "##ayo": 28852,
      "1652": 28853,
      "crawley": 28854,
      "ether": 28855,
      "footed": 28856,
      "dwellers": 28857,
      "deserts": 28858,
      "hamish": 28859,
      "rubs": 28860,
      "warlock": 28861,
      "skimmed": 28862,
      "##lizer": 28863,
      "870": 28864,
      "buick": 28865,
      "embark": 28866,
      "heraldic": 28867,
      "irregularities": 28868,
      "##ajan": 28869,
      "kiara": 28870,
      "##kulam": 28871,
      "##ieg": 28872,
      "antigen": 28873,
      "kowalski": 28874,
      "##lge": 28875,
      "oakley": 28876,
      "visitation": 28877,
      "##mbit": 28878,
      "vt": 28879,
      "##suit": 28880,
      "1570": 28881,
      "murderers": 28882,
      "##miento": 28883,
      "##rites": 28884,
      "chimneys": 28885,
      "##sling": 28886,
      "condemn": 28887,
      "custer": 28888,
      "exchequer": 28889,
      "havre": 28890,
      "##ghi": 28891,
      "fluctuations": 28892,
      "##rations": 28893,
      "dfb": 28894,
      "hendricks": 28895,
      "vaccines": 28896,
      "##tarian": 28897,
      "nietzsche": 28898,
      "biking": 28899,
      "juicy": 28900,
      "##duced": 28901,
      "brooding": 28902,
      "scrolling": 28903,
      "selangor": 28904,
      "##ragan": 28905,
      "352": 28906,
      "annum": 28907,
      "boomed": 28908,
      "seminole": 28909,
      "sugarcane": 28910,
      "##dna": 28911,
      "departmental": 28912,
      "dismissing": 28913,
      "innsbruck": 28914,
      "arteries": 28915,
      "ashok": 28916,
      "batavia": 28917,
      "daze": 28918,
      "kun": 28919,
      "overtook": 28920,
      "##rga": 28921,
      "##tlan": 28922,
      "beheaded": 28923,
      "gaddafi": 28924,
      "holm": 28925,
      "electronically": 28926,
      "faulty": 28927,
      "galilee": 28928,
      "fractures": 28929,
      "kobayashi": 28930,
      "##lized": 28931,
      "gunmen": 28932,
      "magma": 28933,
      "aramaic": 28934,
      "mala": 28935,
      "eastenders": 28936,
      "inference": 28937,
      "messengers": 28938,
      "bf": 28939,
      "##qu": 28940,
      "407": 28941,
      "bathrooms": 28942,
      "##vere": 28943,
      "1658": 28944,
      "flashbacks": 28945,
      "ideally": 28946,
      "misunderstood": 28947,
      "##jali": 28948,
      "##weather": 28949,
      "mendez": 28950,
      "##grounds": 28951,
      "505": 28952,
      "uncanny": 28953,
      "##iii": 28954,
      "1709": 28955,
      "friendships": 28956,
      "##nbc": 28957,
      "sacrament": 28958,
      "accommodated": 28959,
      "reiterated": 28960,
      "logistical": 28961,
      "pebbles": 28962,
      "thumped": 28963,
      "##escence": 28964,
      "administering": 28965,
      "decrees": 28966,
      "drafts": 28967,
      "##flight": 28968,
      "##cased": 28969,
      "##tula": 28970,
      "futuristic": 28971,
      "picket": 28972,
      "intimidation": 28973,
      "winthrop": 28974,
      "##fahan": 28975,
      "interfered": 28976,
      "339": 28977,
      "afar": 28978,
      "francoise": 28979,
      "morally": 28980,
      "uta": 28981,
      "cochin": 28982,
      "croft": 28983,
      "dwarfs": 28984,
      "##bruck": 28985,
      "##dents": 28986,
      "##nami": 28987,
      "biker": 28988,
      "##hner": 28989,
      "##meral": 28990,
      "nano": 28991,
      "##isen": 28992,
      "##ometric": 28993,
      "##pres": 28994,
      "##ан": 28995,
      "brightened": 28996,
      "meek": 28997,
      "parcels": 28998,
      "securely": 28999,
      "gunners": 29000,
      "##jhl": 29001,
      "##zko": 29002,
      "agile": 29003,
      "hysteria": 29004,
      "##lten": 29005,
      "##rcus": 29006,
      "bukit": 29007,
      "champs": 29008,
      "chevy": 29009,
      "cuckoo": 29010,
      "leith": 29011,
      "sadler": 29012,
      "theologians": 29013,
      "welded": 29014,
      "##section": 29015,
      "1663": 29016,
      "jj": 29017,
      "plurality": 29018,
      "xander": 29019,
      "##rooms": 29020,
      "##formed": 29021,
      "shredded": 29022,
      "temps": 29023,
      "intimately": 29024,
      "pau": 29025,
      "tormented": 29026,
      "##lok": 29027,
      "##stellar": 29028,
      "1618": 29029,
      "charred": 29030,
      "ems": 29031,
      "essen": 29032,
      "##mmel": 29033,
      "alarms": 29034,
      "spraying": 29035,
      "ascot": 29036,
      "blooms": 29037,
      "twinkle": 29038,
      "##abia": 29039,
      "##apes": 29040,
      "internment": 29041,
      "obsidian": 29042,
      "##chaft": 29043,
      "snoop": 29044,
      "##dav": 29045,
      "##ooping": 29046,
      "malibu": 29047,
      "##tension": 29048,
      "quiver": 29049,
      "##itia": 29050,
      "hays": 29051,
      "mcintosh": 29052,
      "travers": 29053,
      "walsall": 29054,
      "##ffie": 29055,
      "1623": 29056,
      "beverley": 29057,
      "schwarz": 29058,
      "plunging": 29059,
      "structurally": 29060,
      "m3": 29061,
      "rosenthal": 29062,
      "vikram": 29063,
      "##tsk": 29064,
      "770": 29065,
      "ghz": 29066,
      "##onda": 29067,
      "##tiv": 29068,
      "chalmers": 29069,
      "groningen": 29070,
      "pew": 29071,
      "reckon": 29072,
      "unicef": 29073,
      "##rvis": 29074,
      "55th": 29075,
      "##gni": 29076,
      "1651": 29077,
      "sulawesi": 29078,
      "avila": 29079,
      "cai": 29080,
      "metaphysical": 29081,
      "screwing": 29082,
      "turbulence": 29083,
      "##mberg": 29084,
      "augusto": 29085,
      "samba": 29086,
      "56th": 29087,
      "baffled": 29088,
      "momentary": 29089,
      "toxin": 29090,
      "##urian": 29091,
      "##wani": 29092,
      "aachen": 29093,
      "condoms": 29094,
      "dali": 29095,
      "steppe": 29096,
      "##3d": 29097,
      "##app": 29098,
      "##oed": 29099,
      "##year": 29100,
      "adolescence": 29101,
      "dauphin": 29102,
      "electrically": 29103,
      "inaccessible": 29104,
      "microscopy": 29105,
      "nikita": 29106,
      "##ega": 29107,
      "atv": 29108,
      "##cel": 29109,
      "##enter": 29110,
      "##oles": 29111,
      "##oteric": 29112,
      "##ы": 29113,
      "accountants": 29114,
      "punishments": 29115,
      "wrongly": 29116,
      "bribes": 29117,
      "adventurous": 29118,
      "clinch": 29119,
      "flinders": 29120,
      "southland": 29121,
      "##hem": 29122,
      "##kata": 29123,
      "gough": 29124,
      "##ciency": 29125,
      "lads": 29126,
      "soared": 29127,
      "##ה": 29128,
      "undergoes": 29129,
      "deformation": 29130,
      "outlawed": 29131,
      "rubbish": 29132,
      "##arus": 29133,
      "##mussen": 29134,
      "##nidae": 29135,
      "##rzburg": 29136,
      "arcs": 29137,
      "##ingdon": 29138,
      "##tituted": 29139,
      "1695": 29140,
      "wheelbase": 29141,
      "wheeling": 29142,
      "bombardier": 29143,
      "campground": 29144,
      "zebra": 29145,
      "##lices": 29146,
      "##oj": 29147,
      "##bain": 29148,
      "lullaby": 29149,
      "##ecure": 29150,
      "donetsk": 29151,
      "wylie": 29152,
      "grenada": 29153,
      "##arding": 29154,
      "##ης": 29155,
      "squinting": 29156,
      "eireann": 29157,
      "opposes": 29158,
      "##andra": 29159,
      "maximal": 29160,
      "runes": 29161,
      "##broken": 29162,
      "##cuting": 29163,
      "##iface": 29164,
      "##ror": 29165,
      "##rosis": 29166,
      "additive": 29167,
      "britney": 29168,
      "adultery": 29169,
      "triggering": 29170,
      "##drome": 29171,
      "detrimental": 29172,
      "aarhus": 29173,
      "containment": 29174,
      "jc": 29175,
      "swapped": 29176,
      "vichy": 29177,
      "##ioms": 29178,
      "madly": 29179,
      "##oric": 29180,
      "##rag": 29181,
      "brant": 29182,
      "##ckey": 29183,
      "##trix": 29184,
      "1560": 29185,
      "1612": 29186,
      "broughton": 29187,
      "rustling": 29188,
      "##stems": 29189,
      "##uder": 29190,
      "asbestos": 29191,
      "mentoring": 29192,
      "##nivorous": 29193,
      "finley": 29194,
      "leaps": 29195,
      "##isan": 29196,
      "apical": 29197,
      "pry": 29198,
      "slits": 29199,
      "substitutes": 29200,
      "##dict": 29201,
      "intuitive": 29202,
      "fantasia": 29203,
      "insistent": 29204,
      "unreasonable": 29205,
      "##igen": 29206,
      "##vna": 29207,
      "domed": 29208,
      "hannover": 29209,
      "margot": 29210,
      "ponder": 29211,
      "##zziness": 29212,
      "impromptu": 29213,
      "jian": 29214,
      "lc": 29215,
      "rampage": 29216,
      "stemming": 29217,
      "##eft": 29218,
      "andrey": 29219,
      "gerais": 29220,
      "whichever": 29221,
      "amnesia": 29222,
      "appropriated": 29223,
      "anzac": 29224,
      "clicks": 29225,
      "modifying": 29226,
      "ultimatum": 29227,
      "cambrian": 29228,
      "maids": 29229,
      "verve": 29230,
      "yellowstone": 29231,
      "##mbs": 29232,
      "conservatoire": 29233,
      "##scribe": 29234,
      "adherence": 29235,
      "dinners": 29236,
      "spectra": 29237,
      "imperfect": 29238,
      "mysteriously": 29239,
      "sidekick": 29240,
      "tatar": 29241,
      "tuba": 29242,
      "##aks": 29243,
      "##ifolia": 29244,
      "distrust": 29245,
      "##athan": 29246,
      "##zle": 29247,
      "c2": 29248,
      "ronin": 29249,
      "zac": 29250,
      "##pse": 29251,
      "celaena": 29252,
      "instrumentalist": 29253,
      "scents": 29254,
      "skopje": 29255,
      "##mbling": 29256,
      "comical": 29257,
      "compensated": 29258,
      "vidal": 29259,
      "condor": 29260,
      "intersect": 29261,
      "jingle": 29262,
      "wavelengths": 29263,
      "##urrent": 29264,
      "mcqueen": 29265,
      "##izzly": 29266,
      "carp": 29267,
      "weasel": 29268,
      "422": 29269,
      "kanye": 29270,
      "militias": 29271,
      "postdoctoral": 29272,
      "eugen": 29273,
      "gunslinger": 29274,
      "##ɛ": 29275,
      "faux": 29276,
      "hospice": 29277,
      "##for": 29278,
      "appalled": 29279,
      "derivation": 29280,
      "dwarves": 29281,
      "##elis": 29282,
      "dilapidated": 29283,
      "##folk": 29284,
      "astoria": 29285,
      "philology": 29286,
      "##lwyn": 29287,
      "##otho": 29288,
      "##saka": 29289,
      "inducing": 29290,
      "philanthropy": 29291,
      "##bf": 29292,
      "##itative": 29293,
      "geek": 29294,
      "markedly": 29295,
      "sql": 29296,
      "##yce": 29297,
      "bessie": 29298,
      "indices": 29299,
      "rn": 29300,
      "##flict": 29301,
      "495": 29302,
      "frowns": 29303,
      "resolving": 29304,
      "weightlifting": 29305,
      "tugs": 29306,
      "cleric": 29307,
      "contentious": 29308,
      "1653": 29309,
      "mania": 29310,
      "rms": 29311,
      "##miya": 29312,
      "##reate": 29313,
      "##ruck": 29314,
      "##tucket": 29315,
      "bien": 29316,
      "eels": 29317,
      "marek": 29318,
      "##ayton": 29319,
      "##cence": 29320,
      "discreet": 29321,
      "unofficially": 29322,
      "##ife": 29323,
      "leaks": 29324,
      "##bber": 29325,
      "1705": 29326,
      "332": 29327,
      "dung": 29328,
      "compressor": 29329,
      "hillsborough": 29330,
      "pandit": 29331,
      "shillings": 29332,
      "distal": 29333,
      "##skin": 29334,
      "381": 29335,
      "##tat": 29336,
      "##you": 29337,
      "nosed": 29338,
      "##nir": 29339,
      "mangrove": 29340,
      "undeveloped": 29341,
      "##idia": 29342,
      "textures": 29343,
      "##inho": 29344,
      "##500": 29345,
      "##rise": 29346,
      "ae": 29347,
      "irritating": 29348,
      "nay": 29349,
      "amazingly": 29350,
      "bancroft": 29351,
      "apologetic": 29352,
      "compassionate": 29353,
      "kata": 29354,
      "symphonies": 29355,
      "##lovic": 29356,
      "airspace": 29357,
      "##lch": 29358,
      "930": 29359,
      "gifford": 29360,
      "precautions": 29361,
      "fulfillment": 29362,
      "sevilla": 29363,
      "vulgar": 29364,
      "martinique": 29365,
      "##urities": 29366,
      "looting": 29367,
      "piccolo": 29368,
      "tidy": 29369,
      "##dermott": 29370,
      "quadrant": 29371,
      "armchair": 29372,
      "incomes": 29373,
      "mathematicians": 29374,
      "stampede": 29375,
      "nilsson": 29376,
      "##inking": 29377,
      "##scan": 29378,
      "foo": 29379,
      "quarterfinal": 29380,
      "##ostal": 29381,
      "shang": 29382,
      "shouldered": 29383,
      "squirrels": 29384,
      "##owe": 29385,
      "344": 29386,
      "vinegar": 29387,
      "##bner": 29388,
      "##rchy": 29389,
      "##systems": 29390,
      "delaying": 29391,
      "##trics": 29392,
      "ars": 29393,
      "dwyer": 29394,
      "rhapsody": 29395,
      "sponsoring": 29396,
      "##gration": 29397,
      "bipolar": 29398,
      "cinder": 29399,
      "starters": 29400,
      "##olio": 29401,
      "##urst": 29402,
      "421": 29403,
      "signage": 29404,
      "##nty": 29405,
      "aground": 29406,
      "figurative": 29407,
      "mons": 29408,
      "acquaintances": 29409,
      "duets": 29410,
      "erroneously": 29411,
      "soyuz": 29412,
      "elliptic": 29413,
      "recreated": 29414,
      "##cultural": 29415,
      "##quette": 29416,
      "##ssed": 29417,
      "##tma": 29418,
      "##zcz": 29419,
      "moderator": 29420,
      "scares": 29421,
      "##itaire": 29422,
      "##stones": 29423,
      "##udence": 29424,
      "juniper": 29425,
      "sighting": 29426,
      "##just": 29427,
      "##nsen": 29428,
      "britten": 29429,
      "calabria": 29430,
      "ry": 29431,
      "bop": 29432,
      "cramer": 29433,
      "forsyth": 29434,
      "stillness": 29435,
      "##л": 29436,
      "airmen": 29437,
      "gathers": 29438,
      "unfit": 29439,
      "##umber": 29440,
      "##upt": 29441,
      "taunting": 29442,
      "##rip": 29443,
      "seeker": 29444,
      "streamlined": 29445,
      "##bution": 29446,
      "holster": 29447,
      "schumann": 29448,
      "tread": 29449,
      "vox": 29450,
      "##gano": 29451,
      "##onzo": 29452,
      "strive": 29453,
      "dil": 29454,
      "reforming": 29455,
      "covent": 29456,
      "newbury": 29457,
      "predicting": 29458,
      "##orro": 29459,
      "decorate": 29460,
      "tre": 29461,
      "##puted": 29462,
      "andover": 29463,
      "ie": 29464,
      "asahi": 29465,
      "dept": 29466,
      "dunkirk": 29467,
      "gills": 29468,
      "##tori": 29469,
      "buren": 29470,
      "huskies": 29471,
      "##stis": 29472,
      "##stov": 29473,
      "abstracts": 29474,
      "bets": 29475,
      "loosen": 29476,
      "##opa": 29477,
      "1682": 29478,
      "yearning": 29479,
      "##glio": 29480,
      "##sir": 29481,
      "berman": 29482,
      "effortlessly": 29483,
      "enamel": 29484,
      "napoli": 29485,
      "persist": 29486,
      "##peration": 29487,
      "##uez": 29488,
      "attache": 29489,
      "elisa": 29490,
      "b1": 29491,
      "invitations": 29492,
      "##kic": 29493,
      "accelerating": 29494,
      "reindeer": 29495,
      "boardwalk": 29496,
      "clutches": 29497,
      "nelly": 29498,
      "polka": 29499,
      "starbucks": 29500,
      "##kei": 29501,
      "adamant": 29502,
      "huey": 29503,
      "lough": 29504,
      "unbroken": 29505,
      "adventurer": 29506,
      "embroidery": 29507,
      "inspecting": 29508,
      "stanza": 29509,
      "##ducted": 29510,
      "naia": 29511,
      "taluka": 29512,
      "##pone": 29513,
      "##roids": 29514,
      "chases": 29515,
      "deprivation": 29516,
      "florian": 29517,
      "##jing": 29518,
      "##ppet": 29519,
      "earthly": 29520,
      "##lib": 29521,
      "##ssee": 29522,
      "colossal": 29523,
      "foreigner": 29524,
      "vet": 29525,
      "freaks": 29526,
      "patrice": 29527,
      "rosewood": 29528,
      "triassic": 29529,
      "upstate": 29530,
      "##pkins": 29531,
      "dominates": 29532,
      "ata": 29533,
      "chants": 29534,
      "ks": 29535,
      "vo": 29536,
      "##400": 29537,
      "##bley": 29538,
      "##raya": 29539,
      "##rmed": 29540,
      "555": 29541,
      "agra": 29542,
      "infiltrate": 29543,
      "##ailing": 29544,
      "##ilation": 29545,
      "##tzer": 29546,
      "##uppe": 29547,
      "##werk": 29548,
      "binoculars": 29549,
      "enthusiast": 29550,
      "fujian": 29551,
      "squeak": 29552,
      "##avs": 29553,
      "abolitionist": 29554,
      "almeida": 29555,
      "boredom": 29556,
      "hampstead": 29557,
      "marsden": 29558,
      "rations": 29559,
      "##ands": 29560,
      "inflated": 29561,
      "334": 29562,
      "bonuses": 29563,
      "rosalie": 29564,
      "patna": 29565,
      "##rco": 29566,
      "329": 29567,
      "detachments": 29568,
      "penitentiary": 29569,
      "54th": 29570,
      "flourishing": 29571,
      "woolf": 29572,
      "##dion": 29573,
      "##etched": 29574,
      "papyrus": 29575,
      "##lster": 29576,
      "##nsor": 29577,
      "##toy": 29578,
      "bobbed": 29579,
      "dismounted": 29580,
      "endelle": 29581,
      "inhuman": 29582,
      "motorola": 29583,
      "tbs": 29584,
      "wince": 29585,
      "wreath": 29586,
      "##ticus": 29587,
      "hideout": 29588,
      "inspections": 29589,
      "sanjay": 29590,
      "disgrace": 29591,
      "infused": 29592,
      "pudding": 29593,
      "stalks": 29594,
      "##urbed": 29595,
      "arsenic": 29596,
      "leases": 29597,
      "##hyl": 29598,
      "##rrard": 29599,
      "collarbone": 29600,
      "##waite": 29601,
      "##wil": 29602,
      "dowry": 29603,
      "##bant": 29604,
      "##edance": 29605,
      "genealogical": 29606,
      "nitrate": 29607,
      "salamanca": 29608,
      "scandals": 29609,
      "thyroid": 29610,
      "necessitated": 29611,
      "##!": 29612,
      "##\"": 29613,
      "###": 29614,
      "##$": 29615,
      "##%": 29616,
      "##&": 29617,
      "##'": 29618,
      "##(": 29619,
      "##)": 29620,
      "##*": 29621,
      "##+": 29622,
      "##,": 29623,
      "##-": 29624,
      "##.": 29625,
      "##/": 29626,
      "##:": 29627,
      "##;": 29628,
      "##<": 29629,
      "##=": 29630,
      "##>": 29631,
      "##?": 29632,
      "##@": 29633,
      "##[": 29634,
      "##\\": 29635,
      "##]": 29636,
      "##^": 29637,
      "##_": 29638,
      "##`": 29639,
      "##{": 29640,
      "##|": 29641,
      "##}": 29642,
      "##~": 29643,
      "##¡": 29644,
      "##¢": 29645,
      "##£": 29646,
      "##¤": 29647,
      "##¥": 29648,
      "##¦": 29649,
      "##§": 29650,
      "##¨": 29651,
      "##©": 29652,
      "##ª": 29653,
      "##«": 29654,
      "##¬": 29655,
      "##®": 29656,
      "##±": 29657,
      "##´": 29658,
      "##µ": 29659,
      "##¶": 29660,
      "##·": 29661,
      "##º": 29662,
      "##»": 29663,
      "##¼": 29664,
      "##¾": 29665,
      "##¿": 29666,
      "##æ": 29667,
      "##ð": 29668,
      "##÷": 29669,
      "##þ": 29670,
      "##đ": 29671,
      "##ħ": 29672,
      "##ŋ": 29673,
      "##œ": 29674,
      "##ƒ": 29675,
      "##ɐ": 29676,
      "##ɑ": 29677,
      "##ɒ": 29678,
      "##ɔ": 29679,
      "##ɕ": 29680,
      "##ə": 29681,
      "##ɡ": 29682,
      "##ɣ": 29683,
      "##ɨ": 29684,
      "##ɪ": 29685,
      "##ɫ": 29686,
      "##ɬ": 29687,
      "##ɯ": 29688,
      "##ɲ": 29689,
      "##ɴ": 29690,
      "##ɹ": 29691,
      "##ɾ": 29692,
      "##ʀ": 29693,
      "##ʁ": 29694,
      "##ʂ": 29695,
      "##ʃ": 29696,
      "##ʉ": 29697,
      "##ʊ": 29698,
      "##ʋ": 29699,
      "##ʌ": 29700,
      "##ʎ": 29701,
      "##ʐ": 29702,
      "##ʑ": 29703,
      "##ʒ": 29704,
      "##ʔ": 29705,
      "##ʰ": 29706,
      "##ʲ": 29707,
      "##ʳ": 29708,
      "##ʷ": 29709,
      "##ʸ": 29710,
      "##ʻ": 29711,
      "##ʼ": 29712,
      "##ʾ": 29713,
      "##ʿ": 29714,
      "##ˈ": 29715,
      "##ˡ": 29716,
      "##ˢ": 29717,
      "##ˣ": 29718,
      "##ˤ": 29719,
      "##β": 29720,
      "##γ": 29721,
      "##δ": 29722,
      "##ε": 29723,
      "##ζ": 29724,
      "##θ": 29725,
      "##κ": 29726,
      "##λ": 29727,
      "##μ": 29728,
      "##ξ": 29729,
      "##ο": 29730,
      "##π": 29731,
      "##ρ": 29732,
      "##σ": 29733,
      "##τ": 29734,
      "##υ": 29735,
      "##φ": 29736,
      "##χ": 29737,
      "##ψ": 29738,
      "##ω": 29739,
      "##б": 29740,
      "##г": 29741,
      "##д": 29742,
      "##ж": 29743,
      "##з": 29744,
      "##м": 29745,
      "##п": 29746,
      "##с": 29747,
      "##у": 29748,
      "##ф": 29749,
      "##х": 29750,
      "##ц": 29751,
      "##ч": 29752,
      "##ш": 29753,
      "##щ": 29754,
      "##ъ": 29755,
      "##э": 29756,
      "##ю": 29757,
      "##ђ": 29758,
      "##є": 29759,
      "##і": 29760,
      "##ј": 29761,
      "##љ": 29762,
      "##њ": 29763,
      "##ћ": 29764,
      "##ӏ": 29765,
      "##ա": 29766,
      "##բ": 29767,
      "##գ": 29768,
      "##դ": 29769,
      "##ե": 29770,
      "##թ": 29771,
      "##ի": 29772,
      "##լ": 29773,
      "##կ": 29774,
      "##հ": 29775,
      "##մ": 29776,
      "##յ": 29777,
      "##ն": 29778,
      "##ո": 29779,
      "##պ": 29780,
      "##ս": 29781,
      "##վ": 29782,
      "##տ": 29783,
      "##ր": 29784,
      "##ւ": 29785,
      "##ք": 29786,
      "##־": 29787,
      "##א": 29788,
      "##ב": 29789,
      "##ג": 29790,
      "##ד": 29791,
      "##ו": 29792,
      "##ז": 29793,
      "##ח": 29794,
      "##ט": 29795,
      "##י": 29796,
      "##ך": 29797,
      "##כ": 29798,
      "##ל": 29799,
      "##ם": 29800,
      "##מ": 29801,
      "##ן": 29802,
      "##נ": 29803,
      "##ס": 29804,
      "##ע": 29805,
      "##ף": 29806,
      "##פ": 29807,
      "##ץ": 29808,
      "##צ": 29809,
      "##ק": 29810,
      "##ר": 29811,
      "##ש": 29812,
      "##ת": 29813,
      "##،": 29814,
      "##ء": 29815,
      "##ب": 29816,
      "##ت": 29817,
      "##ث": 29818,
      "##ج": 29819,
      "##ح": 29820,
      "##خ": 29821,
      "##ذ": 29822,
      "##ز": 29823,
      "##س": 29824,
      "##ش": 29825,
      "##ص": 29826,
      "##ض": 29827,
      "##ط": 29828,
      "##ظ": 29829,
      "##ع": 29830,
      "##غ": 29831,
      "##ـ": 29832,
      "##ف": 29833,
      "##ق": 29834,
      "##ك": 29835,
      "##و": 29836,
      "##ى": 29837,
      "##ٹ": 29838,
      "##پ": 29839,
      "##چ": 29840,
      "##ک": 29841,
      "##گ": 29842,
      "##ں": 29843,
      "##ھ": 29844,
      "##ہ": 29845,
      "##ے": 29846,
      "##अ": 29847,
      "##आ": 29848,
      "##उ": 29849,
      "##ए": 29850,
      "##क": 29851,
      "##ख": 29852,
      "##ग": 29853,
      "##च": 29854,
      "##ज": 29855,
      "##ट": 29856,
      "##ड": 29857,
      "##ण": 29858,
      "##त": 29859,
      "##थ": 29860,
      "##द": 29861,
      "##ध": 29862,
      "##न": 29863,
      "##प": 29864,
      "##ब": 29865,
      "##भ": 29866,
      "##म": 29867,
      "##य": 29868,
      "##र": 29869,
      "##ल": 29870,
      "##व": 29871,
      "##श": 29872,
      "##ष": 29873,
      "##स": 29874,
      "##ह": 29875,
      "##ा": 29876,
      "##ि": 29877,
      "##ी": 29878,
      "##ो": 29879,
      "##।": 29880,
      "##॥": 29881,
      "##ং": 29882,
      "##অ": 29883,
      "##আ": 29884,
      "##ই": 29885,
      "##উ": 29886,
      "##এ": 29887,
      "##ও": 29888,
      "##ক": 29889,
      "##খ": 29890,
      "##গ": 29891,
      "##চ": 29892,
      "##ছ": 29893,
      "##জ": 29894,
      "##ট": 29895,
      "##ড": 29896,
      "##ণ": 29897,
      "##ত": 29898,
      "##থ": 29899,
      "##দ": 29900,
      "##ধ": 29901,
      "##ন": 29902,
      "##প": 29903,
      "##ব": 29904,
      "##ভ": 29905,
      "##ম": 29906,
      "##য": 29907,
      "##র": 29908,
      "##ল": 29909,
      "##শ": 29910,
      "##ষ": 29911,
      "##স": 29912,
      "##হ": 29913,
      "##া": 29914,
      "##ি": 29915,
      "##ী": 29916,
      "##ে": 29917,
      "##க": 29918,
      "##ச": 29919,
      "##ட": 29920,
      "##த": 29921,
      "##ந": 29922,
      "##ன": 29923,
      "##ப": 29924,
      "##ம": 29925,
      "##ய": 29926,
      "##ர": 29927,
      "##ல": 29928,
      "##ள": 29929,
      "##வ": 29930,
      "##ா": 29931,
      "##ி": 29932,
      "##ு": 29933,
      "##ே": 29934,
      "##ை": 29935,
      "##ನ": 29936,
      "##ರ": 29937,
      "##ಾ": 29938,
      "##ක": 29939,
      "##ය": 29940,
      "##ර": 29941,
      "##ල": 29942,
      "##ව": 29943,
      "##ා": 29944,
      "##ก": 29945,
      "##ง": 29946,
      "##ต": 29947,
      "##ท": 29948,
      "##น": 29949,
      "##พ": 29950,
      "##ม": 29951,
      "##ย": 29952,
      "##ร": 29953,
      "##ล": 29954,
      "##ว": 29955,
      "##ส": 29956,
      "##อ": 29957,
      "##า": 29958,
      "##เ": 29959,
      "##་": 29960,
      "##།": 29961,
      "##ག": 29962,
      "##ང": 29963,
      "##ད": 29964,
      "##ན": 29965,
      "##པ": 29966,
      "##བ": 29967,
      "##མ": 29968,
      "##འ": 29969,
      "##ར": 29970,
      "##ལ": 29971,
      "##ས": 29972,
      "##မ": 29973,
      "##ა": 29974,
      "##ბ": 29975,
      "##გ": 29976,
      "##დ": 29977,
      "##ე": 29978,
      "##ვ": 29979,
      "##თ": 29980,
      "##ი": 29981,
      "##კ": 29982,
      "##ლ": 29983,
      "##მ": 29984,
      "##ნ": 29985,
      "##ო": 29986,
      "##რ": 29987,
      "##ს": 29988,
      "##ტ": 29989,
      "##უ": 29990,
      "##ᄀ": 29991,
      "##ᄂ": 29992,
      "##ᄃ": 29993,
      "##ᄅ": 29994,
      "##ᄆ": 29995,
      "##ᄇ": 29996,
      "##ᄉ": 29997,
      "##ᄊ": 29998,
      "##ᄋ": 29999,
      "##ᄌ": 30000,
      "##ᄎ": 30001,
      "##ᄏ": 30002,
      "##ᄐ": 30003,
      "##ᄑ": 30004,
      "##ᄒ": 30005,
      "##ᅡ": 30006,
      "##ᅢ": 30007,
      "##ᅥ": 30008,
      "##ᅦ": 30009,
      "##ᅧ": 30010,
      "##ᅩ": 30011,
      "##ᅪ": 30012,
      "##ᅭ": 30013,
      "##ᅮ": 30014,
      "##ᅯ": 30015,
      "##ᅲ": 30016,
      "##ᅳ": 30017,
      "##ᅴ": 30018,
      "##ᅵ": 30019,
      "##ᆨ": 30020,
      "##ᆫ": 30021,
      "##ᆯ": 30022,
      "##ᆷ": 30023,
      "##ᆸ": 30024,
      "##ᆼ": 30025,
      "##ᴬ": 30026,
      "##ᴮ": 30027,
      "##ᴰ": 30028,
      "##ᴵ": 30029,
      "##ᴺ": 30030,
      "##ᵀ": 30031,
      "##ᵃ": 30032,
      "##ᵇ": 30033,
      "##ᵈ": 30034,
      "##ᵉ": 30035,
      "##ᵍ": 30036,
      "##ᵏ": 30037,
      "##ᵐ": 30038,
      "##ᵒ": 30039,
      "##ᵖ": 30040,
      "##ᵗ": 30041,
      "##ᵘ": 30042,
      "##ᵣ": 30043,
      "##ᵤ": 30044,
      "##ᵥ": 30045,
      "##ᶜ": 30046,
      "##ᶠ": 30047,
      "##‐": 30048,
      "##‑": 30049,
      "##‒": 30050,
      "##–": 30051,
      "##—": 30052,
      "##―": 30053,
      "##‖": 30054,
      "##‘": 30055,
      "##’": 30056,
      "##‚": 30057,
      "##“": 30058,
      "##”": 30059,
      "##„": 30060,
      "##†": 30061,
      "##‡": 30062,
      "##•": 30063,
      "##…": 30064,
      "##‰": 30065,
      "##′": 30066,
      "##″": 30067,
      "##›": 30068,
      "##‿": 30069,
      "##⁄": 30070,
      "##⁰": 30071,
      "##ⁱ": 30072,
      "##⁴": 30073,
      "##⁵": 30074,
      "##⁶": 30075,
      "##⁷": 30076,
      "##⁸": 30077,
      "##⁹": 30078,
      "##⁻": 30079,
      "##ⁿ": 30080,
      "##₅": 30081,
      "##₆": 30082,
      "##₇": 30083,
      "##₈": 30084,
      "##₉": 30085,
      "##₊": 30086,
      "##₍": 30087,
      "##₎": 30088,
      "##ₐ": 30089,
      "##ₑ": 30090,
      "##ₒ": 30091,
      "##ₓ": 30092,
      "##ₕ": 30093,
      "##ₖ": 30094,
      "##ₗ": 30095,
      "##ₘ": 30096,
      "##ₚ": 30097,
      "##ₛ": 30098,
      "##ₜ": 30099,
      "##₤": 30100,
      "##₩": 30101,
      "##€": 30102,
      "##₱": 30103,
      "##₹": 30104,
      "##ℓ": 30105,
      "##№": 30106,
      "##ℝ": 30107,
      "##™": 30108,
      "##⅓": 30109,
      "##⅔": 30110,
      "##←": 30111,
      "##↑": 30112,
      "##→": 30113,
      "##↓": 30114,
      "##↔": 30115,
      "##↦": 30116,
      "##⇄": 30117,
      "##⇌": 30118,
      "##⇒": 30119,
      "##∂": 30120,
      "##∅": 30121,
      "##∆": 30122,
      "##∇": 30123,
      "##∈": 30124,
      "##∗": 30125,
      "##∘": 30126,
      "##√": 30127,
      "##∞": 30128,
      "##∧": 30129,
      "##∨": 30130,
      "##∩": 30131,
      "##∪": 30132,
      "##≈": 30133,
      "##≡": 30134,
      "##≤": 30135,
      "##≥": 30136,
      "##⊂": 30137,
      "##⊆": 30138,
      "##⊕": 30139,
      "##⊗": 30140,
      "##⋅": 30141,
      "##─": 30142,
      "##│": 30143,
      "##■": 30144,
      "##▪": 30145,
      "##●": 30146,
      "##★": 30147,
      "##☆": 30148,
      "##☉": 30149,
      "##♠": 30150,
      "##♣": 30151,
      "##♥": 30152,
      "##♦": 30153,
      "##♯": 30154,
      "##⟨": 30155,
      "##⟩": 30156,
      "##ⱼ": 30157,
      "##⺩": 30158,
      "##⺼": 30159,
      "##⽥": 30160,
      "##、": 30161,
      "##。": 30162,
      "##〈": 30163,
      "##〉": 30164,
      "##《": 30165,
      "##》": 30166,
      "##「": 30167,
      "##」": 30168,
      "##『": 30169,
      "##』": 30170,
      "##〜": 30171,
      "##あ": 30172,
      "##い": 30173,
      "##う": 30174,
      "##え": 30175,
      "##お": 30176,
      "##か": 30177,
      "##き": 30178,
      "##く": 30179,
      "##け": 30180,
      "##こ": 30181,
      "##さ": 30182,
      "##し": 30183,
      "##す": 30184,
      "##せ": 30185,
      "##そ": 30186,
      "##た": 30187,
      "##ち": 30188,
      "##っ": 30189,
      "##つ": 30190,
      "##て": 30191,
      "##と": 30192,
      "##な": 30193,
      "##に": 30194,
      "##ぬ": 30195,
      "##ね": 30196,
      "##の": 30197,
      "##は": 30198,
      "##ひ": 30199,
      "##ふ": 30200,
      "##へ": 30201,
      "##ほ": 30202,
      "##ま": 30203,
      "##み": 30204,
      "##む": 30205,
      "##め": 30206,
      "##も": 30207,
      "##や": 30208,
      "##ゆ": 30209,
      "##よ": 30210,
      "##ら": 30211,
      "##り": 30212,
      "##る": 30213,
      "##れ": 30214,
      "##ろ": 30215,
      "##を": 30216,
      "##ん": 30217,
      "##ァ": 30218,
      "##ア": 30219,
      "##ィ": 30220,
      "##イ": 30221,
      "##ウ": 30222,
      "##ェ": 30223,
      "##エ": 30224,
      "##オ": 30225,
      "##カ": 30226,
      "##キ": 30227,
      "##ク": 30228,
      "##ケ": 30229,
      "##コ": 30230,
      "##サ": 30231,
      "##シ": 30232,
      "##ス": 30233,
      "##セ": 30234,
      "##タ": 30235,
      "##チ": 30236,
      "##ッ": 30237,
      "##ツ": 30238,
      "##テ": 30239,
      "##ト": 30240,
      "##ナ": 30241,
      "##ニ": 30242,
      "##ノ": 30243,
      "##ハ": 30244,
      "##ヒ": 30245,
      "##フ": 30246,
      "##ヘ": 30247,
      "##ホ": 30248,
      "##マ": 30249,
      "##ミ": 30250,
      "##ム": 30251,
      "##メ": 30252,
      "##モ": 30253,
      "##ャ": 30254,
      "##ュ": 30255,
      "##ョ": 30256,
      "##ラ": 30257,
      "##リ": 30258,
      "##ル": 30259,
      "##レ": 30260,
      "##ロ": 30261,
      "##ワ": 30262,
      "##ン": 30263,
      "##・": 30264,
      "##ー": 30265,
      "##一": 30266,
      "##三": 30267,
      "##上": 30268,
      "##下": 30269,
      "##不": 30270,
      "##世": 30271,
      "##中": 30272,
      "##主": 30273,
      "##久": 30274,
      "##之": 30275,
      "##也": 30276,
      "##事": 30277,
      "##二": 30278,
      "##五": 30279,
      "##井": 30280,
      "##京": 30281,
      "##人": 30282,
      "##亻": 30283,
      "##仁": 30284,
      "##介": 30285,
      "##代": 30286,
      "##仮": 30287,
      "##伊": 30288,
      "##会": 30289,
      "##佐": 30290,
      "##侍": 30291,
      "##保": 30292,
      "##信": 30293,
      "##健": 30294,
      "##元": 30295,
      "##光": 30296,
      "##八": 30297,
      "##公": 30298,
      "##内": 30299,
      "##出": 30300,
      "##分": 30301,
      "##前": 30302,
      "##劉": 30303,
      "##力": 30304,
      "##加": 30305,
      "##勝": 30306,
      "##北": 30307,
      "##区": 30308,
      "##十": 30309,
      "##千": 30310,
      "##南": 30311,
      "##博": 30312,
      "##原": 30313,
      "##口": 30314,
      "##古": 30315,
      "##史": 30316,
      "##司": 30317,
      "##合": 30318,
      "##吉": 30319,
      "##同": 30320,
      "##名": 30321,
      "##和": 30322,
      "##囗": 30323,
      "##四": 30324,
      "##国": 30325,
      "##國": 30326,
      "##土": 30327,
      "##地": 30328,
      "##坂": 30329,
      "##城": 30330,
      "##堂": 30331,
      "##場": 30332,
      "##士": 30333,
      "##夏": 30334,
      "##外": 30335,
      "##大": 30336,
      "##天": 30337,
      "##太": 30338,
      "##夫": 30339,
      "##奈": 30340,
      "##女": 30341,
      "##子": 30342,
      "##学": 30343,
      "##宀": 30344,
      "##宇": 30345,
      "##安": 30346,
      "##宗": 30347,
      "##定": 30348,
      "##宣": 30349,
      "##宮": 30350,
      "##家": 30351,
      "##宿": 30352,
      "##寺": 30353,
      "##將": 30354,
      "##小": 30355,
      "##尚": 30356,
      "##山": 30357,
      "##岡": 30358,
      "##島": 30359,
      "##崎": 30360,
      "##川": 30361,
      "##州": 30362,
      "##巿": 30363,
      "##帝": 30364,
      "##平": 30365,
      "##年": 30366,
      "##幸": 30367,
      "##广": 30368,
      "##弘": 30369,
      "##張": 30370,
      "##彳": 30371,
      "##後": 30372,
      "##御": 30373,
      "##德": 30374,
      "##心": 30375,
      "##忄": 30376,
      "##志": 30377,
      "##忠": 30378,
      "##愛": 30379,
      "##成": 30380,
      "##我": 30381,
      "##戦": 30382,
      "##戸": 30383,
      "##手": 30384,
      "##扌": 30385,
      "##政": 30386,
      "##文": 30387,
      "##新": 30388,
      "##方": 30389,
      "##日": 30390,
      "##明": 30391,
      "##星": 30392,
      "##春": 30393,
      "##昭": 30394,
      "##智": 30395,
      "##曲": 30396,
      "##書": 30397,
      "##月": 30398,
      "##有": 30399,
      "##朝": 30400,
      "##木": 30401,
      "##本": 30402,
      "##李": 30403,
      "##村": 30404,
      "##東": 30405,
      "##松": 30406,
      "##林": 30407,
      "##森": 30408,
      "##楊": 30409,
      "##樹": 30410,
      "##橋": 30411,
      "##歌": 30412,
      "##止": 30413,
      "##正": 30414,
      "##武": 30415,
      "##比": 30416,
      "##氏": 30417,
      "##民": 30418,
      "##水": 30419,
      "##氵": 30420,
      "##氷": 30421,
      "##永": 30422,
      "##江": 30423,
      "##沢": 30424,
      "##河": 30425,
      "##治": 30426,
      "##法": 30427,
      "##海": 30428,
      "##清": 30429,
      "##漢": 30430,
      "##瀬": 30431,
      "##火": 30432,
      "##版": 30433,
      "##犬": 30434,
      "##王": 30435,
      "##生": 30436,
      "##田": 30437,
      "##男": 30438,
      "##疒": 30439,
      "##発": 30440,
      "##白": 30441,
      "##的": 30442,
      "##皇": 30443,
      "##目": 30444,
      "##相": 30445,
      "##省": 30446,
      "##真": 30447,
      "##石": 30448,
      "##示": 30449,
      "##社": 30450,
      "##神": 30451,
      "##福": 30452,
      "##禾": 30453,
      "##秀": 30454,
      "##秋": 30455,
      "##空": 30456,
      "##立": 30457,
      "##章": 30458,
      "##竹": 30459,
      "##糹": 30460,
      "##美": 30461,
      "##義": 30462,
      "##耳": 30463,
      "##良": 30464,
      "##艹": 30465,
      "##花": 30466,
      "##英": 30467,
      "##華": 30468,
      "##葉": 30469,
      "##藤": 30470,
      "##行": 30471,
      "##街": 30472,
      "##西": 30473,
      "##見": 30474,
      "##訁": 30475,
      "##語": 30476,
      "##谷": 30477,
      "##貝": 30478,
      "##貴": 30479,
      "##車": 30480,
      "##軍": 30481,
      "##辶": 30482,
      "##道": 30483,
      "##郎": 30484,
      "##郡": 30485,
      "##部": 30486,
      "##都": 30487,
      "##里": 30488,
      "##野": 30489,
      "##金": 30490,
      "##鈴": 30491,
      "##镇": 30492,
      "##長": 30493,
      "##門": 30494,
      "##間": 30495,
      "##阝": 30496,
      "##阿": 30497,
      "##陳": 30498,
      "##陽": 30499,
      "##雄": 30500,
      "##青": 30501,
      "##面": 30502,
      "##風": 30503,
      "##食": 30504,
      "##香": 30505,
      "##馬": 30506,
      "##高": 30507,
      "##龍": 30508,
      "##龸": 30509,
      "##ﬁ": 30510,
      "##ﬂ": 30511,
      "##！": 30512,
      "##（": 30513,
      "##）": 30514,
      "##，": 30515,
      "##－": 30516,
      "##．": 30517,
      "##／": 30518,
      "##：": 30519,
      "##？": 30520,
      "##～": 30521
    }
  }
}

---

### Spring Ai Client Chat/Src/Test/Resources/Bikes.Json (spring-ai-client-chat/src/test/resources/bikes.json)

[
  {
    "name": "E-Adrenaline 8.0 EX1",
    "shortDescription": "a versatile and comfortable e-MTB designed for adrenaline enthusiasts who want to explore all types of terrain. It features a powerful motor and advanced suspension to provide a smooth and responsive ride, with a variety of customizable settings to fit any rider's needs.",
    "description": "## Overview\r\nIt's right for you if...\r\nYou want to push your limits on challenging trails and terrain, with the added benefit of an electric assist to help you conquer steep climbs and rough terrain. You also want a bike with a comfortable and customizable fit, loaded with high-quality components and technology.\r\n\r\nThe tech you get\r\nA lightweight, full ADV Mountain Carbon frame with a customizable geometry, including an adjustable head tube and chainstay length. A powerful and efficient motor with a 375Wh battery that can assist up to 28 mph when it's on, and provides a smooth and seamless transition when it's off. A SRAM EX1 8-speed drivetrain, a RockShox Lyrik Ultimate fork, and a RockShox Super Deluxe Ultimate rear shock.\r\n\r\nThe final word\r\nOur E-Adrenaline 8.0 EX1 is the perfect bike for adrenaline enthusiasts who want to explore all types of terrain. It's versatile, comfortable, and loaded with advanced technology to provide a smooth and responsive ride, no matter where your adventures take you.\r\n\r\n\r\n## Features\r\nVersatile and customizable\r\nThe E-Adrenaline 8.0 EX1 features a customizable geometry, including an adjustable head tube and chainstay length, so you can fine-tune your ride to fit your needs and preferences. It also features a variety of customizable settings, including suspension tuning, motor assistance levels, and more.\r\n\r\nPowerful and efficient\r\nThe bike is equipped with a powerful and efficient motor that provides a smooth and seamless transition between human power and electric assist. It can assist up to 28 mph when it's on, and provides zero drag when it's off.\r\n\r\nAdvanced suspension\r\nThe E-Adrenaline 8.0 EX1 features a RockShox Lyrik Ultimate fork and a RockShox Super Deluxe Ultimate rear shock, providing advanced suspension technology to absorb shocks and bumps on any terrain. The suspension is also customizable to fit your riding style and preferences.\r\n\r\n\r\n## Specs\r\nFrameset\r\nFrame ADV Mountain Carbon main frame & stays, adjustable head tube and chainstay length, tapered head tube, Knock Block, Control Freak internal routing, Boost148, 150mm travel\r\nFork RockShox Lyrik Ultimate, DebonAir spring, Charger 2.1 RC2 damper, remote lockout, tapered steerer, 42mm offset, Boost110, 15mm Maxle Stealth, 160mm travel\r\nShock RockShox Super Deluxe Ultimate, DebonAir spring, Thru Shaft 3-position damper, 230x57.5mm\r\n\r\nWheels\r\nWheel front Bontrager Line Elite 30, ADV Mountain Carbon, Tubeless Ready, 6-bolt, Boost110, 15mm thru axle\r\nWheel rear Bontrager Line Elite 30, ADV Mountain Carbon, Tubeless Ready, 54T Rapid Drive, 6-bolt, Shimano MicroSpline freehub, Boost148, 12mm thru axle\r\nSkewer rear Bontrager Switch thru axle, removable lever\r\nTire Bontrager XR5 Team Issue, Tubeless Ready, Inner Strength sidewall, aramid bead, 120tpi, 29x2.50''\r\nTire part Bontrager TLR sealant, 6oz\r\n\r\nDrivetrain\r\nShifter SRAM EX1, 8 speed\r\nRear derailleur SRAM EX1, 8 speed\r\nCrank Bosch Performance CX, magnesium motor body, 250 watt, 75 Nm torque\r\nChainring SRAM EX1, 18T, steel\r\nCassette SRAM EX1, 11-48, 8 speed\r\nChain SRAM EX1, 8 speed\r\n\r\nComponents\r\nSaddle Bontrager Arvada, hollow chromoly rails, 138mm width\r\nSeatpost Bontrager Line Elite Dropper, internal routing, 31.6mm\r\nHandlebar Bontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\r\nGrips Bontrager XR Trail Elite, alloy lock-on\r\nStem Bontrager Line Pro, 35mm, Knock Block, Blendr compatible, 0 degree, 50mm length\r\nHeadset Knock Block Integrated, 62-degree radius, cartridge bearing, 1-1\/8'' top, 1.5'' bottom\r\nBrake SRAM G2 RSC hydraulic disc, carbon levers\r\nBrake rotor SRAM Centerline, centerlock, round edge, 200mm\r\n\r\nAccessories\r\nE-bike system Bosch Performance CX, magnesium motor body, 250 watt, 75 Nm torque\r\nBattery Bosch PowerTube 625, 625Wh\r\nCharger Bosch 4A standard charger\r\nController Bosch Kiox with Anti-theft solution, Bluetooth connectivity, 1.9'' display\r\nTool Bontrager Switch thru axle, removable lever\r\n\r\nWeight\r\nWeight M - 20.25 kg \/ 44.6 lbs (with TLR sealant, no tubes)\r\nWeight limit This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\r\n\r\n## Sizing & fit\r\n\r\n| Size |       Rider Height       |        Inseam        |\r\n|:----:|:------------------------:|:--------------------:|\r\n|   S  | 155 - 170 cm 5'1\" - 5'7\" | 73 - 80 cm 29\" - 31.5\" |\r\n|   M  | 163 - 178 cm 5'4\" - 5'10\" | 77 - 83 cm 30.5\" - 32.5\" |\r\n|   L  | 176 - 191 cm 5'9\" - 6'3\" | 83 - 89 cm 32.5\" - 35\" |\r\n|  XL  | 188 - 198 cm 6'2\" - 6'6\" | 88 - 93 cm 34.5\" - 36.5\" |\r\n\r\n\r\n## Geometry\r\n\r\nAll measurements provided in cm unless otherwise noted.\r\nSizing table\r\n| Frame size letter         | S     | M     | L     | XL    |\r\n|---------------------------|-------|-------|-------|-------|\r\n| Actual frame size         | 15.8  | 17.8  | 19.8  | 21.8  |\r\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\r\n| A \u2014 Seat tube             | 40.0  | 42.5  | 47.5  | 51.0  |\r\n| B \u2014 Seat tube angle       | 72.5\u00B0 | 72.8\u00B0 | 73.0\u00B0 | 73.0\u00B0 |\r\n| C \u2014 Head tube length      | 9.5   | 10.5  | 11.0  | 11.5  |\r\n| D \u2014 Head angle            | 67.8\u00B0 | 67.8\u00B0 | 67.8\u00B0 | 67.8\u00B0 |\r\n| E \u2014 Effective top tube    | 59.0  | 62.0  | 65.0  | 68.0  |\r\n| F \u2014 Bottom bracket height | 32.5  | 32.5  | 32.5  | 32.5  |\r\n| G \u2014 Bottom bracket drop   | 5.5   | 5.5   | 5.5   | 5.5   |\r\n| H \u2014 Chainstay length      | 45.0  | 45.0  | 45.0  | 45.0  |\r\n| I \u2014 Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\r\n| J \u2014 Trail                 | 11.0  | 11.0  | 11.0  | 11.0  |\r\n| K \u2014 Wheelbase             | 113.0 | 117.0 | 120.0 | 123.0 |\r\n| L \u2014 Standover             | 77.0  | 77.0  | 77.0  | 77.0  |\r\n| M \u2014 Frame reach           | 41.0  | 44.5  | 47.5  | 50.0  |\r\n| N \u2014 Frame stack           | 61.0  | 62.0  | 62.5  | 63.0  |",
    "price": 1499.99,
    "tags": [
      "bicycle"
    ]
  },
  {
    "name": "Enduro X Pro",
    "shortDescription": "The Enduro X Pro is the ultimate mountain bike for riders who demand the best. With its full carbon frame and top-of-the-line components, this bike is ready to tackle any trail, from technical downhill descents to grueling uphill climbs.",
    "text": "## Overview\nIt's right for you if...\nYou're an experienced mountain biker who wants a high-performance bike that can handle any terrain. You want a bike with the best components available, including a full carbon frame, suspension system, and hydraulic disc brakes.\n\nThe tech you get\nOur top-of-the-line full carbon frame with aggressive geometry and a slack head angle for maximum control. It's equipped with a Fox Factory suspension system with 170mm of travel in the front and 160mm in the rear, a Shimano XTR 12-speed drivetrain, and hydraulic disc brakes for maximum stopping power. The bike also features a dropper seatpost for easy adjustments on the fly.\n\nThe final word\nThe Enduro X Pro is the ultimate mountain bike for riders who demand the best. With its full carbon frame, top-of-the-line components, and aggressive geometry, this bike is ready to take on any trail. Whether you're a seasoned pro or just starting out, the Enduro X Pro will help you take your riding to the next level.\n\n## Features\nFull carbon frame\nAggressive geometry with a slack head angle\nFox Factory suspension system with 170mm of travel in the front and 160mm in the rear\nShimano XTR 12-speed drivetrain\nHydraulic disc brakes for maximum stopping power\nDropper seatpost for easy adjustments on the fly\n\n## Specifications\nFrameset\nFrame\tFull carbon frame\nFork\tFox Factory suspension system with 170mm of travel\nRear suspension\tFox Factory suspension system with 160mm of travel\n\nWheels\nWheel size\t27.5\" or 29\"\nTires\tTubeless-ready Maxxis tires\n\nDrivetrain\nShifters\tShimano XTR 12-speed\nFront derailleur\tN/A\nRear derailleur\tShimano XTR\nCrankset\tShimano XTR\nCassette\tShimano XTR 12-speed\nChain\tShimano XTR\n\nComponents\nBrakes\tHydraulic disc brakes\nHandlebar\tAlloy handlebar\nStem\tAlloy stem\nSeatpost\tDropper seatpost\n\nAccessories\nPedals\tNot included\n\nWeight\nWeight\tApproximately 27-29 lbs\n\n## Sizing\n| Size |        Rider Height       |\n|:----:|:-------------------------:|\n|  S  |  5'4\" - 5'8\" (162-172cm) |\n|  M  |  5'8\" - 5'11\" (172-180cm) |\n|  L  |  5'11\" - 6'3\" (180-191cm) |\n|  XL |  6'3\" - 6'6\" (191-198cm) |\n\n## Geometry\n| Size |        S        |        M       |        L         |        XL       |\n|:----:|:---------------:|:---------------:|:-----------------:|:---------------:|\n| A - Seat tube length |   390mm   |   425mm   |     460mm     |    495mm   |\n| B - Effective top tube length |  585mm  |  610mm  |    635mm     |  660mm |\n| C - Head tube angle |  65.5°  |  65.5°  |  65.5°  |  65.5°  |\n| D - Seat tube angle |  76°  |  76°  |  76°  |  76°  |\n| E - Chainstay length |  435mm  |  435mm  |  435mm  |  435mm  |\n| F - Head tube length |  100mm  |  110mm  |  120mm  |  130mm  |\n| G - BB drop |  20mm  |  20mm  |  20mm  |  20mm  |\n| H - Wheelbase |  1155mm  |  1180mm  |  1205mm  |  1230mm  |\n| I - Standover height |  780mm  |  800mm  |  820mm  |  840mm  |\n| J - Reach |  425mm  |  450mm  |  475mm  |  500mm  |\n| K - Stack |  610mm  |  620mm  |  630mm  |  640mm  |",
    "price": 599.99,
    "tags": [
      "bicycle"
    ]
  },
  {
    "name": "Blaze X1",
    "shortDescription": "Blaze X1 is a high-performance road bike that offers superior speed and agility, making it perfect for competitive racing or fast-paced group rides. The bike features a lightweight carbon frame, aerodynamic tube shapes, a 12-speed Shimano Ultegra drivetrain, and hydraulic disc brakes for precise stopping power. With its sleek design and cutting-edge technology, Blaze X1 is a bike that is built to perform and dominate on any road.",
    "description": "## Overview\nIt's right for you if...\nYou're a competitive road cyclist or an enthusiast who enjoys fast-paced group rides. You want a bike that is lightweight, agile, and delivers exceptional speed.\n\nThe tech you get\nBlaze X1 features a lightweight carbon frame with a tapered head tube and aerodynamic tube shapes for maximum speed and efficiency. The bike is equipped with a 12-speed Shimano Ultegra drivetrain for smooth and precise shifting, Shimano hydraulic disc brakes for powerful and reliable stopping power, and Bontrager Aeolus Elite 35 carbon wheels for increased speed and agility.\n\nThe final word\nBlaze X1 is a high-performance road bike that is designed to deliver exceptional speed and agility. With its cutting-edge technology and top-of-the-line components, it's a bike that is built to perform and dominate on any road.\n\n## Features\nSpeed and efficiency\nBlaze X1's lightweight carbon frame and aerodynamic tube shapes offer maximum speed and efficiency, allowing you to ride faster and farther with ease.\n\nPrecision stopping power\nShimano hydraulic disc brakes provide precise and reliable stopping power, even in wet or muddy conditions.\n\nAgility and control\nBontrager Aeolus Elite 35 carbon wheels make Blaze X1 incredibly agile and responsive, allowing you to navigate tight turns and corners with ease.\n\nSmooth and precise shifting\nThe 12-speed Shimano Ultegra drivetrain offers smooth and precise shifting, so you can easily find the right gear for any terrain.\n\n## Specifications\nFrameset\nFrame\tADV Carbon, tapered head tube, BB90, direct mount rim brakes, internal cable routing, DuoTrap S compatible, 130x9mm QR\nFork\tADV Carbon, tapered steerer, direct mount rim brakes, internal brake routing, 100x9mm QR\n\nWheels\nWheel front\tBontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, 100x9mm QR\nWheel rear\tBontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, Shimano 11-speed freehub, 130x9mm QR\nTire front\tBontrager R3 Hard-Case Lite, aramid bead, 120 tpi, 700x25c\nTire rear\tBontrager R3 Hard-Case Lite, aramid bead, 120 tpi, 700x25c\nMax tire size\t25c Bontrager tires (with at least 4mm of clearance to frame)\n\nDrivetrain\nShifter\tShimano Ultegra R8020, 12 speed\nFront derailleur\tShimano Ultegra R8000, braze-on\nRear derailleur\tShimano Ultegra R8000, short cage, 30T max cog\nCrank\tSize: 50, 52, 54\nShimano Ultegra R8000, 50/34 (compact), 170mm length\nSize: 56, 58, 60, 62\nShimano Ultegra R8000, 50/34 (compact), 172.5mm length\nBottom bracket\tBB90, Shimano press-fit\nCassette\tShimano Ultegra R8000, 11-30, 12 speed\nChain\tShimano Ultegra HG701, 12 speed\n\nComponents\nSaddle\tBontrager Montrose Elite, titanium rails, 138mm width\nSeatpost\tBontrager carbon seatmast cap, 20mm offset\nHandlebar\tBontrager Elite Aero VR-CF, alloy, 31.8mm, internal cable routing, 40cm width\nGrips\tBontrager Supertack Perf tape\nStem\tBontrager Elite, 31.8mm, Blendr-compatible, 7 degree, 80mm length\nBrake Shimano Ultegra hydraulic disc brake\n\nWeight\nWeight\t56 - 8.91 kg / 19.63 lbs (with tubes)\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size | Rider height |\n|------|-------------|\n| 50   | 162-166cm   |\n| 52   | 165-170cm   |\n| 54   | 168-174cm   |\n| 56   | 174-180cm   |\n| 58   | 179-184cm   |\n| 60   | 184-189cm   |\n| 62   | 189-196cm   |\n\n## Geometry\n| Frame size | 50cm | 52cm | 54cm | 56cm | 58cm | 60cm | 62cm |\n|------------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A - Seat tube | 443mm | 460mm | 478mm | 500mm | 520mm | 540mm | 560mm |\n| B - Seat tube angle | 74.1° | 73.9° | 73.7° | 73.4° | 73.2° | 73.0° | 72.8° |\n| C - Head tube length | 100mm | 110mm | 130mm | 150mm | 170mm | 190mm | 210mm |\n| D - Head angle | 71.4° | 72.0° | 72.5° | 73.0° | 73.3° | 73.6° | 73.8° |\n| E - Effective top tube | 522mm | 535mm | 547mm | 562mm | 577mm | 593mm | 610mm |\n| F - Bottom bracket height | 268mm | 268mm | 268mm | 268mm | 268mm | 268mm | 268mm |\n| G - Bottom bracket drop | 69mm | 69mm | 69mm | 69mm | 69mm | 69mm | 69mm |\n| H - Chainstay length | 410mm | 410mm | 410mm | 410mm | 410mm | 410mm | 410mm |\n| I - Offset | 50mm | 50mm | 50mm | 50mm | 50mm | 50mm | 50mm |\n| J - Trail | 65mm | 62mm | 59mm | 56mm | 55mm | 53mm | 52mm |\n| K - Wheelbase | 983mm | 983mm | 990mm | 1005mm | 1019mm | 1036mm | 1055mm |\n| L - Standover | 741mm | 765mm | 787mm | 806mm | 825mm | 847mm | 869mm |",
    "price": 799.99,
    "tags": [
      "bicycle",
      "mountain bike"
    ]
  },
  {
    "name": "Celerity X5",
    "shortDescription": "Celerity X5 is a versatile and reliable road bike that is designed for experienced and amateur riders alike. It's designed to provide smooth and comfortable rides over long distances. With an ultra-lightweight and responsive carbon fiber frame, Shimano 105 groupset, hydraulic disc brakes, and 28mm wide tires, this bike ensures efficient power transfer, precise handling, and superior stopping power.",
    "description": "## Overview\n\nIt's right for you if...    \nYou are looking for a high-performance road bike that offers a perfect balance of speed, comfort, and control. You enjoy long-distance rides and need a bike that is designed to handle various road conditions with ease. You also appreciate the latest technology and reliable components that make your riding experience more enjoyable.\n\nThe tech you get    \nCelerity X5 is equipped with a full carbon fiber frame that ensures maximum strength and durability while keeping the weight down. It features a Shimano 105 groupset with 11-speed gearing for precise and efficient shifting. Hydraulic disc brakes offer superior stopping power, and 28mm wide tires provide comfort and stability on various road surfaces. Internal cable routing enhances the bike's sleek appearance.\n\nThe final word    \nIf you are looking for a high-performance road bike that offers comfort, speed, and control, Celerity X5 is the perfect choice. With its lightweight carbon fiber frame, reliable components, and advanced technology, this bike is designed to help you enjoy long-distance rides with ease.\n\n## Features    \n\nLightweight and responsive    \nCelerity X5 comes with a full carbon fiber frame that is not only lightweight but also responsive, providing excellent handling and control.\n\nHydraulic disc brakes    \nThis bike is equipped with hydraulic disc brakes that provide superior stopping power in all weather conditions, ensuring your safety and confidence on the road.\n\nComfortable rides    \nThe 28mm wide tires and carbon seat post provide ample cushioning, ensuring a smooth and comfortable ride over long distances.\n\nSleek appearance    \nThe bike's internal cable routing enhances its sleek appearance while also protecting the cables from the elements, ensuring smooth shifting for longer periods.\n\n## Specifications    \n\nFrameset    \nFrame\tCelerity X5 Full Carbon Fiber Frame, Internal Cable Routing, Tapered Headtube, Press Fit Bottom Bracket, 12x142mm Thru-Axle    \nFork\tCelerity X5 Full Carbon Fiber Fork, Internal Brake Routing, 12x100mm Thru-Axle    \n\nWheels    \nWheelset\tAlexRims CXD7 Wheelset    \nTire\tSchwalbe Durano Plus 700x28mm    \nInner Tubes\tSchwalbe SV15 700x18-28mm    \nSkewers\tCelerity X5 Thru-Axle Skewers    \n\nDrivetrain    \nShifter\tShimano 105 R7025 Hydraulic Disc Shifters    \nFront Derailleur\tShimano 105 R7000    \nRear Derailleur\tShimano 105 R7000    \nCrankset\tShimano 105 R7000 50-34T    \nBottom Bracket\tShimano BB72-41B    \nCassette\tShimano 105 R7000 11-30T    \nChain\tShimano HG601 11-Speed Chain    \n\nComponents    \nSaddle\tSelle Royal Asphalt Saddle    \nSeatpost\tCelerity X5 Carbon Seatpost    \nHandlebar\tCelerity X5 Compact Handlebar    \nStem\tCelerity X5 Aluminum Stem    \nHeadset\tFSA Orbit IS-2    \n\nBrakes    \nBrakes\tShimano 105 R7025 Hydraulic Disc Brakes    \nRotors\tShimano SM-RT70 160mm Rotors    \n\nAccessories    \nPedals\tCelerity X5 Road Pedals    \n\nWeight    \nWeight\t8.2 kg / 18.1 lbs    \nWeight Limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 120 kg (265 lbs).\n\n## Sizing    \n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  49  |  155 - 162 cm 5'1\" - 5'4\" | 71 - 76 cm 28\" - 30\" |\n|  52  |  162 - 170 cm 5'4\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|  54  |  170 - 178 cm 5'7\" - 5'10\" | 77 - 83 cm 30\" - 32\" |\n|  56  |  178 - 185 cm 5'10\" - 6'1\" | 82 - 88 cm 32\" - 34\" |\n|  58  |  185 - 193 cm 6'1\" - 6'4\" | 86 - 92 cm 34\" - 36\" |\n|  61  |  193 - 200 cm 6'4\" - 6'7\" | 90 - 95 cm 35\" - 37\" |\n\n## Geometry    \n| Frame size number                     | 49 cm | 52 cm | 54 cm | 56 cm | 58 cm | 61 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 47.5  | 50.0  | 52.0  | 54.0  | 56.0  | 58.5  |\n| B — Seat tube angle                   | 75.0° | 74.5° | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length                  | 12.0  | 14.5  | 16.5  | 18.5  | 20.5  | 23.5  |\n| D — Head angle                        | 70.0° | 71.0° | 71.5° | 72.0° | 72.5° | 72.5° |\n| E — Effective top tube                | 52.5  | 53.5  | 54.5  | 56.0  | 57.5  | 59.5  |\n| G — Bottom bracket drop               | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length                  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  |\n| K — Wheelbase                         | 98.4  | 98.9  | 99.8  | 100.8 | 101.7 | 103.6 |\n| L — Standover                         | 72.0  | 74.0  | 76.0  | 78.0  | 80.0  | 82.0  |\n| M — Frame reach                       | 36.2  | 36.8  | 37.3  | 38.1  | 38.6  | 39.4  |\n| N — Frame stack                       | 52.0  | 54.3  | 56.2  | 58.1  | 59.8  | 62.4  |\n| Saddle rail height min                | 67.0  | 69.5  | 71.5  | 74.0  | 76.0  | 78.0  |\n| Saddle rail height max                | 75.0  | 77.5  | 79.5  | 82.0  | 84.0  | 86.0  |",
    "price": 399.99,
    "tags": [
      "bicycle",
      "city bike"
    ]
  },
  {
    "name": "Velocity V8",
    "shortDescription": "Velocity V8 is a high-performance road bike that is designed to deliver speed, agility, and control on the road. With its lightweight aluminum frame, carbon fiber fork, Shimano Tiagra groupset, and hydraulic disc brakes, this bike is perfect for experienced riders who are looking for a fast and responsive bike that can handle various road conditions.",
    "description": "## Overview\n\nIt's right for you if...    \nYou are an experienced rider who is looking for a high-performance road bike that is lightweight, agile, and responsive. You want a bike that can handle long-distance rides, steep climbs, and fast descents with ease. You also appreciate the latest technology and reliable components that make your riding experience more enjoyable.\n\nThe tech you get    \nVelocity V8 features a lightweight aluminum frame with a carbon fiber fork that ensures a comfortable ride without sacrificing stiffness and power transfer. It comes with a Shimano Tiagra groupset with 10-speed gearing for precise and efficient shifting. Hydraulic disc brakes offer superior stopping power in all weather conditions, while 28mm wide tires provide comfort and stability on various road surfaces. Internal cable routing enhances the bike's sleek appearance.\n\nThe final word    \nIf you are looking for a high-performance road bike that is lightweight, fast, and responsive, Velocity V8 is the perfect choice. With its lightweight aluminum frame, reliable components, and advanced technology, this bike is designed to help you enjoy fast and comfortable rides on the road.\n\n## Features    \n\nLightweight and responsive    \nVelocity V8 comes with a lightweight aluminum frame that is not only lightweight but also responsive, providing excellent handling and control.\n\nHydraulic disc brakes    \nThis bike is equipped with hydraulic disc brakes that provide superior stopping power in all weather conditions, ensuring your safety and confidence on the road.\n\nComfortable rides    \nThe 28mm wide tires and carbon fork provide ample cushioning, ensuring a smooth and comfortable ride over long distances.\n\nSleek appearance    \nThe bike's internal cable routing enhances its sleek appearance while also protecting the cables from the elements, ensuring smooth shifting for longer periods.\n\n## Specifications    \n\nFrameset    \nFrame\tVelocity V8 Aluminum Frame, Internal Cable Routing, Tapered Headtube, Press Fit Bottom Bracket, 12x142mm Thru-Axle    \nFork\tVelocity V8 Carbon Fiber Fork, Internal Brake Routing, 12x100mm Thru-Axle    \n\nWheels    \nWheelset\tAlexRims CXD7 Wheelset    \nTire\tSchwalbe Durano Plus 700x28mm    \nInner Tubes\tSchwalbe SV15 700x18-28mm    \nSkewers\tVelocity V8 Thru-Axle Skewers    \n\nDrivetrain    \nShifter\tShimano Tiagra Hydraulic Disc Shifters    \nFront Derailleur\tShimano Tiagra    \nRear Derailleur\tShimano Tiagra    \nCrankset\tShimano Tiagra 50-34T    \nBottom Bracket\tShimano BB-RS500-PB    \nCassette\tShimano Tiagra 11-32T    \nChain\tShimano HG54 10-Speed Chain    \n\nComponents    \nSaddle\tVelocity V8 Saddle    \nSeatpost\tVelocity V8 Aluminum Seatpost    \nHandlebar\tVelocity V8 Compact Handlebar    \nStem\tVelocity V8 Aluminum Stem    \nHeadset\tFSA Orbit IS-2    \n\nBrakes    \nBrakes\tShimano Tiagra Hydraulic Disc Brakes    \nRotors\tShimano SM-RT64 160mm Rotors    \n\nAccessories    \nPedals\tVelocity V8 Road Pedals    \n\nWeight    \nWeight\t9.4 kg / 20.7 lbs    \nWeight Limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 120 kg (265 lbs).\n\n## Sizing    \n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  49  |  155 - 162 cm 5'1\" - 5'4\" | 71 - 76 cm 28\" - 30\" |\n|  52  |  162 - 170 cm 5'4\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|  54  |  170 - 178 cm 5'7\" - 5'10\" | 77 - 83 cm 30\" - 32\" |\n|  56  |  178 - 185 cm 5'10\" - 6'1\" | 82 - 88 cm 32\" - 34\" |\n|  58  |  185 - 193 cm 6'1\" - 6'4\" | 86 - 92 cm 34\" - 36\" |\n|  61  |  193 - 200 cm 6'4\" - 6'7\" | 90 - 95 cm 35\" - 37\" |\n\n## Geometry    \n| Frame size number                     | 49 cm | 52 cm | 54 cm | 56 cm | 58 cm | 61 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 47.5  | 50.0  | 52.0  | 54.0  | 56.0  | 58.5  |\n| B — Seat tube angle                   | 75.0° | 74.5° | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length                  | 12.0  | 14.5  | 16.5  | 18.5  | 20.5  | 23.5  |\n| D — Head angle                        | 70.0° | 71.0° | 71.5° | 72.0° | 72.5° | 72.5° |\n| E — Effective top tube                | 52.5  | 53.5  | 54.5  | 56.0  | 57.5  | 59.5  |\n| G — Bottom bracket drop               | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length                  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  |\n| K — Wheelbase                         | 98.4  | 98.9  | 99.8  | 100.8 | 101.7 | 103.6 |\n| L — Standover                         | 72.0  | 74.0  | 76.0  | 78.0  | 80.0  | 82.0  |\n| M — Frame reach                       | 36.2  | 36.8  | 37.3  | 38.1  | 38.6  | 39.4  |\n| N — Frame stack                       | 52.0  | 54.3  | 56.2  | 58.1  | 59.8  | 62.4  |\n| Saddle rail height min                | 67.0  | 69.5  | 71.5  | 74.0  | 76.0  | 78.0  |\n| Saddle rail height max                | 75.0  | 77.5  | 79.5  | 82.0  | 84.0  | 86.0  |",
    "price": 1899.99,
    "tags": [
      "bicycle",
      "electric bike"
    ]
  },
  {
    "name": "VeloCore X9 eMTB",
    "shortDescription": "The VeloCore X9 eMTB is a light, agile and versatile electric mountain bike designed for adventure and performance. Its purpose-built frame and premium components offer an exhilarating ride experience on both technical terrain and smooth singletrack.",
    "description": "## Overview\nIt's right for you if...\nYou love exploring new trails and testing your limits on challenging terrain. You want an electric mountain bike that offers power when you need it, without sacrificing performance or agility. You're looking for a high-quality bike with top-notch components and a sleek design.\n\nThe tech you get\nA lightweight, full carbon frame with custom geometry, a 140mm RockShox Pike Ultimate fork with Charger 2.1 damper, and a Fox Float DPS Performance shock. A Shimano STEPS E8000 motor and 504Wh battery that provide up to 62 miles of range and 20 mph assistance. A Shimano XT 12-speed drivetrain, Shimano SLX brakes, and DT Swiss wheels.\n\nThe final word\nThe VeloCore X9 eMTB delivers power and agility in equal measure. It's a versatile and capable electric mountain bike that can handle any trail with ease. With premium components, a custom carbon frame, and a sleek design, this bike is built for adventure.\n\n## Features\nAgile and responsive\n\nThe VeloCore X9 eMTB is designed to be nimble and responsive on the trail. Its custom carbon frame offers a perfect balance of stiffness and compliance, while the suspension system provides smooth and stable performance on technical terrain.\n\nPowerful and efficient\n\nThe Shimano STEPS E8000 motor and 504Wh battery provide up to 62 miles of range and 20 mph assistance. The motor delivers smooth and powerful performance, while the battery offers reliable and consistent power for long rides.\n\nCustomizable ride experience\n\nThe VeloCore X9 eMTB comes with an intuitive and customizable Shimano STEPS display that allows you to adjust the level of assistance, monitor your speed and battery life, and customize your ride experience to suit your needs.\n\nPremium components\n\nThe VeloCore X9 eMTB is equipped with high-end components, including a Shimano XT 12-speed drivetrain, Shimano SLX brakes, and DT Swiss wheels. These components offer reliable and precise performance, allowing you to push your limits with confidence.\n\n## Specs\nFrameset\nFrame\tVeloCore carbon fiber frame, Boost, tapered head tube, internal cable routing, 140mm travel\nFork\tRockShox Pike Ultimate, Charger 2.1 damper, DebonAir spring, 15x110mm Boost Maxle Ultimate, 46mm offset, 140mm travel\nShock\tFox Float DPS Performance, EVOL, 3-position adjust, Kashima Coat, 210x50mm\n\nWheels\nWheel front\tDT Swiss XM1700 Spline, 30mm internal width, 15x110mm Boost axle\nWheel rear\tDT Swiss XM1700 Spline, 30mm internal width, Shimano Microspline driver, 12x148mm Boost axle\nTire front\tMaxxis Minion DHF, 29x2.5\", EXO+ casing, tubeless ready\nTire rear\tMaxxis Minion DHR II, 29x2.4\", EXO+ casing, tubeless ready\n\nDrivetrain\nShifter\tShimano XT M8100, 12-speed\nRear derailleur\tShimano XT M8100, Shadow Plus, long cage, 51T max cog\nCrankset\tShimano STEPS E8000, 165mm length, 34T chainring\nCassette\tShimano XT M8100, 10-51T, 12-speed\nChain\tShimano CN-M8100, 12-speed\nPedals\tNot included\n\nComponents\nSaddle\tBontrager Arvada, hollow chromoly rails\nSeatpost\tDrop Line, internal routing, 31.6mm (15.5: 100mm, 17.5 & 18.5: 125mm, 19.5 & 21.5: 150mm)\nHandlebar\tBontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\nStem\tBontrager Line Pro, 35mm, Knock Block, 0 degree, 50mm length\nGrips\tBontrager XR Trail Elite, alloy lock-on\nHeadset\tIntegrated, sealed cartridge bearing, 1-1/8\" top, 1.5\" bottom\nBrakeset\tShimano SLX M7120, 4-piston hydraulic disc\n\nAccessories\nBattery\tShimano STEPS BT-E8010, 504Wh\nCharger\tShimano STEPS EC-E8004, 4A\nController\tShimano STEPS E8000 display\nBike weight\tM - 22.5 kg / 49.6 lbs (with tubes)\n\n## Sizing & fit\n\n| Size |       Rider Height       |\n|:----:|:------------------------:|\n|   S  | 162 - 170 cm 5'4\" - 5'7\" |\n|   M  | 170 - 178 cm 5'7\" - 5'10\"|\n|   L  | 178 - 186 cm 5'10\" - 6'1\"|\n|  XL  | 186 - 196 cm 6'1\" - 6'5\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\n| Frame size         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| A — Seat tube             | 40.6  | 43.2  | 47.0  | 51.0  |\n| B — Seat tube angle       | 75.0° | 75.0° | 75.0° | 75.0° |\n| C — Head tube length      | 9.6   | 10.6  | 11.6  | 12.6  |\n| D — Head angle            | 66.5° | 66.5° | 66.5° | 66.5° |\n| E — Effective top tube    | 60.4  | 62.6  | 64.8  | 66.9  |\n| F — Bottom bracket height | 33.2  | 33.2  | 33.2  | 33.2  |\n| G — Bottom bracket drop   | 3.0   | 3.0   | 3.0   | 3.0   |\n| H — Chainstay length      | 45.5  | 45.5  | 45.5  | 45.5  |\n| I — Offset                | 4.6   | 4.6   | 4.6   | 4.6   |\n| J — Trail                 | 11.9  | 11.9  | 11.9  | 11.9  |\n| K — Wheelbase             | 117.0 | 119.3 | 121.6 | 123.9 |\n| L — Standover             | 75.9  | 75.9  | 78.6  | 78.6  |\n| M — Frame reach           | 43.6  | 45.6  | 47.6  | 49.6  |\n| N — Frame stack           | 60.5  | 61.5  | 62.4  | 63.4  |",
    "price": 1299.99,
    "tags": [
      "bicycle",
      "touring bike"
    ]
  },
  {
    "name": "Zephyr 8.8 GX Eagle AXS Gen 3",
    "shortDescription": "Zephyr 8.8 GX Eagle AXS is a light and nimble full-suspension mountain bike. It's designed to handle technical terrain with ease and has a smooth and efficient ride feel. The sleek and powerful Bosch Performance Line CX motor and removable Powertube battery provide a boost to your pedaling and give you long-lasting riding time. The bike also features high-end components and advanced technology for an ultimate mountain biking experience.",
    "description": "## Overview\nIt's right for you if...\nYou're an avid mountain biker looking for a high-performance e-MTB that can tackle challenging trails. You want a bike with a powerful motor, efficient suspension, and advanced technology to enhance your riding experience. You also need a bike that's reliable and durable for long-lasting use.\n\nThe tech you get\nA lightweight, full carbon frame with 150mm of rear travel and a 160mm RockShox Pike Ultimate fork with Charger 2.1 RCT3 damper, remote lockout, and DebonAir spring. A Bosch Performance Line CX motor and removable Powertube 625Wh battery that can assist up to 20mph when it's on and gives zero drag when it's off, plus an easy-to-use handlebar-mounted Bosch Purion controller. A SRAM GX Eagle AXS wireless electronic drivetrain, a RockShox Reverb Stealth dropper, and DT Swiss HX1501 Spline One wheels.\n\nThe final word\nZephyr 8.8 GX Eagle AXS is a high-performance e-MTB that's designed to handle technical terrain with ease. With a powerful Bosch motor and long-lasting battery, you can conquer challenging climbs and enjoy long rides. The bike also features high-end components and advanced technology for an ultimate mountain biking experience.\n\n## Features\nPowerful motor\n\nThe Bosch Performance Line CX motor provides a boost to your pedaling and can assist up to 20mph. It has four power modes and a walk-assist function for easy navigation on steep climbs. The motor is also reliable and durable for long-lasting use.\n\nEfficient suspension\n\nZephyr 8.8 has a 150mm of rear travel and a 160mm RockShox Pike Ultimate fork with Charger 2.1 RCT3 damper, remote lockout, and DebonAir spring. The suspension is efficient and responsive, allowing you to handle technical terrain with ease.\n\nRemovable battery\n\nThe Powertube 625Wh battery is removable for easy charging and storage. It provides long-lasting riding time and can be replaced with a spare battery for even longer rides. The battery is also durable and weather-resistant for all-season riding.\n\nAdvanced technology\n\nZephyr 8.8 is equipped with advanced technology, including a Bosch Purion controller for easy motor control, a SRAM GX Eagle AXS wireless electronic drivetrain for precise shifting, and a RockShox Reverb Stealth dropper for adjustable saddle height. The bike also has DT Swiss HX1501 Spline One wheels for reliable performance on any terrain.\n\nCarbon frame\n\nThe full carbon frame is lightweight and durable, providing a smooth and efficient ride. It's also designed with a tapered head tube, internal cable routing, and Boost148 spacing for enhanced stiffness and responsiveness.\n\n## Specs\nFrameset\nFrame\tCarbon main frame & stays, tapered head tube, internal routing, Boost148, 150mm travel\nFork\tRockShox Pike Ultimate, Charger 2.1 RCT3 damper, DebonAir spring, remote lockout, tapered steerer, Boost110, 15mm Maxle Stealth, 160mm travel\nShock\tRockShox Deluxe RT3, DebonAir spring, 205mm x 57.5mm\nMax compatible fork travel\t170mm\n\nWheels\nWheel front\tDT Swiss HX1501 Spline One, Centerlock, 30mm inner width, 110x15mm Boost\nWheel rear\tDT Swiss HX1501 Spline One, Centerlock, 30mm inner width, SRAM XD driver, 148x12mm Boost\nTire\tBontrager XR4 Team Issue, Tubeless Ready, Inner Strength sidewall, aramid bead, 120tpi, 29x2.40''\nMax tire size\t29x2.60\"\n\nDrivetrain\nShifter\tSRAM GX Eagle AXS, wireless, 12 speed\nRear derailleur\tSRAM GX Eagle AXS\nCrank\tBosch Gen 4, 32T\nChainring\tSRAM X-Sync 2, 32T, direct-mount\nCassette\tSRAM PG-1275 Eagle, 10-52, 12 speed\nChain\tSRAM GX Eagle, 12 speed\n\nComponents\nSaddle\tBontrager Arvada, hollow titanium rails, 138mm width\nSeatpost\tRockShox Reverb Stealth, 31.6mm, internal routing, 150mm (S), 170mm (M/L), 200mm (XL)\nHandlebar\tBontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\nGrips\tBontrager XR Trail Elite, alloy lock-on\nStem\tBontrager Line Pro, Knock Block, 35mm, 0 degree, 50mm length\nHeadset\tIntegrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\nBrake\tSRAM Code RSC hydraulic disc, 200mm (front), 180mm (rear)\nBrake rotor\tSRAM CenterLine, centerlock, round edge, 200mm (front), 180mm (rear)\n\nAccessories\nE-bike system\tBosch Performance Line CX\nBattery\tBosch Powertube 625Wh\nCharger\tBosch 4A compact charger\nController\tBosch Purion\nTool\tBontrager multi-tool, integrated storage bag\n\nWeight\nWeight\tM - 24.08 kg / 53.07 lbs (with TLR sealant, no tubes)\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n\n## Sizing & fit\n\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 153 - 162 cm 5'0\" - 5'4\" | 67 - 74 cm 26\" - 29\" |\n|   M  | 161 - 172 cm 5'3\" - 5'8\" | 74 - 79 cm 29\" - 31\" |\n|   L  | 171 - 180 cm 5'7\" - 5'11\" | 79 - 84 cm 31\" - 33\" |\n|  XL  | 179 - 188 cm 5'10\" - 6'2\" | 84 - 89 cm 33\" - 35\" |\n\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 15.5  | 17.5  | 19.5  | 21.5  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.4  | 41.9  | 44.5  | 47.6  |\n| B — Seat tube angle       | 76.1° | 76.1° | 76.1° | 76.1° |\n| C — Head tube length      | 9.6   | 10.5  | 11.5  | 12.5  |\n| D — Head angle            | 65.5° | 65.5° | 65.5° | 65.5° |\n| E — Effective top tube    | 58.6  | 61.3  | 64.0  | 66.7  |\n| F — Bottom bracket height | 34.0  | 34.0  | 34.0  | 34.0  |\n| G — Bottom bracket drop   | 1.0   | 1.0   | 1.0   | 1.0   |\n| H — Chainstay length      | 45.0  | 45.0  | 45.0  | 45.0  |\n| I — Offset                | 4.6   | 4.6   | 4.6   | 4.6   |\n| J — Trail                 | 10.5  | 10.5  | 10.5  | 10.5  |\n| K — Wheelbase             | 119.5 | 122.3 | 125.0 | 127.8 |\n| L — Standover             | 72.7  | 74.7  | 77.6  | 81.0  |\n|",
    "price": 1499.99,
    "tags": [
      "bicycle",
      "electric bike",
      "city bike"
    ]
  },
  {
    "name": "Velo 99 XR1 AXS",
    "shortDescription": "Velo 99 XR1 AXS is a next-generation bike designed for fast-paced adventure seekers and speed enthusiasts. Built for high-performance racing, the bike boasts state-of-the-art technology and premium components. It is the ultimate bike for riders who want to push their limits and get their adrenaline pumping.",
    "description": "## Overview\nIt's right for you if...\nYou are a passionate cyclist looking for a bike that can keep up with your speed, agility, and endurance. You are an adventurer who loves to explore new terrains and challenge yourself on the toughest courses. You want a bike that is lightweight, durable, and packed with the latest technology.\n\nThe tech you get\nA lightweight, full carbon frame with advanced aerodynamics and integrated cable routing for a clean look. A high-performance SRAM XX1 Eagle AXS wireless electronic drivetrain, featuring a 12-speed cassette and a 32T chainring. A RockShox SID Ultimate fork with a remote lockout, 120mm travel, and Charger Race Day damper. A high-end SRAM G2 Ultimate hydraulic disc brake with carbon levers. A FOX Transfer SL dropper post for quick and easy height adjustments. DT Swiss XRC 1501 carbon wheels for superior speed and handling.\n\nThe final word\nVelo 99 XR1 AXS is a premium racing bike that can help you achieve your goals and reach new heights. It is designed for speed, agility, and performance, and it is packed with the latest technology and premium components. If you are a serious cyclist who wants the best, this is the bike for you.\n\n## Features\nAerodynamic design\n\nThe Velo 99 XR1 AXS features a state-of-the-art frame design that reduces drag and improves speed. It has an aerodynamic seatpost, integrated cable routing, and a sleek, streamlined look that sets it apart from other bikes.\n\nWireless electronic drivetrain\n\nThe SRAM XX1 Eagle AXS drivetrain features a wireless electronic system that provides precise, instant shifting and unmatched efficiency. It eliminates the need for cables and makes the bike lighter and faster.\n\nHigh-performance suspension\n\nThe RockShox SID Ultimate fork and Charger Race Day damper provide 120mm of smooth, responsive suspension that can handle any terrain. The fork also has a remote lockout for quick adjustments on the fly.\n\nSuperior braking power\n\nThe SRAM G2 Ultimate hydraulic disc brake system delivers unmatched stopping power and control. It has carbon levers for a lightweight, ergonomic design and precision control.\n\nCarbon wheels\n\nThe DT Swiss XRC 1501 carbon wheels are ultra-lightweight, yet incredibly strong and durable. They provide superior speed and handling, making the bike more agile and responsive.\n\n## Specs\nFrameset\nFrame\tFull carbon frame, integrated cable routing, aerodynamic design, Boost148\nFork\tRockShox SID Ultimate, Charger Race Day damper, remote lockout, tapered steerer, Boost110, 15mm Maxle Stealth, 120mm travel\n\nWheels\nWheel front\tDT Swiss XRC 1501 carbon wheel, Boost110, 15mm thru axle\nWheel rear\tDT Swiss XRC 1501 carbon wheel, SRAM XD driver, Boost148, 12mm thru axle\nTire\tSchwalbe Racing Ray, Performance Line, Addix, 29x2.25\"\nTire part\tSchwalbe Doc Blue Professional, 500ml\nMax tire size\t29x2.3\"\n\nDrivetrain\nShifter\tSRAM Eagle AXS, wireless, 12-speed\nRear derailleur\tSRAM XX1 Eagle AXS\nCrank\tSRAM XX1 Eagle, 32T, carbon\nChainring\tSRAM X-SYNC, 32T, alloy\nCassette\tSRAM Eagle XG-1299, 10-52, 12-speed\nChain\tSRAM XX1 Eagle, 12-speed\nMax chainring size\t1x: 32T\n\nComponents\nSaddle\tBontrager Montrose Elite, carbon rails, 138mm width\nSeatpost\tFOX Transfer SL, 125mm travel, internal routing, 31.6mm\nHandlebar\tBontrager Kovee Pro, ADV Carbon, 35mm, 5mm rise, 720mm width\nGrips\tBontrager XR Endurance Elite\nStem\tBontrager Kovee Pro, 35mm, Blendr compatible, 7 degree, 60mm length\nHeadset\tIntegrated, cartridge bearing, 1-1/8\" top, 1.5\" bottom\nBrake\tSRAM G2 Ultimate hydraulic disc, carbon levers, 180mm rotors\n\nAccessories\nBike computer\tBontrager Trip 300\nTool\tBontrager Flatline Pro pedal wrench, T25 Torx\n\n\n## Sizing & fit\n\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 158 - 168 cm 5'2\" - 5'6\" | 74 - 78 cm 29\" - 31\" |\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 78 - 82 cm 31\" - 32\" |\n|   L  | 173 - 183 cm 5'8\" - 6'0\" | 82 - 86 cm 32\" - 34\" |\n|  XL  | 180 - 193 cm 5'11\" - 6'4\" | 86 - 90 cm 34\" - 35\" |\n\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 15.5  | 17.5  | 19.5  | 21.5  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.9  | 43.0  | 47.0  | 51.0  |\n| B — Seat tube angle       | 74.5° | 74.5° | 74.5° | 74.5° |\n| C — Head tube length      | 9.0   | 10.0  | 11.0  | 12.0  |\n| D — Head angle            | 68.0° | 68.0° | 68.0° | 68.0° |\n| E — Effective top tube    | 57.8  | 59.7  | 61.6  | 63.6  |\n| F — Bottom bracket height | 33.0  | 33.0  | 33.0  | 33.0  |\n| G — Bottom bracket drop   | 5.0   | 5.0   | 5.0   | 5.0   |\n| H — Chainstay length      | 43.0  | 43.0  | 43.0  | 43.0  |\n| I — Offset                | 4.2   | 4.2   | 4.2   | 4.2   |\n| J — Trail                 | 9.7   | 9.7   | 9.7   | 9.7   |\n| K — Wheelbase             | 112.5 | 114.5 | 116.5 | 118.6 |\n| L — Standover             | 75.9  | 77.8  | 81.5  | 84.2  |\n| M — Frame reach           | 41.6  | 43.4  | 45.2  | 47.1  |\n| N — Frame stack           | 58.2  | 58.9  | 59.3  | 59.9  |",
    "price": 1099.99,
    "tags": [
      "bicycle",
      "mountain bike"
    ]
  },
  {
    "name": "AURORA 11S E-MTB",
    "shortDescription": "The AURORA 11S is a powerful and stylish electric mountain bike designed to take you on thrilling off-road adventures. With its sturdy frame and premium components, this bike is built to handle any terrain. It features a high-performance motor, long-lasting battery, and advanced suspension system that guarantee a smooth and comfortable ride.",
    "description": "## Overview\nIt's right for you if...\nYou want a top-of-the-line e-MTB that is both powerful and stylish. You also want a bike that can handle any terrain, from steep climbs to rocky descents. With its advanced features and premium components, the AURORA 11S is designed for serious off-road riders who demand the best.\n\nThe tech you get\nA sturdy aluminum frame with advanced suspension system that provides 120mm of travel. A 750W brushless motor that delivers up to 28mph, and a 48V/14Ah lithium-ion battery that provides up to 60 miles of range on a single charge. An advanced 11-speed Shimano drivetrain with hydraulic disc brakes for precise shifting and reliable stopping power. \n\nThe final word\nThe AURORA 11S is a top-of-the-line e-MTB that delivers exceptional performance and style. Whether you're tackling steep climbs or hitting rocky descents, this bike is built to handle any terrain with ease. With its advanced features and premium components, the AURORA 11S is the perfect choice for serious off-road riders who demand the best.\n\n## Features\nPowerful and efficient\n\nThe AURORA 11S is equipped with a high-performance 750W brushless motor that delivers up to 28mph. The motor is powered by a long-lasting 48V/14Ah lithium-ion battery that provides up to 60 miles of range on a single charge.\n\nAdvanced suspension system\n\nThe bike's advanced suspension system provides 120mm of travel, ensuring a smooth and comfortable ride on any terrain. The front suspension is a Suntour XCR32 Air fork, while the rear suspension is a KS-281 hydraulic shock absorber.\n\nPremium components\n\nThe AURORA 11S features an advanced 11-speed Shimano drivetrain with hydraulic disc brakes. The bike is also equipped with a Tektro HD-E725 hydraulic disc brake system that provides reliable stopping power.\n\nSleek and stylish design\n\nWith its sleek and stylish design, the AURORA 11S is sure to turn heads on the trail. The bike's sturdy aluminum frame is available in a range of colors, including black, blue, and red.\n\n## Specs\nFrameset\nFrame Material: Aluminum\nFrame Size: S, M, L\nFork: Suntour XCR32 Air, 120mm Travel\nShock Absorber: KS-281 Hydraulic Shock Absorber\n\nWheels\nWheel Size: 27.5 inches\nTires: Kenda K1151 Nevegal, 27.5x2.35\nRims: Alloy Double Wall\nSpokes: 32H, Stainless Steel\n\nDrivetrain\nShifters: Shimano SL-M7000\nRear Derailleur: Shimano RD-M8000\nCrankset: Prowheel 42T, Alloy Crank Arm\nCassette: Shimano CS-M7000, 11-42T\nChain: KMC X11EPT\n\nBrakes\nBrake System: Tektro HD-E725 Hydraulic Disc Brake\nBrake Rotors: 180mm Front, 160mm Rear\n\nE-bike system\nMotor: 750W Brushless\nBattery: 48V/14Ah Lithium-Ion\nCharger: 48V/3A Smart Charger\nController: Intelligent Sinusoidal Wave\n\nWeight\nWeight: 59.5 lbs\n\n## Sizing & fit\n| Size | Rider Height | Standover Height |\n|------|-------------|-----------------|\n| S    | 5'2\"-5'6\"   | 28.5\"           |\n| M    | 5'7\"-6'0\"   | 29.5\"           |\n| L    | 6'0\"-6'4\"   | 30.5\"           |\n\n## Geometry\nAll measurements provided in cm.\nSizing table\n| Frame size letter | S   | M   | L   |\n|-------------------|-----|-----|-----|\n| Wheel Size        | 27.5\"| 27.5\"| 27.5\"|\n| Seat tube length  | 44.5| 48.5| 52.5|\n| Head tube angle   | 68° | 68° | 68° |\n| Seat tube angle   | 74.5°| 74.5°| 74.5°|\n| Effective top tube | 57.5| 59.5| 61.5|\n| Head tube length  | 12.0| 12.0| 13.0|\n| Chainstay length  | 45.5| 45.5| 45.5|\n| Bottom bracket height | 30.0| 30.0| 30.0|\n| Wheelbase         | 115.0|116.5|118.5|",
    "price": 1999.99,
    "tags": [
      "bicycle",
      "road bike"
    ]
  },
  {
    "name": "VeloTech V9.5 AXS Gen 3",
    "shortDescription": "VeloTech V9.5 AXS is a sleek and fast carbon bike that combines high-end tech with a comfortable ride. It's designed to provide the ultimate experience for the most serious riders. The bike comes with a lightweight and powerful motor that can be activated when needed, and you get a spec filled with premium parts.",
    "description": "## Overview\nIt's right for you if...\nYou want a bike that is fast, efficient, and delivers an adrenaline-filled experience. You are looking for a bike that is built with cutting-edge technology, and you want a ride that is both comfortable and exciting.\n\nThe tech you get\nA lightweight and durable full carbon frame with a fork that has 100mm of travel. The bike comes with a powerful motor that can deliver up to 20 mph of assistance. The drivetrain is a wireless electronic system that is precise and reliable. The bike is also equipped with hydraulic disc brakes, tubeless-ready wheels, and comfortable grips.\n\nThe final word\nThe VeloTech V9.5 AXS is a high-end bike that delivers an incredible experience for serious riders. It combines the latest technology with a comfortable ride, making it perfect for long rides, tough climbs, and fast descents.\n\n## Features\nFast and efficient\nThe VeloTech V9.5 AXS comes with a powerful motor that can provide up to 20 mph of assistance. The motor is lightweight and efficient, providing a boost when you need it without adding bulk. The bike's battery is removable, allowing you to ride without assistance when you don't need it.\n\nSmart software for the trail\nThe VeloTech V9.5 AXS is equipped with intelligent software that delivers a smooth and responsive ride. The software allows the motor to respond immediately as you start to pedal, delivering more power over a wider cadence range. You can also customize your user settings to suit your preferences.\n\nComfortable ride\nThe VeloTech V9.5 AXS is designed to provide a comfortable ride, even on long rides. The bike's fork has 100mm of travel, providing ample cushioning for rough terrain. The bike's grips are also designed to provide a comfortable and secure grip, even on the most challenging rides.\n\n## Specs\nFrameset\nFrame\tCarbon fiber frame with internal cable routing and Boost148\nFork\t100mm of travel with remote lockout\nShock\tN/A\n\nWheels\nWheel front\tCarbon fiber tubeless-ready wheel\nWheel rear\tCarbon fiber tubeless-ready wheel\nSkewer rear\t12mm thru-axle\nTire\tTubeless-ready tire\nTire part\tTubeless sealant\n\nDrivetrain\nShifter\tWireless electronic shifter\nRear derailleur\tWireless electronic derailleur\nCrank\tCarbon fiber crankset with chainring\nCrank arm\tCarbon fiber crank arm\nChainring\tAlloy chainring\nCassette\t12-speed cassette\nChain\t12-speed chain\n\nComponents\nSaddle\tCarbon fiber saddle\nSeatpost\tCarbon fiber seatpost\nHandlebar\tCarbon fiber handlebar\nGrips\tComfortable and secure grips\nStem\tCarbon fiber stem\nHeadset\tCarbon fiber headset\nBrake\tHydraulic disc brakes\nBrake rotor\tDisc brake rotor\n\nAccessories\nE-bike system\tPowerful motor with removable battery\nBattery\tLithium-ion battery\nCharger\tFast charging adapter\nController\tHandlebar-mounted controller\nTool\tBasic toolkit\n\nWeight\nWeight\tM - 17.5 kg / 38.5 lbs (with tubeless sealant)\n\nWeight limit\nThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing & fit\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 160 - 170 cm 5'3\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|   M  | 170 - 180 cm 5'7\" - 5'11\" | 79 - 84 cm 31\" - 33\" |\n|   L  | 180 - 190 cm 5'11\" - 6'3\" | 84 - 89 cm 33\" - 35\" |\n|  XL  | 190 - 200 cm 6'3\" - 6'7\" | 89 - 94 cm 35\" - 37\" |\n\n## Geometry\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 50.0  | 53.3  | 55.6  | 58.8  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.4  | 43.2  | 48.3  | 53.3  |\n| B — Seat tube angle       | 72.3° | 72.6° | 72.8° | 72.8° |\n| C — Head tube length      | 9.0   | 10.0  | 10.5  | 11.0  |\n| D — Head angle            | 67.5° | 67.5° | 67.5° | 67.5° |\n| E — Effective top tube    | 58.0  | 61.7  | 64.8  | 67.0  |\n| F — Bottom bracket height | 32.3  | 32.3  | 32.3  | 32.3  |\n| G — Bottom bracket drop   | 5.0   | 5.0   | 5.0   | 5.0   |\n| H — Chainstay length      | 44.7  | 44.7  | 44.7  | 44.7  |\n| I — Offset                | 4.2   | 4.2   | 4.2   | 4.2   |\n| J — Trail                 | 10.9  | 10.9  | 10.9  | 10.9  |\n| K — Wheelbase             | 112.6 | 116.5 | 119.7 | 121.9 |\n| L — Standover             | 76.8  | 76.8  | 76.8  | 76.8  |\n| M — Frame reach           | 40.5  | 44.0  | 47.0  | 49.0  |\n| N — Frame stack           | 60.9  | 61.8  | 62.2  | 62.7  |",
    "price": 1699.99,
    "tags": [
      "bicycle",
      "electric bike",
      "city bike"
    ]
  },
  {
    "name": "Axiom D8 E-Mountain Bike",
    "shortDescription": "The Axiom D8 is an electrifying mountain bike that is built for adventure. It boasts a light aluminum frame, a powerful motor and the latest tech to tackle the toughest of terrains. The D8 provides assistance without adding bulk to the bike, giving you the flexibility to ride like a traditional mountain bike or have an extra push when you need it.",
    "description": "## Overview  \nIt's right for you if...  \nYou're looking for an electric mountain bike that can handle a wide variety of terrain, from flowing singletrack to technical descents. You also want a bike that offers a powerful motor that provides assistance without adding bulk to the bike. The D8 is designed to take you anywhere, quickly and comfortably.\n\nThe tech you get  \nA lightweight aluminum frame with 140mm of travel, a Suntour fork with hydraulic lockout, and a reliable and powerful Bafang M400 mid-motor that provides a boost up to 20 mph. The bike features a Shimano Deore drivetrain, hydraulic disc brakes, and a dropper seat post. With the latest tech on-board, the D8 is designed to take you to new heights.\n\nThe final word  \nThe Axiom D8 is an outstanding electric mountain bike that is designed for adventure. It's built with the latest tech and provides the flexibility to ride like a traditional mountain bike or have an extra push when you need it. Whether you're a beginner or an experienced rider, the D8 is the perfect companion for your next adventure.\n\n## Features  \nBuilt for Adventure  \n\nThe D8 features a lightweight aluminum frame that is built to withstand rugged terrain. It comes equipped with 140mm of travel and a Suntour fork that can handle even the toughest of trails. With this bike, you're ready to take on anything the mountain can throw at you.\n\nPowerful Motor  \n\nThe Bafang M400 mid-motor provides reliable and powerful assistance without adding bulk to the bike. You can quickly and easily switch between the different assistance levels to find the perfect balance between range and power.\n\nShimano Deore Drivetrain  \n\nThe Shimano Deore drivetrain is reliable and offers smooth shifting on any terrain. You can easily adjust the gears to match your riding style and maximize your performance on the mountain.\n\nDropper Seat Post  \n\nThe dropper seat post allows you to easily adjust your seat height on the fly, so you can maintain the perfect position for any terrain. With the flick of a switch, you can quickly and easily lower or raise your seat to match the terrain.\n\nHydraulic Disc Brakes  \n\nThe D8 features powerful hydraulic disc brakes that offer reliable stopping power in any weather condition. You can ride with confidence knowing that you have the brakes to stop on a dime.\n\n## Specs  \nFrameset  \nFrame\tAluminum frame with 140mm of travel  \nFork\tSuntour fork with hydraulic lockout, 140mm of travel  \nShock\tN/A  \nMax compatible fork travel\t140mm  \n  \nWheels  \nWheel front\tAlloy wheel  \nWheel rear\tAlloy wheel  \nSkewer rear\tThru axle  \nTire\t29\" x 2.35\"  \nTire part\tN/A  \nMax tire size\t29\" x 2.6\"  \n  \nDrivetrain  \nShifter\tShimano Deore  \nRear derailleur\tShimano Deore  \nCrank\tBafang M400  \nCrank arm\tN/A  \nChainring\tN/A  \nCassette\tShimano Deore  \nChain\tShimano Deore  \nMax chainring size\tN/A  \n  \nComponents  \nSaddle\tAxiom D8 saddle  \nSeatpost\tDropper seat post  \nHandlebar\tAxiom D8 handlebar  \nGrips\tAxiom D8 grips  \nStem\tAxiom D8 stem  \nHeadset\tAxiom D8 headset  \nBrake\tHydraulic disc brakes  \nBrake rotor\t180mm  \n\nAccessories  \nE-bike system\tBafang M400 mid-motor  \nBattery\tLithium-ion battery, 500Wh  \nCharger\tLithium-ion charger  \nController\tBafang M400 controller  \nTool\tN/A  \n  \nWeight  \nWeight\tM - 22 kg / 48.5 lbs  \nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 136 kg (300 lbs).  \n  \n  \n## Sizing & fit  \n  \n| Size |       Rider Height       |        Inseam        |  \n|:----:|:------------------------:|:--------------------:|  \n|   S  | 152 - 165 cm 5'0\" - 5'5\" | 70 - 76 cm 27\" - 30\" |  \n|   M  | 165 - 178 cm 5'5\" - 5'10\" | 76 - 81 cm 30\" - 32\" |  \n|   L  | 178 - 185 cm 5'10\" - 6'1\" | 81 - 86 cm 32\" - 34\" |  \n|  XL  | 185 - 193 cm 6'1\" - 6'4\" | 86 - 91 cm 34\" - 36\" |  \n  \n  \n## Geometry  \n  \nAll measurements provided in cm unless otherwise noted.  \nSizing table  \n| Frame size letter         | S     | M     | L     | XL    |  \n|---------------------------|-------|-------|-------|-------|  \n| Actual frame size         | 41.9  | 46.5  | 50.8  | 55.9  |  \n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |  \n| A — Seat tube             | 42.0  | 46.5  | 51.0  | 56.0  |  \n| B — Seat tube angle       | 74.0° | 74.0° | 74.0° | 74.0° |  \n| C — Head tube length      | 11.0  | 12.0  | 13.0  | 15.0  |  \n| D — Head angle            | 68.0° | 68.0° | 68.0° | 68.0° |  \n| E — Effective top tube    | 57.0  | 60.0  | 62.0  | 65.0  |  \n| F — Bottom bracket height | 33.0  | 33.0  | 33.0  | 33.0  |  \n| G — Bottom bracket drop   | 3.0   | 3.0   | 3.0   | 3.0   |  \n| H — Chainstay length      | 46.0  | 46.0  | 46.0  | 46.0  |  \n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |  \n| J — Trail                 | 10.9  | 10.9  | 10.9  | 10.9  |  \n| K — Wheelbase             | 113.0 | 116.0 | 117.5 | 120.5 |  \n| L — Standover             | 73.5  | 75.5  | 76.5  | 79.5  |  \n| M — Frame reach           | 41.0  | 43.5  | 45.0  | 47.5  |  \n| N — Frame stack           | 60.5  | 61.5  | 62.5  | 64.5  |",
    "price": 1399.99,
    "tags": [
      "bicycle",
      "electric bike",
      "mountain bike"
    ]
  },
  {
    "name": "Velocity X1",
    "shortDescription": "Velocity X1 is a high-performance road bike designed for speed enthusiasts. It features a lightweight yet durable frame, aerodynamic design, and top-quality components, making it the perfect choice for those who want to take their cycling experience to the next level.",
    "description": "## Overview\nIt's right for you if...\nYou're an experienced cyclist looking for a bike that can keep up with your need for speed. You want a bike that's lightweight, aerodynamic, and built to perform, whether you're training for a race or just pushing yourself to go faster.\n\nThe tech you get\nA lightweight aluminum frame with a carbon fork, Shimano Ultegra groupset with a wide range of gearing, hydraulic disc brakes, aerodynamic carbon wheels, and a vibration-absorbing handlebar with ergonomic grips.\n\nThe final word\nVelocity X1 is the ultimate road bike for speed enthusiasts. Its lightweight frame, aerodynamic design, and top-quality components make it the perfect choice for those who want to take their cycling experience to the next level.\n\n\n## Features\n\nAerodynamic design\nVelocity X1 is built with an aerodynamic design to help you go faster with less effort. It features a sleek profile, hidden cables, and a carbon fork that cuts through the wind, reducing drag and increasing speed.\n\nHydraulic disc brakes\nVelocity X1 comes equipped with hydraulic disc brakes, providing excellent stopping power in all weather conditions. They're also low maintenance, with minimal adjustments needed over time.\n\nCarbon wheels\nThe Velocity X1's aerodynamic carbon wheels provide excellent speed and responsiveness, helping you achieve your fastest times yet. They're also lightweight, reducing overall bike weight and making acceleration and handling even easier.\n\nShimano Ultegra groupset\nThe Shimano Ultegra groupset provides smooth shifting and reliable performance, ensuring you get the most out of every ride. With a wide range of gearing options, it's ideal for tackling any terrain, from steep climbs to fast descents.\n\n\n## Specifications\nFrameset\nFrame with Fork\tAluminium frame, internal cable routing, 135x9mm QR\nFork\tCarbon, hidden cable routing, 100x9mm QR\n\nWheels\nWheel front\tCarbon, 30mm deep rim, 23mm width, 100x9mm QR\nWheel rear\tCarbon, 30mm deep rim, 23mm width, 135x9mm QR\nSkewer front\t100x9mm QR\nSkewer rear\t135x9mm QR\nTire\tContinental Grand Prix 5000, 700x25mm, folding bead\nMax tire size\t700x28mm without fenders\n\nDrivetrain\nShifter\tShimano Ultegra R8020, 11 speed\nRear derailleur\tShimano Ultegra R8000, 11 speed\n*Crank\tSize: S, M\nShimano Ultegra R8000, 50/34T, 170mm length\nSize: L, XL\nShimano Ultegra R8000, 50/34T, 175mm length\nBottom bracket\tShimano BB-RS500-PB, PressFit\nCassette\tShimano Ultegra R8000, 11-30T, 11 speed\nChain\tShimano Ultegra HG701, 11 speed\nPedal\tNot included\nMax chainring size\t50/34T\n\nComponents\nSaddle\tBontrager Montrose Comp, steel rails, 138mm width\nSeatpost\tBontrager Comp, 6061 alloy, 27.2mm, 8mm offset, 330mm length\n*Handlebar\tSize: S, M, L\nBontrager Elite Aero VR-CF, alloy, 31.8mm, 93mm reach, 123mm drop, 400mm width\nSize: XL\nBontrager Elite Aero VR-CF, alloy, 31.8mm, 93mm reach, 123mm drop, 420mm width\nGrips\tBontrager Supertack Perf tape\n*Stem\tSize: S, M, L\nBontrager Elite Blendr, 31.8mm clamp, 7 degree, 90mm length\nSize: XL\nBontrager Elite Blendr, 31.8mm clamp, 7 degree, 100mm length\nBrake\tShimano Ultegra R8070 hydraulic disc, flat mount\nBrake rotor\tShimano RT800, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 8.15 kg / 17.97 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|   S  |   162 - 170 cm 5'4\" - 5'7\" | 74 - 78 cm 29\" - 31\" |\n|   M  |   170 - 178 cm 5'7\" - 5'10\" | 77 - 82 cm 30\" - 32\" |\n|   L  |  178 - 186 cm 5'10\" - 6'1\" | 82 - 86 cm 32\" - 34\" |\n|  XL  |  186 - 196 cm 6'1\" - 6'5\" | 87 - 92 cm 34\" - 36\" |\n\n\n## Geometry\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 50.0  | 52.0  | 54.0  | 56.0  |\n| B — Seat tube angle       | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length      | 13.0  | 15.0  | 17.0  | 19.0  |\n| D — Head angle            | 71.0° | 72.0° | 72.0° | 72.5° |\n| E — Effective top tube    | 53.7  | 55.0  | 56.5  | 58.0  |\n| F — Bottom bracket height | 27.5  | 27.5  | 27.5  | 27.5  |\n| G — Bottom bracket drop   | 7.3   | 7.3   | 7.3   | 7.3   |\n| H — Chainstay length      | 41.0  | 41.0  | 41.0  | 41.0  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 6.0   | 6.0   | 6.0   | 5.8   |\n| K — Wheelbase             | 98.2  | 99.1  | 100.1 | 101.0 |\n| L — Standover             | 75.2  | 78.2  | 81.1  | 84.1  |\n| M — Frame reach           | 37.5  | 38.3  | 39.1  | 39.9  |\n| N — Frame stack           | 53.3  | 55.4  | 57.4  | 59.5  |",
    "price": 1799.99,
    "tags": [
      "bicycle",
      "touring bike"
    ]
  },
  {
    "name": "Velocity V9",
    "shortDescription": "Velocity V9 is a high-performance hybrid bike that combines speed and comfort for riders who demand the best of both worlds. The lightweight aluminum frame, along with the carbon fork and seat post, provide optimal stiffness and absorption to tackle any terrain. A 2x Shimano Deore drivetrain, hydraulic disc brakes, and 700c wheels with high-quality tires make it a versatile ride for commuters, fitness riders, and weekend adventurers alike.",
    "description": "## Overview\nIt's right for you if...\nYou want a fast, versatile bike that can handle anything from commuting to weekend adventures. You value comfort as much as speed and performance. You want a reliable and durable bike that will last for years to come.\n\nThe tech you get\nA lightweight aluminum frame with a carbon fork and seat post, a 2x Shimano Deore drivetrain with a wide range of gearing, hydraulic disc brakes, and 700c wheels with high-quality tires. The Velocity V9 is designed for riders who demand both performance and comfort in one package.\n\nThe final word\nThe Velocity V9 is the perfect bike for riders who want speed and performance without sacrificing comfort. The lightweight aluminum frame and carbon components provide optimal stiffness and absorption, while the 2x Shimano Deore drivetrain and hydraulic disc brakes ensure precise shifting and stopping power. Whether you're commuting, hitting the trails, or training for your next race, the Velocity V9 has everything you need to achieve your goals.\n\n## Features\n\n2x drivetrain\nA 2x drivetrain means more versatility and a wider range of gearing options. Whether you're climbing hills or sprinting on the flats, the Velocity V9 has the perfect gear for any situation.\n\nCarbon components\nThe Velocity V9 features a carbon fork and seat post to provide optimal stiffness and absorption. This means you can ride faster and more comfortably over any terrain.\n\nHydraulic disc brakes\nHydraulic disc brakes provide unparalleled stopping power and modulation in any weather condition. You'll feel confident and in control no matter where you ride.\n\n## Specifications\nFrameset\nFrame with Fork\tAluminum frame with carbon fork and seat post, internal cable routing, fender mounts, 135x5mm ThruSkew\nFork\tCarbon fork, hidden fender mounts, flat mount disc, 5x100mm thru-skew\n\nWheels\nWheel front\tDouble wall aluminum rims, 700c, quick release hub\nWheel rear\tDouble wall aluminum rims, 700c, quick release hub\nTire\tKenda Kwick Tendril, puncture resistant, reflective sidewall, 700x32c\nMax tire size\t700x35c without fenders, 700x32c with fenders\n\nDrivetrain\nShifter\tShimano Deore, 10 speed\nFront derailleur\tShimano Deore\nRear derailleur\tShimano Deore\nCrank\tShimano Deore, 46-30T, 170mm (S/M), 175mm (L/XL)\nBottom bracket\tShimano BB52, 68mm, threaded\nCassette\tShimano Deore, 11-36T, 10 speed\nChain\tShimano HG54, 10 speed\nPedal\tWellgo alloy platform\n\nComponents\nSaddle\tVelo VL-2158, steel rails\nSeatpost\tCarbon seat post, 27.2mm\nHandlebar\tAluminum, 31.8mm clamp, 15mm rise, 680mm width\nGrips\tVelo ergonomic grips\nStem\tAluminum, 31.8mm clamp, 7 degree, 90mm length\nBrake\tShimano hydraulic disc, MT200 lever, MT200 caliper\nBrake rotor\tShimano RT56, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 11.5 kg / 25.35 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  |  186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size         | S     | M     | L     | XL    |\n|--------------------|-------|-------|-------|-------|\n| Wheel size         | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube      | 44.0  | 48.0  | 52.0  | 56.0  |\n| B — Seat tube angle | 74.5° | 74.0° | 73.5° | 73.0° |\n| C — Head tube length | 14.5  | 16.0  | 18.0  | 20.0  |\n| D — Head angle       | 71.0° | 71.0° | 71.5° | 71.5° |\n| E — Effective top tube | 56.5  | 57.5  | 58.5  | 59.5  |\n| F — Bottom bracket height | 27.0  | 27.0  | 27.0  | 27.0  |\n| G — Bottom bracket drop | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length | 43.0  | 43.0  | 43.0  | 43.0  |\n| I — Offset | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail | 7.0   | 7.0   | 6.6   | 6.6   |\n| K — Wheelbase | 105.4 | 106.3 | 107.2 | 108.2 |\n| L — Standover | 73.2  | 77.1  | 81.2  | 85.1  |\n| M — Frame reach | 39.0  | 39.8  | 40.4  | 41.3  |\n| N — Frame stack | 57.0  | 58.5  | 60.0  | 61.5  |",
    "price": 2199.99,
    "tags": [
      "bicycle",
      "electric bike",
      "mountain bike"
    ]
  },
  {
    "name": "Aero Pro X",
    "shortDescription": "Aero Pro X is a high-end racing bike designed for serious cyclists who demand speed, agility, and superior performance. The lightweight carbon frame and fork, combined with the aerodynamic design, provide optimal stiffness and efficiency to maximize your speed. The bike features a 2x Shimano Ultegra drivetrain, hydraulic disc brakes, and 700c wheels with high-quality tires. Whether you're competing in a triathlon or climbing steep hills, Aero Pro X delivers exceptional performance and precision handling.",
    "description": "## Overview\nIt's right for you if...\nYou are a competitive cyclist looking for a bike that is designed for racing. You want a bike that delivers exceptional speed, agility, and precision handling. You demand superior performance and reliability from your equipment.\n\nThe tech you get\nA lightweight carbon frame with an aerodynamic design, a carbon fork with hidden fender mounts, a 2x Shimano Ultegra drivetrain with a wide range of gearing, hydraulic disc brakes, and 700c wheels with high-quality tires. Aero Pro X is designed for serious cyclists who demand nothing but the best.\n\nThe final word\nAero Pro X is the ultimate racing bike for serious cyclists. The lightweight carbon frame and aerodynamic design deliver maximum speed and efficiency, while the 2x Shimano Ultegra drivetrain and hydraulic disc brakes ensure precise shifting and stopping power. Whether you're competing in a triathlon or a criterium race, Aero Pro X delivers the performance you need to win.\n\n## Features\n\nAerodynamic design\nThe Aero Pro X features an aerodynamic design that reduces drag and maximizes efficiency. The bike is optimized for speed and agility, so you can ride faster and farther with less effort.\n\nHydraulic disc brakes\nHydraulic disc brakes provide unrivaled stopping power and modulation in any weather condition. You'll feel confident and in control no matter where you ride.\n\nCarbon components\nThe Aero Pro X features a carbon fork with hidden fender mounts to provide optimal stiffness and absorption. This means you can ride faster and more comfortably over any terrain.\n\n## Specifications\nFrameset\nFrame with Fork\tCarbon frame with an aerodynamic design, internal cable routing, 3s chain keeper, 142x12mm thru-axle\nFork\tCarbon fork with hidden fender mounts, flat mount disc, 100x12mm thru-axle\n\nWheels\nWheel front\tDouble wall carbon rims, 700c, thru-axle hub\nWheel rear\tDouble wall carbon rims, 700c, thru-axle hub\nTire\tContinental Grand Prix 5000, folding bead, 700x25c\nMax tire size\t700x28c without fenders, 700x25c with fenders\n\nDrivetrain\nShifter\tShimano Ultegra, 11 speed\nFront derailleur\tShimano Ultegra\nRear derailleur\tShimano Ultegra\nCrank\tShimano Ultegra, 52-36T, 170mm (S), 172.5mm (M), 175mm (L/XL)\nBottom bracket\tShimano BB72, 68mm, PressFit\nCassette\tShimano Ultegra, 11-30T, 11 speed\nChain\tShimano HG701, 11 speed\nPedal\tNot included\n\nComponents\nSaddle\tBontrager Montrose Elite, carbon rails, 138mm width\nSeatpost\tCarbon seat post, 27.2mm, 20mm offset\nHandlebar\tBontrager XXX Aero, carbon, 31.8mm clamp, 75mm reach, 125mm drop\nGrips\tBontrager Supertack Perf tape\nStem\tBontrager Pro, 31.8mm clamp, 7 degree, 90mm length\nBrake\tShimano hydraulic disc, Ultegra lever, Ultegra caliper\nBrake rotor\tShimano RT800, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 8.36 kg / 18.42 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size |        Rider Height       |\n|:----:|:-------------------------:|\n|   S  |  155 - 165 cm 5'1\" - 5'5\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" |\n|  XL  |  186 - 197 cm 6'1\" - 6'6\" |\n\n## Geometry\n| Frame size         | S     | M     | L     | XL    |\n|--------------------|-------|-------|-------|-------|\n| Wheel size         | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube      | 50.6  | 52.4  | 54.3  | 56.2  |\n| B — Seat tube angle | 75.5° | 74.5° | 73.5° | 72.5° |\n| C — Head tube length | 12.0  | 14.0  | 16.0  | 18.0  |\n| D — Head angle       | 72.5° | 73.0° | 73.5° | 74.0° |\n| E — Effective top tube | 53.8  | 55.4  | 57.0  | 58.6  |\n| F — Bottom bracket height | 26.5  | 26.5  | 26.5  | 26.5  |\n| G — Bottom bracket drop | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length | 41.0  | 41.0  | 41.0  | 41.0  |\n| I — Offset | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail | 6.0   | 6.0   | 6.0   | 6.0   |\n| K — Wheelbase | 97.1  | 98.7  | 100.2 | 101.8 |\n| L — Standover | 73.8  | 76.2  | 78.5  | 80.8  |\n| M — Frame reach | 38.8  | 39.5  | 40.2  | 40.9  |\n| N — Frame stack | 52.8  | 54.7  | 56.6  | 58.5  |",
    "price": 1599.99,
    "tags": [
      "bicycle",
      "road bike"
    ]
  },
  {
    "name": "Voltex+ Ultra Lowstep",
    "shortDescription": "Voltex+ Ultra Lowstep is a high-performance electric hybrid bike designed for riders who seek speed, comfort, and reliability during their everyday rides. Equipped with a powerful and efficient Voltex Drive Pro motor and a fully-integrated 600Wh battery, this e-bike allows you to cover longer distances on a single charge. The Voltex+ Ultra Lowstep comes with premium components that prioritize comfort and safety, such as a suspension seatpost, wide and stable tires, and integrated lights.",
    "description": "## Overview\n\nIt's right for you if...\nYou want an e-bike that provides a boost for faster rides and effortless usage. Durability is crucial, and you need a bike with one of the most powerful and efficient motors.\n\nThe tech you get\nA lightweight Delta Carbon Fiber frame with an ultra-lowstep design, a Voltex Drive Pro (350W, 75Nm) motor capable of maintaining speeds up to 30 mph, an extended range 600Wh battery integrated into the frame, and a Voltex Control Panel. Additionally, it features a 12-speed Shimano drivetrain, hydraulic disc brakes for optimal all-weather stopping power, a suspension seatpost, wide puncture-resistant tires for added stability, ergonomic grips, a kickstand, lights, and a cargo rack.\n\nThe final word\nThis bike offers enhanced enjoyment and ease of use on long commutes, leisure rides, and adventures. With its extended-range battery, powerful Voltex motor, user-friendly controller, and a seatpost that smooths out road vibrations, it guarantees an exceptional riding experience.\n\n## Features\n\nUltra-fast assistance\n\nExperience speeds up to 30 mph with the cutting-edge Voltex Drive Pro motor, allowing you to breeze through errands, commutes, and joyrides.\n\n## Specs\n\nFrameset\n- Frame: Delta Carbon Fiber, Removable Integrated Battery (RIB), sleek welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: Voltex Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: Voltex Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: Voltex E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore XT M8100, 12-speed\n- Rear derailleur: Shimano Deore XT M8100, long cage\n- Crank: Voltex alloy, 170mm length\n- Chainring: FSA, 44T, aluminum with guard\n- Cassette: Shimano Deore XT M8100, 10-51, 12-speed\n- Chain: KMC E12 Turbo\n- Pedal: Voltex Urban pedals\n\nComponents\n- Saddle: Voltex Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar: Voltex alloy, 31.8mm, comfort sweep, 620mm width (XS, S, M), 660mm width (L)\n- Grips: Voltex Satellite Elite, alloy lock-on\n- Stem: Voltex alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length (XS, S), 105mm length (M, L)\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT520 hydraulic disc\n- Brake rotor: Shimano RT56, 6-bolt, 180mm (XS, S, M, L), 160mm (XS, S, M, L)\n\nAccessories\n- Battery: Voltex PowerTube 600Wh\n- Charger: Voltex compact 2A, 100-240V\n- Computer: Voltex Control Panel\n- Motor: Voltex Drive Pro, 75Nm, 30mph\n- Light: Voltex Solo for e-bike, taillight (XS, S, M, L), Voltex MR8, 180 lumen, 60 lux, LED, headlight (XS, S, M, L)\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: Voltex-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender: Voltex wide (XS, S, M, L), Voltex plastic (XS, S, M, L)\n\nWeight\n- Weight: M - 20.50 kg / 45.19 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 330 pounds (150 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 38.0  | 43.0  | 48.0  | 53.0  |\n| B — Seat tube angle       | 70.5° | 70.5° | 70.5° | 70.5° |\n| C — Head tube length      | 15.0  | 15.0  | 17.0  | 19.0  |\n| D — Head angle            | 69.2° | 69.2° | 69.2° | 69.2° |\n| E — Effective top tube    | 57.2  | 57.7  | 58.8  | 60.0  |\n| F — Bottom bracket height | 30.3  | 30.3  | 30.3  | 30.3  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.5  | 48.5  | 48.5  | 48.5  |\n| I — Offset                | 5.0   | 5.0   | 5.0   | 5.0   |\n| J — Trail                 | 9.0   | 9.0   | 9.0   | 9.0   |\n| K — Wheelbase             | 111.8 | 112.3 | 113.6 | 114.8 |\n| L — Standover             | 42.3  | 42.3  | 42.3  | 42.3  |\n| M — Frame reach           | 36.0  | 38.0  | 38.0  | 38.0  |\n| N — Frame stack           | 62.0  | 62.0  | 63.9  | 65.8  |\n| Stem length               | 8.0   | 8.5   | 8.5   | 10.5  |\n\nPlease note that the specifications and features listed above are subject to change and may vary based on different models and versions of the Voltex+ Ultra Lowstep bike.",
    "price": 2999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "SwiftRide Hybrid",
    "shortDescription": "SwiftRide Hybrid is a versatile and efficient bike designed for riders who want a smooth and enjoyable ride on various terrains. It incorporates advanced technology and high-quality components to provide a comfortable and reliable cycling experience.",
    "description": "## Overview\n\nIt's right for you if...\nYou are looking for a bike that combines the benefits of an electric bike with the versatility of a hybrid. You value durability, speed, and ease of use.\n\nThe tech you get\nThe SwiftRide Hybrid features a lightweight and durable aluminum frame, making it easy to handle and maneuver. It is equipped with a powerful electric motor that offers a speedy assist, helping you reach speeds of up to 25 mph. The bike comes with a removable and fully-integrated 500Wh battery, providing a long-range capacity for extended rides. It also includes a 10-speed Shimano drivetrain, hydraulic disc brakes for precise stopping power, wide puncture-resistant tires for stability, and integrated lights for enhanced visibility.\n\nThe final word\nThe SwiftRide Hybrid is designed for riders who want a bike that can handle daily commutes, recreational rides, and adventures. With its efficient motor, intuitive controls, and comfortable features, it offers an enjoyable and hassle-free riding experience.\n\n## Features\n\nEfficient electric assist\nExperience the thrill of effortless riding with the powerful electric motor that provides a speedy assist, making your everyday rides faster and more enjoyable.\n\n## Specs\n\nFrameset\n- Frame: Lightweight Aluminum, Removable Integrated Battery (RIB), rack & fender mounts, internal routing, 135x5mm QR\n- Fork: SwiftRide Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: SwiftRide Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: SwiftRide E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: SwiftRide City pedals\n\nComponents\n- Saddle: SwiftRide Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - SwiftRide alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - SwiftRide alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: SwiftRide Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - SwiftRide alloy quill, 31.8mm clamp, adjustable rise, 85mm length\n  - Size: M, L - SwiftRide alloy quill, 31.8mm clamp, adjustable rise, 105mm length\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: SwiftRide PowerTube 500Wh\n- Charger: SwiftRide compact 2A, 100-240V\n- Computer: SwiftRide Purion\n- Motor: SwiftRide Performance Line Sport, 65Nm, 25mph\n- Light:\n  - Size: XS, S, M, L - SwiftRide SOLO for e-bike, taillight\n  - Size: XS, S, M, L - SwiftRide MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: SwiftRide-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - SwiftRide wide\n  - Size: XS, S, M, L - SwiftRide plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm (4'10\" - 5'1\") | 69 - 73 cm (27\" - 29\") |\n|   S  |  155 - 165 cm (5'1\" - 5'5\") | 72 - 78 cm (28\" - 31\") |\n|   M  |  165 - 175 cm (5'5\" - 5'9\") | 77 - 83 cm (30\" - 33\") |\n|   L  |  175 - 186 cm (5'9\" - 6'1\") | 82 - 88 cm (32\" - 35\") |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 3999.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "RoadRunner E-Speed Lowstep",
    "shortDescription": "RoadRunner E-Speed Lowstep is a high-performance electric hybrid designed for riders seeking speed and excitement on their daily rides. It is equipped with a powerful and reliable ThunderBolt drive unit that offers exceptional acceleration. The bike features a fully-integrated 500Wh battery, allowing riders to cover longer distances on a single charge. With its comfortable and safe components, including a suspension seatpost, wide and stable tires, and integrated lights, the RoadRunner E-Speed Lowstep ensures a smooth and enjoyable ride.",
    "description": "## Overview\n\nIt's right for you if...\nYou're looking for an e-bike that provides an extra boost to reach your destination quickly and effortlessly. You prioritize durability and want a bike with one of the fastest motors available.\n\nThe tech you get\nA lightweight and sturdy ThunderBolt aluminum frame with a lowstep geometry. The bike is equipped with a ThunderBolt Performance Sport (250W, 65Nm) drive unit capable of reaching speeds up to 28 mph. It features a long-range 500Wh battery fully integrated into the frame and a ThunderBolt controller. Additionally, the bike has a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThe RoadRunner E-Speed Lowstep is designed to provide enjoyment and ease of use on longer commutes, recreational rides, and adventurous journeys. Its long-range battery, fast ThunderBolt motor, intuitive controller, and road-smoothing suspension seatpost make it the perfect choice for riders seeking both comfort and speed.\n\n## Features\n\nSuper speedy assist\n\nThe ThunderBolt Performance Sport drive unit allows you to accelerate up to 28mph, making errands, commutes, and joyrides a breeze.\n\n## Specs\n\nFrameset\n- Frame: ThunderBolt Smooth Aluminum, Removable Integrated Battery (RIB), sleek welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: RoadRunner Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: ThunderBolt DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: ThunderBolt DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: ThunderBolt Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: ThunderBolt E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: RoadRunner City pedals\n\nComponents\n- Saddle: RoadRunner Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - RoadRunner alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - RoadRunner alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: RoadRunner Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - RoadRunner alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\n  - Size: M, L - RoadRunner alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: ThunderBolt PowerTube 500Wh\n- Charger: ThunderBolt compact 2A, 100-240V\n- Computer: ThunderBolt Purion\n- Motor: ThunderBolt Performance Line Sport, 65Nm, 28mph\n- Light:\n  - Size: XS, S, M, L - ThunderBolt SOLO for e-bike, taillight\n  - Size: XS, S, M, L - ThunderBolt MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: MIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - RoadRunner wide\n  - Size: XS, S, M, L - RoadRunner plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 4999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "Hyperdrive Turbo X1",
    "shortDescription": "Hyperdrive Turbo X1 is a high-performance electric bike designed for riders seeking an exhilarating experience on their daily rides. It features a powerful and efficient Hyperdrive Sport drive unit and a sleek, integrated 500Wh battery for extended range. This e-bike is equipped with top-of-the-line components prioritizing comfort and safety, including a suspension seatpost, wide and stable tires, and integrated lights.",
    "description": "## Overview\n\nIt's right for you if...\nYou crave the thrill of an e-bike that can accelerate rapidly, reaching high speeds effortlessly. You value durability and are looking for a bike that is equipped with one of the fastest motors available.\n\nThe tech you get\nA lightweight Hyper Alloy frame with a lowstep geometry, a Hyperdrive Sport (300W, 70Nm) drive unit capable of maintaining speeds up to 30 mph, a long-range 500Wh battery seamlessly integrated into the frame, and an intuitive Hyper Control controller. Additionally, it features a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for enhanced stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThis bike is designed for riders seeking enjoyment and convenience on longer commutes, recreational rides, and thrilling adventures. With its long-range battery, high-speed motor, user-friendly controller, and smooth-riding suspension seatpost, the Hyperdrive Turbo X1 guarantees an exceptional e-biking experience.\n\n## Features\n\nHyperboost Acceleration\nExperience adrenaline-inducing rides with the powerful Hyperdrive Sport drive unit that enables quick acceleration and effortless cruising through errands, commutes, and joyrides.\n\n## Specs\n\nFrameset\nFrame\tHyper Alloy, Removable Integrated Battery (RIB), seamless welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\nFork\tHyper Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\nMax compatible fork travel\t50mm\n\nWheels\nHub front\tFormula DC-20, alloy, 6-bolt, 5x100mm QR\nSkewer front\t132x5mm QR, ThruSkew\nHub rear\tFormula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\nSkewer rear\t153x5mm bolt-on\nRim\tHyper Connection, double-wall, 32-hole, 20 mm width, Schrader valve\nTire\tHyper E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\nMax tire size\t700x50mm with or without fenders\n\nDrivetrain\nShifter\tShimano Deore M4100, 10 speed\nRear derailleur\tShimano Deore M5120, long cage\nCrank\tProWheel alloy, 170mm length\nChainring\tFSA, 42T, steel w/guard\nCassette\tShimano Deore M4100, 11-42, 10 speed\nChain\tKMC E10\nPedal\tHyper City pedals\n\nComponents\nSaddle\tHyper Boulevard\nSeatpost\tAlloy, suspension, 31.6mm, 300mm length\n*Handlebar\tSize: XS, S, M\nHyper alloy, 31.8mm, comfort sweep, 620mm width\nSize: L\nHyper alloy, 31.8mm, comfort sweep, 660mm width\nGrips\tHyper Satellite Elite, alloy lock-on\n*Stem\tSize: XS, S\nHyper alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\nSize: M, L\nHyper alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\nHeadset\tVP sealed cartridge, 1-1/8'', threaded\nBrake\tShimano MT200 hydraulic disc\n*Brake rotor\tSize: XS, S, M, L\nShimano RT26, 6-bolt,180mm\nSize: XS, S, M, L\nShimano RT26, 6-bolt,160mm\n\nAccessories\nBattery\tHyper PowerTube 500Wh\nCharger\tHyper compact 2A, 100-240V\nComputer\tHyper Control\nMotor\tHyperdrive Sport, 70Nm, 30mph\n*Light\tSize: XS, S, M, L\nSpanninga SOLO for e-bike, taillight\nSize: XS, S, M, L\nHerrmans MR8, 180 lumen, 60 lux, LED, headlight\nKickstand\tAdjustable length rear mount alloy kickstand\nCargo rack\tMIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n*Fender\tSize: XS, S, M, L\nSKS wide\nSize: XS, S, M, L\nSKS plastic\n\nWeight\nWeight\tM - 22.30 kg / 49.17 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 1999.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  },
  {
    "name": "Horizon+ Evo Lowstep",
    "shortDescription": "The Horizon+ Evo Lowstep is a versatile electric hybrid bike designed for riders seeking a thrilling and efficient riding experience on a variety of terrains. With its powerful Bosch Performance Line Sport drive unit and integrated 500Wh battery, this e-bike enables riders to cover long distances with ease. Equipped with features prioritizing comfort and safety, such as a suspension seatpost, stable tires, and integrated lights, the Horizon+ Evo Lowstep is a reliable companion for everyday rides.",
    "description": "## Overview\n\nIt's right for you if...\nYou desire the convenience and speed of an e-bike to enhance your riding, and you want an intuitive and durable bicycle. You prioritize having one of the fastest motors developed by Bosch.\n\nThe tech you get\nA lightweight Alpha Smooth Aluminum frame with a lowstep geometry, a Bosch Performance Line Sport (250W, 65Nm) drive unit capable of sustaining speeds up to 28 mph, a fully encased 500Wh battery integrated into the frame, and a Bosch Purion controller. Additionally, it features a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for improved stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThe Horizon+ Evo Lowstep offers an enjoyable and user-friendly riding experience for longer commutes, recreational rides, and adventures. It boasts an extended range battery, a high-performance Bosch motor, an intuitive controller, and a suspension seatpost for a smooth ride on various road surfaces.\n\n## Features\n\nSuper speedy assist\nExperience effortless cruising through errands, commutes, and joyrides with the new Bosch Performance Sport drive unit, allowing acceleration of up to 28 mph.\n\n## Specs\n\nFrameset\n- Frame: Alpha Platinum Aluminum, Removable Integrated Battery (RIB), smooth welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: Horizon Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Front Hub: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Front Skewer: 132x5mm QR, ThruSkew\n- Rear Hub: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Rear Skewer: 153x5mm bolt-on\n- Rim: Bontrager Connection, double-wall, 32-hole, 20mm width, Schrader valve\n- Tire: Bontrager E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10-speed\n- Rear Derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10-speed\n- Chain: KMC E10\n- Pedal: Bontrager City pedals\n\nComponents\n- Saddle: Bontrager Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - Bontrager alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - Bontrager alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: Bontrager Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - Bontrager alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\n  - Size: M, L - Bontrager alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\n- Headset: VP sealed cartridge, 1-1/8\", threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: Bosch PowerTube 500Wh\n- Charger: Bosch compact 2A, 100-240V\n- Computer: Bosch Purion\n- Motor: Bosch Performance Line Sport, 65Nm, 28mph\n- Light:\n  - Size: XS, S, M, L - Spanninga SOLO for e-bike, taillight\n  - Size: XS, S, M, L - Herrmans MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: MIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - SKS wide\n  - Size: XS, S, M, L - SKS plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 4499.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "FastRider X1",
    "shortDescription": "FastRider X1 is a high-performance e-bike designed for riders seeking speed and long-distance capabilities. Equipped with a powerful motor and a high-capacity battery, the FastRider X1 is perfect for daily commuters and e-bike enthusiasts. It boasts a sleek and functional design, making it a great alternative to car transportation. The bike also features a smartphone controller for easy navigation and entertainment options.",
    "description": "## Overview\nIt's right for you if...\nYou're looking for an e-bike that offers both speed and endurance. The FastRider X1 comes with a high-performance motor and a long-lasting battery, making it ideal for long-distance rides.\n\nThe tech you get\nThe FastRider X1 features a state-of-the-art motor and a spacious battery, ensuring a fast and efficient ride.\n\nThe final word\nWith the powerful motor and long-range battery, the FastRider X1 allows you to cover more distance at higher speeds.\n\n## Features\nConnect Your Ride with the FastRider App\nDownload the FastRider app and transform your smartphone into an on-board computer. Easily dock and charge your phone with the smartphone controller, and use the thumb pad on your handlebar to make calls, listen to music, get turn-by-turn directions, and more. The app also allows you to connect with fitness and health apps, syncing your routes and ride data.\n\nGoodbye, Car. Hello, Extended Range!\nWith the option to add the Range Boost feature, you can attach a second long-range battery to your FastRider X1, doubling the distance and time between charges. This enhancement allows you to ride longer, commute farther, and take on more adventurous routes.\n\nWhat is the range?\nTo estimate the distance you can travel on a single charge, use our range calculator tool. It automatically fills in the variables for this specific bike model and assumes an average rider, but you can adjust the settings to get the most accurate estimate for your needs.\n\n## Specifications\nFrameset\n- Frame: High-performance hydroformed alloy, Removable Integrated Battery, Range Boost-compatible, internal cable routing, Motor Armour, post-mount disc, 135x5 mm QR\n- Fork: FastRider rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru axle, post mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: FastRider sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: FastRider Switch thru axle, removable lever\n- Rear Hub: FastRider alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: FastRider MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: Size: M, L, XL - 14g stainless steel, black\n- Tire: FastRider E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Size: M, L, XL - Shimano Deore M5120, long cage\n- Crank: Size: M - FastRider alloy, 170mm length / Size: L, XL - FastRider alloy, 175mm length\n- Chainring: FastRider 46T narrow/wide alloy, w/alloy guard\n- Cassette: Size: M, L, XL - Shimano Deore M4100, 11-42, 10 speed\n- Chain: Size: M, L, XL - KMC E10 / Size: M, L, XL - KMC X10e\n- Pedal: Size: M, L, XL - FastRider City pedals / Size: M, L, XL - Wellgo C157, boron axle, plastic body / Size: M, L, XL - slip-proof aluminum pedals with reflectors\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: FastRider Commuter Comp\n- Seatpost: FastRider Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Size: M - FastRider alloy, 31.8mm, 15mm rise, 600mm width / Size: L, XL - FastRider alloy, 31.8mm, 15mm rise, 660mm width\n- Grips: FastRider Satellite Elite, alloy lock-on\n- Stem: Size: M - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length / Size: L - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length / Size: XL - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\n- Headset: Size: M, L, XL - FSA IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom / Size: M, L, XL - FSA Integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\n- Battery: FastRider PowerTube 625Wh\n- Charger: FastRider standard 4A, 100-240V\n- Motor: FastRider Performance Speed, 85 Nm, 28 mph / 45 kph\n- Light: Size: M, L, XL - FastRider taillight, 50 lumens / Size: M, L, XL - FastRider headlight, 500 lumens\n- Kickstand: Size: M, L, XL - Rear mount, alloy / Size: M, L, XL - Adjustable length alloy kickstand\n- Cargo rack: FastRider integrated rear rack, aluminum\n- Fender: FastRider custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n\nWeight limit\n- This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         | M     | L     | XL    |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 5499.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "SonicRide 8S",
    "shortDescription": "SonicRide 8S is a high-performance e-bike designed for riders who crave speed and long-distance capabilities. The advanced SonicDrive motor provides powerful assistance up to 28 mph, combined with a durable and long-lasting battery for extended rides. With its sleek design and thoughtful features, the SonicRide 8S is perfect for those who prefer the freedom of riding a bike over driving a car. Plus, it comes equipped with a smartphone controller for easy navigation, music, and more.",
    "description": "## Overview\nIt's right for you if...\nYou want a fast and efficient e-bike that can take you long distances. The SonicRide 8S features a hydroformed aluminum frame with a concealed 625Wh battery, a high-powered SonicDrive motor, and a Smartphone Controller. It also includes essential accessories such as lights, fenders, and a rear rack.\n\nThe tech you get\nThe SonicRide 8S is equipped with the fastest SonicDrive motor, ensuring exhilarating rides at high speeds. The long-range battery is perfect for commuters and riders looking to explore new horizons.\n\nThe final word\nWith the SonicDrive motor and long-lasting battery, you can enjoy extended rides at higher speeds.\n\n## Features\n\nConnect Your Ride with SonicRide App\nDownload the SonicRide app and transform your phone into an onboard computer. Simply attach it to the Smartphone Controller for docking and charging. Use the thumb pad on your handlebar to control calls, music, directions, and more. The Bluetooth® wireless technology allows you to connect with fitness and health apps, syncing your routes and ride data.\n\nSay Goodbye to Limited Range with Range Boost!\nExperience the convenience of Range Boost, an additional long-range 500Wh battery that seamlessly attaches to your bike's down tube. This upgrade allows you to double your distance and time between charges, enabling longer commutes and more adventurous rides. Range Boost is compatible with select SonicRide electric bike models.\n\nWhat is the range?\nFor an accurate estimate of how far you can ride on a single charge, use SonicRide's range calculator. We have pre-filled the variables for this specific bike model and the average rider, but you can adjust them to obtain the most accurate estimate.\n\n## Specifications\nFrameset\n- Frame: High-performance hydroformed alloy, Removable Integrated Battery, Range Boost-compatible, internal cable routing, Motor Armour, post-mount disc, 135x5 mm QR\n- Fork: SonicRide rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru axle, post mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: SonicRide sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: SonicRide Switch thru axle, removable lever\n- Rear Hub: SonicRide alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: SonicRide MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: Size: M, L, XL - 14g stainless steel, black\n- Tire: SonicRide E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear Derailleur: Size: M, L, XL - Shimano Deore M5120, long cage\n- Crank: Size: M - SonicRide alloy, 170mm length; Size: L, XL - SonicRide alloy, 175mm length\n- Chainring: SonicRide 46T narrow/wide alloy, with alloy guard\n- Cassette: Size: M, L, XL - Shimano Deore M4100, 11-42, 10 speed\n- Chain: Size: M, L, XL - KMC E10; Size: M, L, XL - KMC X10e\n- Pedal: Size: M, L, XL - SonicRide City pedals; Size: M, L, XL - Wellgo C157, boron axle, plastic body; Size: M, L, XL - slip-proof aluminum pedals with reflectors\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: SonicRide Commuter Comp\n- Seatpost: SonicRide Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Size: M - SonicRide alloy, 31.8mm, 15mm rise, 600mm width; Size: L, XL - SonicRide alloy, 31.8mm, 15mm rise, 660mm width\n- Grips: SonicRide Satellite Elite, alloy lock-on\n- Stem: Size: M - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length; Size: L - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length; Size: XL - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\n- Headset: Size: M, L, XL - SonicRide IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom; Size: M, L, XL - SonicRide Integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\n- Battery: SonicRide PowerTube 625Wh\n- Charger: SonicRide standard 4A, 100-240V\n- Motor: SonicRide Performance Speed, 85 Nm, 28 mph / 45 kph\n- Light: Size: M, L, XL - SonicRide Lync taillight, 50 lumens; Size: M, L, XL - SonicRide Lync headlight, 500 lumens\n- Kickstand: Size: M, L, XL - Rear mount, alloy; Size: M, L, XL - Adjustable length alloy kickstand\n- Cargo rack: SonicRide integrated rear rack, aluminum\n- Fender: SonicRide custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm / 5'5\" - 5'9\" | 77 - 83 cm / 30\" - 33\" |\n|   L  | 175 - 186 cm / 5'9\" - 6'1\" | 82 - 88 cm / 32\" - 35\" |\n|  XL  | 186 - 197 cm / 6'1\" - 6'6\" | 87 - 93 cm / 34\" - 37\" |\n\n## Geometry\n| Frame size letter         |   M   |   L   |   XL  |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |",
    "price": 5999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "SwiftVolt Pro",
    "shortDescription": "SwiftVolt Pro is a high-performance e-bike designed for riders seeking a thrilling and fast riding experience. Equipped with a powerful SwiftDrive motor that provides assistance up to 30 mph and a long-lasting battery, this bike is perfect for long-distance commuting and passionate e-bike enthusiasts. The sleek and innovative design features cater specifically to individuals who prioritize cycling over driving. Additionally, the bike is seamlessly integrated with your smartphone, allowing you to use it for navigation, music, and more.",
    "description": "## Overview\nThis bike is ideal for you if:\n- You desire a sleek and modern hydroformed aluminum frame that houses a 700Wh battery.\n- You want to maintain high speeds of up to 30 mph with the assistance of the SwiftDrive motor.\n- You appreciate the convenience of using your smartphone as a controller, which can be docked and charged on the handlebar.\n\n## Features\n\nConnect with SwiftSync App\nBy downloading the SwiftSync app, your smartphone becomes an interactive on-board computer. Attach it to the handlebar-mounted controller for easy access and charging. With the thumb pad, you can make calls, listen to music, receive turn-by-turn directions, and connect with fitness and health apps to track your routes and ride data via Bluetooth® wireless technology.\n\nEnhanced Range with BoostMax\nBoostMax offers the capability to attach a second 700Wh Swift battery to the downtube of your bike, effectively doubling the distance and time between charges. This allows for extended rides, longer commutes, and more significant adventures. BoostMax is compatible with select Swift electric bike models.\n\nRange Estimation\nFor an estimate of how far you can ride on a single charge, consult the Swift range calculator. The variables are automatically populated based on this bike model and the average rider, but you can modify them to obtain the most accurate estimate.\n\n## Specifications\nFrameset\n- Frame: Lightweight hydroformed alloy, Removable Integrated Battery, BoostMax-compatible, internal cable routing, post-mount disc, 135x5 mm QR\n- Fork: SwiftVolt rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru-axle, post-mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: Swift sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: Swift Switch thru-axle, removable lever\n- Rear Hub: Swift alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: SwiftRim, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: 14g stainless steel, black\n- Tire: Swift E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear Derailleur: Shimano Deore M5120, long cage\n- Crank: Swift alloy, 170mm length\n- Chainring: Swift 46T narrow/wide alloy, w/alloy guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: Swift City pedals\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: Swift Commuter Comp\n- Seatpost: Swift Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Swift alloy, 31.8mm, 15mm rise, 600mm width (M), 660mm width (L, XL)\n- Grips: Swift Satellite Elite, alloy lock-on\n- Stem: Swift alloy, 31.8mm, Blendr compatible, 7 degree, 70mm length (M), 90mm length (L), 100mm length (XL)\n- Headset: FSA IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brakes: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake Rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max 180mm front & rear\n\nAccessories\n- Battery: Swift PowerTube 700Wh\n- Charger: Swift standard 4A, 100-240V\n- Motor: SwiftDrive, 90 Nm, 30 mph / 48 kph\n- Light: Swift Lync taillight, 50 lumens (M, L, XL), Swift Lync headlight, 500 lumens (M, L, XL)\n- Kickstand: Rear mount, alloy (M, L, XL), Adjustable length alloy kickstand (M, L, XL)\n- Cargo rack: SwiftVolt integrated rear rack, aluminum\n- Fender: Swift custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |     Rider Height      |     Inseam    |\n|:----:|:---------------------:|:-------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         | M     | L     | XL    |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 2499.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  },
  {
    "name": "AgileEon 9X",
    "shortDescription": "AgileEon 9X is a high-performance e-bike designed for riders seeking speed and endurance. Equipped with a robust motor and an extended battery life, this bike is perfect for long-distance commuters and avid e-bike enthusiasts. It boasts innovative features tailored for individuals who prioritize cycling over driving. Additionally, the bike integrates seamlessly with your smartphone, allowing you to access navigation, music, and more.",
    "description": "## Overview\nIt's right for you if...\nYou crave speed and want to cover long distances efficiently. The AgileEon 9X features a sleek hydroformed aluminum frame that houses a powerful motor, along with a large-capacity battery for extended rides. It comes equipped with a 10-speed drivetrain, front and rear lighting, fenders, and a rear rack.\n\nThe tech you get\nDesigned for those constantly on the move, this bike includes a state-of-the-art motor and a high-capacity battery, making it an excellent choice for lengthy commutes.\n\nThe final word\nWith the AgileEon 9X, you can push your boundaries and explore new horizons thanks to its powerful motor and long-lasting battery.\n\n## Features\n\nConnect Your Ride with RideMate App\nMake use of the RideMate app to transform your smartphone into an onboard computer. Simply attach it to the RideMate controller to dock and charge, then utilize the thumb pad on your handlebar to make calls, listen to music, receive turn-by-turn directions, and more. The bike also supports Bluetooth® wireless technology, enabling seamless connectivity with fitness and health apps for route syncing and ride data.\n\nGoodbye, car. Hello, Extended Range!\nEnhance your riding experience with the Extended Range option, which allows for the attachment of an additional high-capacity 500Wh battery to your bike's downtube. This doubles the distance and time between charges, enabling longer rides, extended commutes, and more significant adventures. The Extended Range feature is compatible with select AgileEon electric bike models.\n\nWhat is the range?\nTo determine how far you can ride on a single charge, you can utilize the range calculator provided by AgileEon. We have pre-filled the variables for this specific model and an average rider, but adjustments can be made for a more accurate estimation.\n\n## Specifications\nFrameset\nFrame: High-performance hydroformed alloy, Removable Integrated Battery, Extended Range-compatible, internal cable routing, Motor Armor, post-mount disc, 135x5 mm QR\nFork: AgileEon rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru-axle, post-mount disc brake\nMax compatible fork travel: 63mm\n\nWheels\nFront Hub: AgileEon sealed bearing, 32-hole 15mm alloy thru-axle\nFront Skewer: AgileEon Switch thru-axle, removable lever\nRear Hub: AgileEon alloy, sealed bearing, 6-bolt, 135x5mm QR\nRear Skewer: 148x5mm bolt-on\nRim: AgileEon MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\nSpokes:\n- Size: M, L, XL: 14g stainless steel, black\nTire: AgileEon E6 Hard-Case Lite, reflective strip, 27.5x2.40''\nMax tire size: 27.5x2.40\"\n\nDrivetrain\nShifter: Shimano Deore M4100, 10-speed\nRear derailleur:\n- Size: M, L, XL: Shimano Deore M5120, long cage\nCrank:\n- Size: M: AgileEon alloy, 170mm length\n- Size: L, XL: AgileEon alloy, 175mm length\nChainring: AgileEon 46T narrow/wide alloy, with alloy guard\nCassette:\n- Size: M, L, XL: Shimano Deore M4100, 11-42, 10-speed\nChain:\n- Size: M, L, XL: KMC E10\nPedal:\n- Size: M, L, XL: AgileEon City pedals\nMax chainring size: 1x: 48T\n\nComponents\nSaddle: AgileEon Commuter Comp\nSeatpost: AgileEon Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\nHandlebar:\n- Size: M: AgileEon alloy, 31.8mm, 15mm rise, 600mm width\n- Size: L, XL: AgileEon alloy, 31.8mm, 15mm rise, 660mm width\nGrips: AgileEon Satellite Elite, alloy lock-on\nStem:\n- Size: M: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length\n- Size: L: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length\n- Size: XL: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\nHeadset:\n- Size: M, L, XL: AgileEon IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\nBrake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\nBrake rotor: Shimano RT56, 6-bolt, 180mm\nRotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\nBattery: AgileEon PowerTube 625Wh\nCharger: AgileEon standard 4A, 100-240V\nMotor: AgileEon Performance Speed, 85 Nm, 28 mph / 45 kph\nLight:\n- Size: M, L, XL: AgileEon taillight, 50 lumens\n- Size: M, L, XL: AgileEon headlight, 500 lumens\nKickstand:\n- Size: M, L, XL: Rear mount, alloy\n- Size: M, L, XL: Adjustable length alloy kickstand\nCargo rack: AgileEon integrated rear rack, aluminum\nFender: AgileEon custom aluminum\n\nWeight\nWeight: M - 25.54 kg / 56.3 lbs\nWeight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         |   M   |   L   |   XL  |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 3499.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "Stealth R1X Pro",
    "shortDescription": "Stealth R1X Pro is a high-performance carbon road bike designed for riders who crave speed and exceptional handling. With its aerodynamic tube shaping, disc brakes, and lightweight carbon wheels, the Stealth R1X Pro offers unparalleled performance for competitive road cycling.",
    "description": "## Overview\nIt's right for you if...\nYou're a competitive cyclist looking for a road bike that offers superior performance in terms of speed, handling, and aerodynamics. You want a complete package that includes lightweight carbon wheels, without the need for future upgrades.\n\nThe tech you get\nThe Stealth R1X Pro features a lightweight and aerodynamic carbon frame, an advanced carbon fork, high-performance Shimano Ultegra 11-speed drivetrain, and powerful Ultegra disc brakes. The bike also comes equipped with cutting-edge Bontrager Aeolus Elite 35 carbon wheels.\n\nThe final word\nThe Stealth R1X Pro stands out with its combination of a fast and aerodynamic frame, high-end drivetrain, and top-of-the-line carbon wheels. Whether you're racing on local roads, participating in pro stage races, or engaging in hill climbing competitions, this bike is a formidable choice that delivers an exceptional riding experience.\n\n## Features\nSleek and aerodynamic design\nThe Stealth R1X Pro's aero tube shapes maximize speed and performance, making it faster on climbs and flats alike. The bike also features a streamlined Aeolus RSL bar/stem for improved front-end aerodynamics.\n\nDesigned for all riders\nThe Stealth R1X Pro is designed to provide an outstanding fit for riders of all genders, body types, riding styles, and abilities. It comes equipped with size-specific components to ensure a comfortable and efficient riding position for competitive riders.\n\n## Specifications\nFrameset\n- Frame: Ultralight carbon frame constructed with high-performance 500 Series ADV Carbon. It features Ride Tuned performance tube optimization, a tapered head tube, internal routing, DuoTrap S compatibility, flat mount disc brake mounts, and a 142x12mm thru axle.\n- Fork: Full carbon fork (Émonda SL) with a tapered carbon steerer, internal brake routing, flat mount disc brake mounts, and a 12x100mm thru axle.\n- Frame fit: H1.5 Race geometry.\n\nWheels\n- Front wheel: Bontrager Aeolus Elite 35 carbon wheel with a 35mm rim depth, ADV Carbon construction, Tubeless Ready compatibility, and a 100x12mm thru axle.\n- Rear wheel: Bontrager Aeolus Elite 35 carbon wheel with a 35mm rim depth, ADV Carbon construction, Tubeless Ready compatibility, Shimano 11/12-speed freehub, and a 142x12mm thru axle.\n- Front skewer: Bontrager Switch thru axle with a removable lever.\n- Rear skewer: Bontrager Switch thru axle with a removable lever.\n- Tire: Bontrager R2 Hard-Case Lite with an aramid bead, 60 tpi, and a size of 700x25c.\n- Maximum tire size: 28mm.\n\nDrivetrain\n- Shifter:\n  - Size 47, 50, 52: Shimano Ultegra R8025 with short-reach levers, 11-speed.\n  - Size 54, 56, 58, 60, 62: Shimano Ultegra R8020, 11-speed.\n- Front derailleur: Shimano Ultegra R8000, braze-on.\n- Rear derailleur: Shimano Ultegra R8000, short cage, with a maximum cog size of 30T.\n- Crank:\n  - Size 47: Shimano Ultegra R8000 with 52/36 chainrings and a 165mm length.\n  - Size 50, 52: Shimano Ultegra R8000 with 52/36 chainrings and a 170mm length.\n  - Size 54, 56, 58: Shimano Ultegra R8000 with 52/36 chainrings and a 172.5mm length.\n  - Size 60, 62: Shimano Ultegra R8000 with 52/36 chainrings and a 175mm length.\n- Bottom bracket: Praxis T47 threaded bottom bracket with internal bearings.\n- Cassette: Shimano Ultegra R8000, 11-30, 11-speed.\n- Chain: Shimano Ultegra HG701, 11-speed.\n- Maximum chainring size: 1x - 50T, 2x - 53/39.\n\nComponents\n- Saddle: Bontrager Aeolus Comp with steel rails and a width of 145mm.\n- Seatpost:\n  - Size 47, 50, 52, 54: Bontrager carbon seatmast cap with a 20mm offset and a short length.\n  - Size 56, 58, 60, 62: Bontrager carbon seatmast cap with a 20mm offset and a tall length.\n- Handlebar:\n  - Size 47, 50: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 38cm.\n  - Size 52: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 40cm.\n  - Size 54, 56, 58: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 42cm.\n  - Size 60, 62: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 44cm.\n- Handlebar tape: Bontrager Supertack Perf tape.\n- Stem:\n  - Size 47: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 70mm.\n  - Size 50: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 80mm.\n  - Size 52, 54: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 90mm.\n  - Size 56: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 100mm.\n  - Size 58, 60, 62: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 110mm.\n- Brake: Shimano Ultegra hydraulic disc brakes with flat mount calipers.\n- Brake rotor: Shimano RT800 with centerlock mounting, 160mm diameter.\n\nWeight\n- Weight: 8.03 kg (17.71 lbs) for the 56cm frame.\n- Weight limit: The bike has a maximum total weight limit (combined weight of the bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\nPlease refer to the table below for the corresponding Stealth R1X Pro frame sizes, recommended rider height range, and inseam measurements:\n\n| Size |      Rider Height     |     Inseam     |\n|:----:|:---------------------:|:--------------:|\n|  47  |  152 - 158 cm (5'0\")  |  71 - 75 cm    |\n|  50  |  158 - 163 cm (5'2\")  |  74 - 77 cm    |\n|  52  |  163 - 168 cm (5'4\")  |  76 - 79 cm    |\n|  54  |  168 - 174 cm (5'6\")  |  78 - 82 cm    |\n|  56  | 174 - 180 cm (5'9\")  |  81 - 85 cm    |\n|  58  | 180 - 185 cm (5'11\") |  84 - 87 cm    |\n|  60  |  185 - 190 cm (6'1\")  |  86 - 90 cm    |\n|  62  |  190 - 195 cm (6'3\")  |  89 - 92 cm    |\n\n## Geometry\nThe table below provides the geometry measurements for each frame size of the Stealth R1X Pro:\n\n| Frame size number              | 47 cm | 50 cm | 52 cm | 54 cm | 56 cm | 58 cm | 60 cm | 62 cm |\n|-------------------------------|-------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size                    | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                 | 42.4  | 45.3  | 48.3  | 49.6  | 52.5  | 55.3  | 57.3  | 59.3  |\n| B — Seat tube angle           | 74.6° | 74.6° | 74.2° | 73.7° | 73.3° | 73.0° | 72.8° | 72.5° |\n| C — Head tube length          | 10.0  | 11.1  | 12.1  | 13.1  | 15.1  | 17.1  | 19.1  | 21.1  |\n| D — Head angle                | 72.1° | 72.1° | 72.8° | 73.0° | 73.5° | 73.8° | 73.9° | 73.9° |\n| E — Effective top tube        | 51.2  | 52.1  | 53.4  | 54.3  | 55.9  | 57.4  | 58.6  | 59.8  |\n| G — Bottom bracket drop       | 7.2   | 7.2   | 7.2   | 7.0   | 7.0   | 6.8   | 6.8   | 6.8   |\n| H — Chainstay length          | 41.0  | 41.0  | 41.0  | 41.0  | 41.0  | 41.1  | 41.1  | 41.2  |\n| I — Offset                    | 4.5   | 4.5   | 4.5   | 4.5   | 4.0   | 4.0   | 4.0   | 4.0   |\n| J — Trail                     | 6.8   | 6.2   | 5.8   | 5.6   | 5.8   | 5.7   | 5.6   | 5.6   |\n| K — Wheelbase                 | 97.2  | 97.4  | 97.7  | 98.1  | 98.3  | 99.2  | 100.1 | 101.0 |\n| L — Standover                 | 69.2  | 71.1  | 73.2  | 74.4  | 76.8  | 79.3  | 81.1  | 82.9  |\n| M — Frame reach               | 37.3  | 37.8  | 38.3  | 38.6  | 39.1  | 39.6  | 39.9  | 40.3  |\n| N — Frame stack               | 50.7  | 52.1  | 53.3  | 54.1  | 56.3  | 58.1  | 60.1  | 62.0  |\n| Saddle rail height min (short mast) | 55.5 | 58.5 | 61.5 | 64.0 | 67.0 | 69.0 | 71.0 | 73.0 |\n| Saddle rail height max (short mast) | 61.5 | 64.5 | 67.5 | 70.0 | 73.0 | 75.0 | 77.0 | 79.0 |\n| Saddle rail height min (tall mast)  | 59.0 | 62.0 | 65.0 | 67.5 | 70.5 | 72.5 | 74.5 | 76.5 |\n| Saddle rail height max (tall mast)  | 65.0 | 68.0 | 71.0 | 73.5 | 76.5 | 78.5 | 80.5 | 82.5 |",
    "price": 2999.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "Avant SLR 6 Disc Pro",
    "shortDescription": "Avant SLR 6 Disc Pro is a high-performance carbon road bike designed for riders who prioritize speed and handling. With its aero tube shaping, disc brakes, and lightweight carbon wheels, it offers the perfect balance of speed and control.",
    "description": "## Overview\nIt's right for you if...\nYou're a rider who values exceptional performance on fast group rides and races, and you want a complete package that includes lightweight carbon wheels. The Avant SLR 6 Disc Pro is designed to provide the speed and aerodynamics you need to excel on any road.\n\nThe tech you get\nThe Avant SLR 6 Disc Pro features a lightweight 500 Series ADV Carbon frame and fork, Bontrager Aeolus Elite 35 carbon wheels, a full Shimano Ultegra 11-speed drivetrain, and powerful Ultegra disc brakes.\n\nThe final word\nThe standout feature of this bike is the combination of its aero frame, high-performance drivetrain, and top-quality carbon wheels. Whether you're racing, tackling challenging climbs, or participating in professional stage races, the Avant SLR 6 Disc Pro is a worthy choice that will enhance your performance.\n\n## Features\nAll-new aero design\nThe Avant SLR 6 Disc Pro features innovative aero tube shapes that provide an advantage in all riding conditions, whether it's climbing or riding on flat roads. Additionally, it is equipped with a sleek new Aeolus RSL bar/stem that enhances front-end aero performance.\n\nAwesome bikes for everyone\nThe Avant SLR 6 Disc Pro is designed with the belief that every rider, regardless of gender, body type, riding style, or ability, deserves a great bike. It is equipped with size-specific components that ensure a perfect fit for competitive riders of all genders.\n\n## Specifications\nFrameset\n- Frame: Ultralight 500 Series ADV Carbon, Ride Tuned performance tube optimization, tapered head tube, internal routing, DuoTrap S compatible, flat mount disc, 142x12mm thru axle\n- Fork: Avant SL full carbon, tapered carbon steerer, internal brake routing, flat mount disc, 12x100mm thru axle\n- Frame fit: H1.5 Race\n\nWheels\n- Front wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, 100x12mm thru axle\n- Rear wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, Shimano 11/12-speed freehub, 142x12mm thru axle\n- Front skewer: Bontrager Switch thru axle, removable lever\n- Rear skewer: Bontrager Switch thru axle, removable lever\n- Tire: Bontrager R2 Hard-Case Lite, aramid bead, 60 tpi, 700x25c\n- Max tire size: 28mm\n\nDrivetrain\n- Shifter: \n    - Size 47, 50, 52: Shimano Ultegra R8025, short-reach lever, 11-speed\n    - Size 54, 56, 58, 60, 62: Shimano Ultegra R8020, 11-speed\n- Front derailleur: Shimano Ultegra R8000, braze-on\n- Rear derailleur: Shimano Ultegra R8000, short cage, 30T max cog\n- Crank: \n    - Size 47: Shimano Ultegra R8000, 52/36, 165mm length\n    - Size 50, 52: Shimano Ultegra R8000, 52/36, 170mm length\n    - Size 54, 56, 58: Shimano Ultegra R8000, 52/36, 172.5mm length\n    - Size 60, 62: Shimano Ultegra R8000, 52/36, 175mm length\n- Bottom bracket: Praxis, T47 threaded, internal bearing\n- Cassette: Shimano Ultegra R8000, 11-30, 11-speed\n- Chain: Shimano Ultegra HG701, 11-speed\n- Max chainring size: 1x: 50T, 2x: 53/39\n\nComponents\n- Saddle: Bontrager Aeolus Comp, steel rails, 145mm width\n- Seatpost: \n    - Size 47, 50, 52, 54: Bontrager carbon seatmast cap, 20mm offset, short length\n    - Size 56, 58, 60, 62: Bontrager carbon seatmast cap, 20mm offset, tall length\n- Handlebar: \n    - Size 47, 50: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 38cm width\n    - Size 52: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 40cm width\n    - Size 54, 56, 58: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 42cm width\n    - Size 60, 62: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 44cm width\n- Handlebar tape: Bontrager Supertack Perf tape\n- Stem: \n    - Size 47: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 70mm length\n    - Size 50: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 80mm length\n    - Size 52, 54: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 90mm length\n    - Size 56: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 100mm length\n    - Size 58, 60, 62: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 110mm length\n- Brake: Shimano Ultegra hydraulic disc, flat mount\n- Brake rotor: Shimano RT800, centerlock, 160mm\n\nWeight\n- Weight: 56 - 8.03 kg / 17.71 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  47  |  152 - 158 cm 5'0\" - 5'2\" | 71 - 75 cm 28\" - 30\" |\n|  50  |  158 - 163 cm 5'2\" - 5'4\" | 74 - 77 cm 29\" - 30\" |\n|  52  |  163 - 168 cm 5'4\" - 5'6\" | 76 - 79 cm 30\" - 31\" |\n|  54  |  168 - 174 cm 5'6\" - 5'9\" | 78 - 82 cm 31\" - 32\" |\n|  56  | 174 - 180 cm 5'9\" - 5'11\" | 81 - 85 cm 32\" - 33\" |\n|  58  | 180 - 185 cm 5'11\" - 6'1\" | 84 - 87 cm 33\" - 34\" |\n|  60  |  185 - 190 cm 6'1\" - 6'3\" | 86 - 90 cm 34\" - 35\" |\n|  62  |  190 - 195 cm 6'3\" - 6'5\" | 89 - 92 cm 35\" - 36\" |\n\n## Geometry\n| Frame size number                     | 47 cm | 50 cm | 52 cm | 54 cm | 56 cm | 58 cm | 60 cm | 62 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 42.4  | 45.3  | 48.3  | 49.6  | 52.5  | 55.3  | 57.3  | 59.3  |\n| B — Seat tube angle                   | 74.6° | 74.6° | 74.2° | 73.7° | 73.3° | 73.0° | 72.8° | 72.5° |\n| C — Head tube length                  | 10.0  | 11.1  | 12.1  | 13.1  | 15.1  | 17.1  | 19.1  | 21.1  |\n| D — Head angle                        | 72.1° | 72.1° | 72.8° | 73.0° | 73.5° | 73.8° | 73.9° | 73.9° |\n| E — Effective top tube                | 51.2  | 52.1  | 53.4  | 54.3  | 55.9  | 57.4  | 58.6  | 59.8  |\n| G — Bottom bracket drop               | 7.2   | 7.2   | 7.2   | 7.0   | 7.0   | 6.8   | 6.8   | 6.8   |\n| H — Chainstay length                  | 41.0  | 41.0  | 41.0  | 41.0  | 41.0  | 41.1  | 41.1  | 41.2  |\n| I — Offset                            | 4.5   | 4.5   | 4.5   | 4.5   | 4.0   | 4.0   | 4.0   | 4.0   |\n| J — Trail                             | 6.8   | 6.2   | 5.8   | 5.6   | 5.8   | 5.7   | 5.6   | 5.6   |\n| K — Wheelbase                         | 97.2  | 97.4  | 97.7  | 98.1  | 98.3  | 99.2  | 100.1 | 101.0 |\n| L — Standover                         | 69.2  | 71.1  | 73.2  | 74.4  | 76.8  | 79.3  | 81.1  | 82.9  |\n| M — Frame reach                       | 37.3  | 37.8  | 38.3  | 38.6  | 39.1  | 39.6  | 39.9  | 40.3  |\n| N — Frame stack                       | 50.7  | 52.1  | 53.3  | 54.1  | 56.3  | 58.1  | 60.1  | 62.0  |\n| Saddle rail height min (w/short mast) | 55.5  | 58.5  | 61.5  | 64.0  | 67.0  | 69.0  | 71.0  | 73.0  |\n| Saddle rail height max (w/short mast) | 61.5  | 64.5  | 67.5  | 70.0  | 73.0  | 75.0  | 77.0  | 79.0  |\n| Saddle rail height min (w/tall mast)  | 59.0  | 62.0  | 65.0  | 67.5  | 70.5  | 72.5  | 74.5  | 76.5  |\n| Saddle rail height max (w/tall mast)  | 65.0  | 68.0  | 71.0  | 73.5  | 76.5  | 78.5  | 80.5  | 82.5  |",
    "price": 999.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  }
]

---

### Spring Ai Client Chat/Src/Test/Resources/Text Source (spring-ai-client-chat/src/test/resources/text_source.txt)

Spring                 Framework                               Documentation


                                                                                                                        Version    6.0.0

            Chapter                1.    Spring              Framework                         Overview


            Spring makes it easy to create Java enterprise applications. It provides everything you need to
            embrace    the  Java   language    in  an  enterprise    environment,      with   support   for  Groovy    and   Kotlin   as
            alternative languages on the JVM, and with the flexibility to create many kinds of architectures
            depending     on  an  application’s    needs.  As  of  Spring   Framework      5.1, Spring   requires    JDK  8+  (Java  SE
            8+) and provides out-of-the-box support for JDK 11 LTS. Java SE 8 update 60 is suggested as the
            minimum      patch  release   for Java  8, but  it is  generally  recommended       to  use a  recent  patch   release.

            Spring  supports    a wide   range   of application    scenarios.   In  a large  enterprise,   applications    often  exist
            for a  long  time   and   have   to run   on  a  JDK  and   application    server   whose    upgrade     cycle  is beyond
            developer    control.   Others   may    run  as  a single   jar with   the  server   embedded,      possibly   in  a cloud
            environment.      Yet others   may    be standalone     applications    (such   as  batch   or integration    workloads)
            that do  not  need   a server.


            Spring  is open   source.   It  has  a large  and active  community      that  provides   continuous     feedback    based
            on a  diverse   range  of  real-world   use  cases.  This  has  helped    Spring  to  successfully   evolve   over  a  very
            long  time.

            1.1.    What          We      Mean          by    "Spring"


            The  term   "Spring"   means    different   things  in  different   contexts.  It can  be  used   to refer  to the  Spring
            Framework      project   itself,  which  is where    it  all  started.  Over time,  other  Spring   projects   have   been
            built on  top  of  the Spring    Framework.      Most   often,  when    people   say  "Spring",   they  mean    the  entire
            family  of  projects.  This  reference    documentation       focuses   on  the foundation:     the  Spring   Framework
            itself.


            The  Spring   Framework      is divided   into  modules.    Applications     can  choose   which    modules    they  need.
            At the heart are the modules of the core container, including a configuration model and a
            dependency injection mechanism. Beyond that, the Spring Framework provides foundational
            support    for   different    application     architectures,     including    messaging,      transactional     data   and
            persistence, and web. It also includes the Servlet-based Spring MVC web framework and, in
            parallel, the  Spring   WebFlux     reactive   web   framework.


            A note about modules: Spring’s framework jars allow for deployment to JDK 9’s module path
            ("Jigsaw"). For use in Jigsaw-enabled applications, the Spring Framework 5 jars come with
            "Automatic-Module-Name" manifest entries which define stable language-level module names
            ("spring.core",   "spring.context",     etc.) independent     from    jar artifact  names    (the  jars follow   the  same
            naming    pattern   with   "-" instead   of  ".",  e.g.  "spring-core"  and   "spring-context").    Of  course,   Spring’s
            framework     jars  keep  working    fine  on  the  classpath   on  both  JDK  8  and  9+.

            1.2.    History            of   Spring          and       the      Spring          Framework


            Spring came into being in 2003 as a response to the complexity of the early J2EE specifications.
            While   some    consider   Java   EE  and   its modern-day      successor    Jakarta   EE  to  be  in  competition     with
            Spring, they are in fact complementary. The Spring programming model does not embrace the
            Jakarta    EE   platform      specification;    rather,    it  integrates     with    carefully    selected    individual

            specifications   from   the  traditional   EE  umbrella:


              • Servlet  API   (JSR 340)

              • WebSocket     API  (JSR  356)

              • Concurrency      Utilities (JSR  236)

              • JSON   Binding    API  (JSR 367)

              • Bean   Validation   (JSR  303)

              • JPA  (JSR  338)

              • JMS   (JSR 914)

              • as well  as  JTA/JCA   setups  for  transaction    coordination,    if necessary.


            The  Spring   Framework      also  supports    the Dependency       Injection   (JSR 330)  and   Common      Annotations
            (JSR 250) specifications, which application developers may choose to use instead of the Spring-
            specific  mechanisms      provided     by the  Spring   Framework.       Originally,  those   were   based   on  common
            javax  packages.

            As  of Spring   Framework       6.0, Spring   has  been   upgraded     to  the Jakarta   EE   9 level  (e.g. Servlet   5.0+,
            JPA  3.0+), based    on  the  jakarta   namespace      instead   of the  traditional   javax   packages.    With   EE  9  as
            the  minimum      and   EE  10  supported     already,   Spring   is prepared     to provide    out-of-the-box     support
            for the further evolution of the Jakarta EE APIs. Spring Framework 6.0 is fully compatible with
            Tomcat   10.1,  Jetty 11  and  Undertow     2.3  as web   servers,   and  also  with  Hibernate    ORM    6.1.


            Over   time,  the role  of  Java/Jakarta    EE  in application    development      has  evolved.    In the  early  days   of
            J2EE  and   Spring,  applications    were   created   to  be deployed     to an  application    server.  Today,   with  the
            help  of Spring   Boot,   applications    are  created   in a  devops-   and   cloud-friendly     way,  with   the  Servlet
            container   embedded      and   trivial  to change.   As  of  Spring   Framework      5, a  WebFlux     application    does
            not  even   use  the  Servlet   API  directly   and   can  run   on  servers   (such   as  Netty)  that  are  not   Servlet
            containers.


            Spring  continues    to  innovate   and   to evolve.  Beyond     the Spring   Framework,      there  are  other   projects,
            such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch, among others. It’s
            important to remember that each project has its own source code repository, issue tracker, and
            release  cadence.    See  spring.io/projects    for the  complete    list of Spring   projects.

            1.3.    Design           Philosophy


            When you learn about a framework, it’s important to know not only what it does but what
            principles   it  follows. Here  are  the  guiding   principles   of the  Spring   Framework:


              • Provide choice at every level. Spring lets you defer design decisions as late as possible. For
                example, you can switch persistence providers through configuration without changing your
                code.  The   same   is true  for  many   other   infrastructure     concerns    and  integration    with  third-party
                APIs.

              • Accommodate diverse perspectives. Spring embraces flexibility and is not opinionated about
                how things should be done. It supports a wide range of application needs with different
                perspectives.

              • Maintain strong backward compatibility. Spring’s evolution has been carefully managed to
                force  few   breaking    changes    between    versions.   Spring    supports   a  carefully   chosen   range   of  JDK
                versions and third-party libraries to facilitate maintenance of applications and libraries that
                depend    on  Spring.

              • Care   about  API   design.  The  Spring   team   puts   a lot of thought   and   time  into  making    APIs  that  are
                intuitive  and   that  hold  up  across  many    versions   and   many    years.

              • Set high standards for code quality. The Spring Framework puts a strong emphasis on
                meaningful,     current,   and   accurate    javadoc.   It is one   of very   few  projects   that  can   claim   clean
                code   structure   with  no  circular   dependencies     between     packages.

            1.4.    Feedback               and       Contributions


            For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click
            here  for  a list of the  suggested    tags  to use  on  Stack   Overflow.    If  you’re fairly  certain   that there   is a
            problem    in the  Spring   Framework      or would    like to suggest   a feature,   please  use  the  GitHub    Issues.

            If you have a solution in mind or a suggested fix, you can submit a pull request on Github.
            However,    please   keep   in mind    that, for  all but  the  most   trivial issues,  we  expect   a  ticket to  be  filed
            in the issue  tracker,   where   discussions    take  place  and   leave  a record   for  future  reference.


            For more    details  see the  guidelines    at the CONTRIBUTING,         top-level  project  page.

            1.5.    Getting           Started


            If  you are  just getting   started   with  Spring,   you  may    want   to begin   using   the  Spring   Framework      by
            creating a Spring Boot-based application. Spring Boot provides a quick (and opinionated) way to
            create a production-ready Spring-based application. It is based on the Spring Framework, favors
            convention    over   configuration,    and  is designed    to get  you  up  and  running    as  quickly  as  possible.


            You  can  use  start.spring.io    to generate    a basic  project   or follow   one  of  the  "Getting   Started"  guides,
            such as Getting Started Building a RESTful Web Service. As well as being easier to digest, these
            guides   are  very   task  focused,   and   most   of them    are  based   on   Spring   Boot.  They   also   cover   other
            projects from the Spring portfolio that you might want to consider when solving a particular
            problem.

            Chapter                2.    Core           Technologies


            This  part  of the  reference    documentation       covers   all  the  technologies   that  are  absolutely   integral   to
            the Spring   Framework.


            Foremost    amongst    these   is  the  Spring Framework’s      Inversion    of Control   (IoC)  container.   A  thorough
            treatment    of the  Spring   Framework’s      IoC  container    is closely  followed    by  comprehensive       coverage
            of Spring’s   Aspect-Oriented      Programming        (AOP)   technologies.    The   Spring   Framework       has  its own
            AOP framework, which is conceptually easy to understand and which successfully addresses the
            80%   sweet  spot  of AOP   requirements      in Java   enterprise   programming.


            Coverage of Spring’s integration with AspectJ (currently the richest — in terms of features — and
            certainly  most   mature    AOP   implementation       in the  Java  enterprise   space)   is also provided.


            AOT processing can be used to optimize your application ahead-of-time. It is typically used for
            native  image   deployment      using  GraalVM.

            2.1.    The       IoC      Container


            This  chapter   covers   Spring’s  Inversion    of Control   (IoC)  container.


            2.1.1.   Introduction          to  the   Spring      IoC   Container        and    Beans

            This chapter covers the Spring Framework implementation of the Inversion of Control (IoC)
            principle. IoC is also known as dependency injection (DI). It is a process whereby objects define
            their dependencies      (that  is, the other   objects   they  work   with)   only  through    constructor    arguments,
            arguments to a factory method, or properties that are set on the object instance after it is
            constructed or returned from a factory method. The container then injects those dependencies
            when   it creates   the  bean.  This   process   is fundamentally      the  inverse   (hence   the  name,    Inversion    of
            Control) of the bean itself controlling the instantiation or location of its dependencies by using
            direct  construction    of classes  or  a mechanism      such   as the  Service  Locator    pattern.


            The  org.springframework.beans         and   org.springframework.context         packages     are  the  basis  for  Spring
            Framework’s       IoC   container.     The   BeanFactory      interface    provides     an   advanced      configuration
            mechanism capable of managing any type of object. ApplicationContext is a sub-interface of
            BeanFactory.   It adds:


              • Easier   integration   with  Spring’s   AOP   features

              • Message    resource    handling    (for use  in internationalization)

              • Event   publication

              • Application-layer       specific    contexts    such     as  the    WebApplicationContext         for   use   in   web
                applications.


            In short, the BeanFactory provides the configuration framework and basic functionality, and the
            ApplicationContext       adds    more     enterprise-specific      functionality.     The    ApplicationContext        is  a
            complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of
            Spring’s    IoC   container.     For    more     information      on    using    the   BeanFactory      instead    of   the

            ApplicationContext,      see  the  section  covering    the BeanFactory    API.


            In Spring, the objects that form the backbone of your application and that are managed by the
            Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and
            managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your
            application.   Beans,   and   the dependencies      among     them,   are  reflected   in the  configuration    metadata
            used  by  a container.


            2.1.2.   Container        Overview

            The  org.springframework.context.ApplicationContext                interface   represents    the  Spring   IoC  container
            and  is responsible     for instantiating,    configuring,    and   assembling     the  beans.   The  container    gets  its
            instructions on what objects to instantiate, configure, and assemble by reading configuration
            metadata.    The  configuration     metadata     is  represented   in  XML,   Java  annotations,    or  Java  code.  It lets
            you express the objects that compose your application and the rich interdependencies between
            those  objects.


            Several implementations of the ApplicationContext interface are supplied with Spring. In stand-
            alone applications, it is common to create an instance of ClassPathXmlApplicationContext or
            FileSystemXmlApplicationContext.           While     XML     has   been     the   traditional    format     for   defining
            configuration metadata, you can instruct the container to use Java annotations or code as the
            metadata    format   by  providing    a small   amount    of XML    configuration    to  declaratively   enable    support
            for these  additional    metadata    formats.


            In most application scenarios, explicit user code is not required to instantiate one or more
            instances   of a  Spring   IoC  container.    For  example,    in a  web   application    scenario,   a simple   eight   (or
            so) lines  of boilerplate    web   descriptor    XML    in the  web.xml    file of the  application    typically   suffices
            (see Convenient     ApplicationContext       Instantiation    for Web    Applications).    If you  use  the  Spring   Tools
            for Eclipse   (an  Eclipse-powered       development      environment),      you   can  easily  create   this  boilerplate
            configuration    with   a few  mouse    clicks  or keystrokes.


            The  following    diagram    shows    a high-level    view   of how   Spring    works.   Your   application    classes  are
            combined with configuration metadata so that, after the ApplicationContext is created and
            initialized,  you  have   a fully configured    and   executable    system   or  application.

            Figure  1.  The  Spring IoC container


            Configuration      Metadata

            As the preceding diagram shows, the Spring IoC container consumes a form of configuration
            metadata. This configuration metadata represents how you, as an application developer, tell the
            Spring  container    to instantiate,   configure,   and   assemble    the  objects  in your   application.


            Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is
            what   most  of  this chapter   uses  to convey    key  concepts    and  features   of the  Spring   IoC container.


                              XML-based     metadata     is not  the  only  allowed    form   of configuration     metadata.     The
                              Spring IoC container itself is totally decoupled from the format in which this
                             configuration metadata is actually written. These days, many developers choose
                              Java-based    configuration    for  their  Spring  applications.


            For information     about   using   other  forms   of metadata     with  the  Spring   container,   see:


              • Annotation-based         configuration:       Spring     2.5   introduced      support      for   annotation-based
                configuration     metadata.

              • Java-based configuration: Starting with Spring 3.0, many features provided by the Spring
                JavaConfig project became part of the core Spring Framework. Thus, you can define beans
                external to your application classes by using Java rather than XML files. To use these new
                features,   see the  @Configuration,     @Bean,  @Import,  and   @DependsOn   annotations.

            Spring   configuration     consists  of  at least  one   and  typically   more    than  one   bean   definition   that  the
            container must manage. XML-based configuration metadata configures these beans as <bean/>
            elements inside a top-level <beans/> element. Java configuration typically uses @Bean-annotated
            methods    within   a @Configuration     class.

            These   bean   definitions    correspond     to the  actual   objects   that  make   up   your   application.   Typically,
            you define service layer objects, data access objects (DAOs), presentation objects such as Struts
            Action instances, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so
            forth. Typically,   one   does  not  configure    fine-grained     domain    objects   in the  container,    because    it  is

            usually   the responsibility    of  DAOs   and   business    logic  to create  and   load  domain     objects.  However,
            you  can   use  Spring’s   integration    with  AspectJ    to configure    objects   that  have   been   created   outside
            the control   of an  IoC  container.   See  Using   AspectJ   to dependency-inject      domain     objects  with  Spring.


            The  following   example     shows   the  basic  structure   of XML-based      configuration     metadata:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="..."    class="...">      ①   ②
                         
                    </bean>


                    <bean   id="..."    class="...">
                         
                    </bean>


                    


              </beans>


            ① The    id attribute   is a string  that identifies   the individual    bean   definition.

            ② The    class  attribute   defines   the type  of the  bean   and  uses   the fully  qualified   classname.

            The  value   of the  id attribute   refers   to collaborating    objects.  The   XML    for referring   to  collaborating
            objects  is not shown    in  this example.    See  Dependencies      for more    information.


            Instantiating    a  Container

            The  location   path   or paths   supplied    to an  ApplicationContext       constructor    are  resource    strings  that
            let  the  container  load  configuration     metadata    from   a variety   of external   resources,    such  as  the local
            file  system, the  Java  CLASSPATH,   and   so on.


            Java


              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");



            Kotlin


              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")

                              After  you  learn   about   Spring’s   IoC  container,    you   may   want   to  know   more    about
                              Spring’s   Resource     abstraction     (as  described     in  Resources),     which     provides     a
                             convenient mechanism for reading an InputStream from locations defined in a
                              URI syntax. In particular, Resource paths are used to construct applications
                              contexts,  as  described    in Application    Contexts   and   Resource    Paths.


            The  following   example     shows   the  service   layer  objects  (services.xml)     configuration     file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    


                    <bean   id="petStore"
              class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
                         <property     name="accountDao"        ref="accountDao"/>
                         <property     name="itemDao"       ref="itemDao"/>
                         
                    </bean>


                    


              </beans>



            The  following   example     shows   the  data  access   objects  daos.xml   file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="accountDao"
                         class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
                         
                    </bean>


                    <bean   id="itemDao"
              class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
                         
                    </bean>


                    


              </beans>

            In the  preceding    example,     the  service  layer   consists  of  the  PetStoreServiceImpl       class and   two   data
            access objects of the types JpaAccountDao and JpaItemDao (based on the JPA Object-Relational
            Mapping    standard).    The  property    name  element    refers  to the  name   of  the JavaBean     property,   and  the
            ref element refers to the name of another bean definition. This linkage between id and ref
            elements expresses the dependency between collaborating objects. For details of configuring an
            object’s  dependencies,     see  Dependencies.



            Composing    XML-based    Configuration   Metadata

            It can be useful to have bean definitions span multiple XML files. Often, each individual XML
            configuration    file represents    a logical  layer  or module     in your  architecture.


            You can use the application context constructor to load bean definitions from all these XML
            fragments.    This  constructor    takes  multiple   Resource   locations,   as was   shown    in the  previous    section.
            Alternatively,   use  one   or more    occurrences     of the  <import/>    element    to load   bean   definitions   from
            another   file or files. The  following    example    shows    how   to do  so:



              <beans>
                    <import    resource="services.xml"/>
                    <import    resource="resources/messageSource.xml"/>
                    <import    resource="/resources/themeSource.xml"/>


                    <bean   id="bean1"     class="..."/>
                    <bean   id="bean2"     class="..."/>
              </beans>



            In the preceding example, external bean definitions are loaded from three files: services.xml,
            messageSource.xml,      and  themeSource.xml.      All location   paths   are   relative  to  the  definition   file doing
            the importing,    so  services.xml    must    be in  the same    directory   or  classpath   location   as  the file doing
            the importing,     while  messageSource.xml       and  themeSource.xml      must   be  in  a resources    location   below
            the  location   of the  importing     file.  As  you can  see,  a leading    slash  is ignored.   However,     given   that
            these  paths   are  relative,  it is better  form   not  to  use  the  slash  at all. The  contents    of the  files being
            imported,    including   the  top  level  <beans/>   element,    must   be  valid  XML    bean   definitions,   according
            to the Spring   Schema.

                              It  is  possible,  but  not  recommended,     to reference    files in parent   directories   using   a
                              relative "../" path. Doing so creates a dependency on a file that is outside the
                              current    application.     In   particular,    this   reference     is  not   recommended          for
                              classpath: URLs (for example, classpath:../services.xml), where the runtime
                              resolution process chooses the “nearest” classpath root and then looks into its
                              parent directory. Classpath configuration changes may lead to the choice of a
                              different,  incorrect   directory.
                
                              You  can  always    use  fully qualified    resource   locations   instead   of  relative  paths:   for
                              example,        file:C:/config/services.xml             or     classpath:/config/services.xml.
                              However, be aware that you are coupling your application’s configuration to
                              specific  absolute   locations.   It  is  generally  preferable  to keep   an indirection    for such
                              absolute locations — for example, through "${…}" placeholders that are resolved
                              against  JVM   system   properties    at runtime.


            The  namespace      itself provides    the  import   directive   feature.  Further    configuration     features   beyond
            plain bean definitions are available in a selection of XML namespaces provided by Spring — for
            example,    the context   and   util  namespaces.



            The Groovy   Bean   Definition  DSL

            As a further example for externalized configuration metadata, bean definitions can also be
            expressed    in Spring’s   Groovy    Bean   Definition    DSL,  as known     from   the  Grails  framework.     Typically,
            such  configuration     live in a ".groovy"    file  with the structure   shown    in  the following    example:



              beans    {
                    dataSource(BasicDataSource)           {
                         driverClassName       =  "org.hsqldb.jdbcDriver"
                         url   =  "jdbc:hsqldb:mem:grailsDB"
                         username     = "sa"
                         password     = ""
                         settings     = [mynew:"setting"]
                    }
                    sessionFactory(SessionFactory)            {
                         dataSource     =  dataSource
                    }
                    myService(MyService)         {
                         nestedBean     =  {  AnotherBean     bean   ->
                               dataSource     =  dataSource
                         }
                    }
              }



            This  configuration     style  is largely  equivalent     to XML    bean   definitions    and  even   supports    Spring’s
            XML   configuration     namespaces.      It also  allows   for importing     XML    bean   definition   files through    an
            importBeans    directive.

            Using   the  Container

            The  ApplicationContext      is the  interface   for an  advanced     factory  capable    of maintaining     a registry   of
            different beans and their dependencies. By using the method T getBean(String name, Class<T>
            requiredType),    you  can  retrieve   instances   of  your  beans.

            The  ApplicationContext       lets you   read   bean   definitions   and   access   them,   as  the  following    example
            shows:


            Java


              //  create    and   configure    beans
              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");


              //  retrieve     configured     instance
              PetStoreService       service    =  context.getBean("petStore",            PetStoreService.class);


              //  use   configured     instance
              List<String>      userList     = service.getUsernameList();



            Kotlin


              import    org.springframework.beans.factory.getBean


              //  create    and   configure    beans
              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")


              //  retrieve     configured     instance
              val   service    =  context.getBean<PetStoreService>("petStore")


              //  use   configured     instance
              var   userList    =  service.getUsernameList()



            With    Groovy     configuration,      bootstrapping       looks    very    similar.   It  has    a   different    context
            implementation class which is Groovy-aware (but also understands XML bean definitions). The
            following   example    shows    Groovy    configuration:


            Java


              ApplicationContext        context    =  new   GenericGroovyApplicationContext("services.groovy",
              "daos.groovy");



            Kotlin


              val   context    =  GenericGroovyApplicationContext("services.groovy",                    "daos.groovy")



            The  most   flexible  variant   is GenericApplicationContext         in  combination     with   reader   delegates — for
            example,    with  XmlBeanDefinitionReader        for XML    files,  as  the  following example    shows:

            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml")
              context.refresh()



            You  can  also  use  the GroovyBeanDefinitionReader         for Groovy    files, as the  following   example     shows:


            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy")
              context.refresh()



            You can mix and match such reader delegates on the same ApplicationContext, reading bean
            definitions   from   diverse  configuration     sources.


            You  can  then  use  getBean   to retrieve   instances    of your  beans.   The  ApplicationContext       interface   has  a
            few  other   methods    for  retrieving   beans,   but,  ideally, your   application    code   should   never   use  them.
            Indeed,   your  application    code   should   have   no  calls to  the getBean()    method    at  all  and thus  have   no
            dependency      on Spring   APIs   at all.  For  example,  Spring’s   integration    with  web   frameworks      provides
            dependency     injection   for  various   web   framework     components      such   as controllers    and  JSF-managed
            beans, letting you declare a dependency on a specific bean through metadata (such as an
            autowiring    annotation).


            2.1.3.   Bean     Overview

            A Spring   IoC  container    manages    one   or more    beans.  These   beans   are  created   with   the configuration
            metadata    that  you  supply   to the  container    (for example,    in the  form   of XML   <bean/>   definitions).


            Within   the  container    itself,  these bean   definitions   are  represented     as BeanDefinition     objects,   which
            contain   (among    other  information)     the  following   metadata:

              • A package-qualified class name: typically, the actual implementation class of the bean being

                defined.

              • Bean behavioral configuration elements, which state how the bean should behave in the
                container    (scope,  lifecycle  callbacks,   and  so  forth).

              • References     to other  beans   that  are  needed    for the  bean   to do  its work.  These   references    are  also
                called  collaborators    or  dependencies.

              • Other   configuration     settings   to set  in the  newly    created   object — for    example,    the  size  limit  of
                the  pool  or the  number     of connections     to use  in a bean   that  manages    a  connection    pool.


            This metadata translates to a set of properties that make up each bean definition. The following
            table describes    these  properties:


            Table 1. The  bean  definition

            Property                                                       Explained     in…

            Class                                                          Instantiating   Beans

            Name                                                           Naming    Beans

            Scope                                                          Bean   Scopes

            Constructor     arguments                                      Dependency      Injection

            Properties                                                     Dependency      Injection

            Autowiring     mode                                            Autowiring     Collaborators

            Lazy   initialization   mode                                   Lazy-initialized    Beans

            Initialization   method                                        Initialization   Callbacks

            Destruction     method                                         Destruction    Callbacks


            In addition to bean definitions that contain information on how to create a specific bean, the
            ApplicationContext      implementations       also  permit   the  registration   of existing   objects  that  are  created
            outside the container (by users). This is done by accessing the ApplicationContext’s BeanFactory
            through      the     getBeanFactory()        method,       which      returns      the    DefaultListableBeanFactory
            implementation.          DefaultListableBeanFactory            supports       this     registration       through       the
            registerSingleton(..)        and    registerBeanDefinition(..)          methods.     However,      typical   applications
            work   solely  with  beans   defined   through    regular   bean   definition   metadata.


                              Bean   metadata    and   manually    supplied    singleton   instances   need   to be  registered    as
                              early  as possible,   in order   for  the container    to properly    reason    about   them   during
                              autowiring    and   other  introspection     steps.  While   overriding    existing   metadata    and
                             existing  singleton    instances    is supported    to  some    degree,   the  registration   of  new
                              beans at runtime (concurrently with live access to the factory) is not officially
                              supported    and   may   lead  to  concurrent    access   exceptions,    inconsistent    state  in the
                              bean  container,    or both.



            Naming     Beans

            Every   bean   has  one  or  more   identifiers.  These   identifiers   must   be  unique    within   the container    that
            hosts  the  bean.   A bean   usually   has   only  one   identifier.  However,     if it  requires  more   than   one,  the

            extra  ones  can  be  considered     aliases.


            In XML-based      configuration    metadata,    you   use  the  id attribute,  the  name  attribute,  or  both  to specify
            the  bean   identifiers.  The   id  attribute   lets you   specify  exactly   one   id. Conventionally,     these   names
            are  alphanumeric      ('myBean',    'someService',    etc.), but  they  can  contain    special  characters    as  well. If
            you  want    to introduce    other   aliases  for  the  bean,   you  can   also  specify  them    in the  name   attribute,
            separated    by  a comma     (,), semicolon     (;), or white   space.   As  a historical   note,  in  versions   prior   to
            Spring   3.1,  the  id  attribute  was defined   as  an xsd:ID   type,  which   constrained     possible   characters.   As
            of 3.1, it is defined as an xsd:string type. Note that bean id uniqueness is still enforced by the
            container,   though   no  longer   by  XML   parsers.


            You  are  not  required   to supply    a name  or an  id for  a bean.   If  you do not  supply   a  name  or id explicitly,
            the container    generates    a unique    name    for that  bean.  However,     if you  want   to refer  to  that bean   by
            name, through the use of the ref element or a Service Locator style lookup, you must provide a
            name. Motivations for not supplying a name are related to using inner beans and autowiring
            collaborators.


                                                    Bean     Naming        Conventions

               The   convention     is  to  use  the  standard Java  convention     for  instance   field names    when    naming
               beans. That is, bean names start with a lowercase letter and are camel-cased from there.
               Examples     of such   names    include   accountManager,    accountService,     userDao,   loginController,     and
               so  forth.


               Naming     beans   consistently    makes    your   configuration     easier  to read   and   understand.     Also,  if
               you   use  Spring  AOP,   it  helps a lot when   applying    advice   to a set of beans    related  by  name.




                              With component scanning in the classpath, Spring generates bean names for
                              unnamed     components,      following    the rules  described    earlier:  essentially,   taking  the
                              simple   class  name    and  turning    its  initial  character  to lower-case.    However,     in the
                             (unusual)    special  case   when    there  is more    than   one   character    and  both   the  first
                              and  second   characters    are  upper   case,  the  original  casing   gets preserved.    These   are
                              the same    rules  as  defined   by  java.beans.Introspector.decapitalize            (which    Spring
                              uses  here).



            Aliasing a Bean   outside  the Bean  Definition

            In a bean definition itself, you can supply more than one name for the bean, by using a
            combination     of up  to  one  name    specified   by  the id  attribute  and   any  number     of other   names    in the
            name attribute. These names can be equivalent aliases to the same bean and are useful for some
            situations, such as letting each component in an application refer to a common dependency by
            using  a bean   name    that is specific  to that  component      itself.

            Specifying all aliases where the bean is actually defined is not always adequate, however. It is
            sometimes     desirable   to  introduce    an  alias  for a  bean   that  is defined   elsewhere.     This  is commonly
            the case in large systems where configuration is split amongst each subsystem, with each
            subsystem     having   its own   set  of object   definitions.   In XML-based      configuration     metadata,    you   can
            use the  <alias/>   element    to accomplish     this. The  following    example    shows    how   to do  so:

              <alias    name="fromName"       alias="toName"/>



            In this case, a bean (in the same container) named fromName may also, after the use of this alias
            definition,  be  referred   to as  toName.


            For example,     the configuration     metadata    for  subsystem     A may   refer  to a  DataSource     by the  name    of
            subsystemA-dataSource.       The  configuration     metadata     for  subsystem     B  may   refer  to a  DataSource     by
            the name of subsystemB-dataSource. When composing the main application that uses both these
            subsystems,    the  main   application    refers  to the  DataSource     by  the name    of myApp-dataSource.     To  have
            all three names refer to the same object, you can add the following alias definitions to the
            configuration    metadata:



              <alias    name="myApp-dataSource"          alias="subsystemA-dataSource"/>
              <alias    name="myApp-dataSource"          alias="subsystemB-dataSource"/>



            Now   each   component      and  the  main   application    can   refer  to the  dataSource    through    a  name   that  is
            unique   and   guaranteed      not  to clash   with  any   other   definition   (effectively   creating   a  namespace),
            yet they  refer  to the  same   bean.


                                                           Java-configuration

               If you   use  Javaconfiguration,      the  @Bean  annotation     can   be used   to  provide   aliases.  See   Using
               the  @Bean  Annotation     for details.




            Instantiating    Beans

            A bean   definition   is essentially   a recipe   for creating   one   or more   objects.   The  container    looks  at the
            recipe for a named bean when asked and uses the configuration metadata encapsulated by that
            bean  definition   to  create  (or acquire)   an  actual   object.


            If  you use  XML-based      configuration     metadata,    you  specify   the  type  (or  class) of  object  that  is to be
            instantiated   in  the class  attribute   of the  <bean/>   element.    This  class  attribute   (which,   internally,  is a
            Class   property      on   a   BeanDefinition      instance)     is  usually    mandatory.       (For   exceptions,     see
            Instantiation    by  Using   an  Instance   Factory    Method    and   Bean   Definition    Inheritance.)    You   can  use
            the Class  property    in one   of two  ways:


              • Typically, to specify the bean class to be constructed in the case where the container itself
                directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java
                code   with  the  new operator.

              • To specify the actual class containing the static factory method that is invoked to create the
                object,  in the  less common      case  where    the  container    invokes   a static   factory   method    on  a class
                to create   the  bean.   The  object   type  returned    from    the invocation     of the  static   factory   method
                may   be  the same    class or  another   class  entirely.

                                                          Nested      class    names

               If you   want   to configure    a  bean   definition   for  a nested   class,  you  may    use  either  the  binary
               name    or the  source   name    of the  nested   class.


               For example, if you have a class called SomeThing in the com.example package, and this
               SomeThing    class  has  a static   nested   class  called  OtherThing,    they  can   be  separated    by  a dollar
               sign ($) or a dot (.). So the value of the class attribute in a bean definition would be
               com.example.SomeThing$OtherThing           or com.example.SomeThing.OtherThing.





            Instantiation  with  a Constructor

            When you create a bean by the constructor approach, all normal classes are usable by and
            compatible    with   Spring.  That   is,  the  class  being developed    does   not  need   to implement     any   specific
            interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice.
            However,     depending     on  what    type  of  IoC  you  use   for that  specific   bean,   you  may    need   a default
            (empty)   constructor.


            The  Spring   IoC  container    can  manage     virtually   any  class  you  want   it to manage.     It  is  not  limited  to
            managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-
            argument) constructor and appropriate setters and getters modeled after the properties in the
            container.   You   can  also  have   more   exotic  non-bean-style      classes  in  your  container.    If,  for  example,
            you need to use a legacy connection pool that absolutely does not adhere to the JavaBean
            specification,   Spring   can  manage    it as well.


            With  XML-based      configuration     metadata    you  can   specify  your   bean   class as follows:



              <bean    id="exampleBean"       class="examples.ExampleBean"/>


              <bean    name="anotherExample"         class="examples.ExampleBeanTwo"/>



            For details about the mechanism for supplying arguments to the constructor (if required) and
            setting  object  instance   properties    after the  object  is constructed,    see  Injecting  Dependencies.



            Instantiation  with  a Static Factory  Method

            When    defining   a bean   that  you  create  with   a static factory   method,    use  the class   attribute  to specify
            the class  that  contains   the  static   factory   method    and   an  attribute   named    factory-method     to specify
            the name of the factory method itself. You should be able to call this method (with optional
            arguments,     as described    later)  and   return   a live  object,  which    subsequently     is treated   as  if it had
            been  created    through    a constructor.    One   use  for such   a bean   definition   is to call static   factories   in
            legacy  code.


            The  following    bean   definition   specifies   that  the  bean   will  be  created   by  calling   a factory   method.
            The definition does not specify the type (class) of the returned object, but rather the class
            containing the factory method. In this example, the createInstance() method must be a static
            method.   The   following   example     shows   how   to specify   a factory   method:

              <bean    id="clientService"
                    class="examples.ClientService"
                    factory-method="createInstance"/>



            The  following   example     shows   a class  that  would   work    with  the  preceding    bean   definition:


            Java


              public    class   ClientService      {
                    private    static   ClientService       clientService      =  new  ClientService();
                    private    ClientService()       {}


                    public   static    ClientService      createInstance()        {
                         return    clientService;
                    }
              }



            Kotlin


              class    ClientService      private    constructor()      {
                    companion     object   {
                         private    val   clientService      =  ClientService()
                         @JvmStatic
                         fun   createInstance()       =  clientService
                    }
              }



            For details about the mechanism for supplying (optional) arguments to the factory method and
            setting  object   instance   properties    after  the  object   is returned    from   the  factory,   see  Dependencies
            and  Configuration     in Detail.



            Instantiation  by Using  an  Instance  Factory  Method

            Similar to instantiation through a static factory method, instantiation with an instance factory
            method    invokes    a non-static   method     of an  existing   bean   from   the  container    to create   a new   bean.
            To  use  this mechanism,      leave   the  class   attribute  empty    and,   in the  factory-bean     attribute,  specify
            the name of a bean in the current (or parent or ancestor) container that contains the instance
            method    that  is  to  be  invoked to  create  the  object.  Set the  name    of the  factory   method    itself with  the
            factory-method     attribute.  The  following    example    shows    how   to configure    such  a bean:

              
              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              
              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>



            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                    }
                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }
              }



            One  factory   class can   also hold   more   than  one   factory  method,    as the  following    example    shows:



              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>


              <bean    id="accountService"
                    factory-bean="serviceLocator"
                    factory-method="createAccountServiceInstance"/>

            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    private    static   AccountService       accountService       = new   AccountServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }


                    public   AccountService       createAccountServiceInstance()             {
                         return    accountService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                         private    val   accountService      =  AccountServiceImpl()
                    }


                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }


                    fun  createAccountServiceInstance():             AccountService       {
                         return    accountService
                    }
              }



            This approach shows that the factory bean itself can be managed and configured through
            dependency     injection   (DI). See  Dependencies      and   Configuration     in Detail.


                              In Spring   documentation,       "factory   bean"   refers  to a  bean   that is configured     in the
                              Spring container and that creates objects through an instance or static factory
                             method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-
                              specific  FactoryBean    implementation       class.



            Determining    a Bean’s Runtime    Type

            The runtime type of a specific bean is non-trivial to determine. A specified class in the bean
            metadata    definition   is just  an  initial class  reference,    potentially   combined      with  a  declared   factory
            method    or being   a  FactoryBean    class which    may   lead  to  a different   runtime    type  of the  bean,   or not

            being set at all in case of an instance-level factory method (which is resolved via the specified
            factory-bean name instead). Additionally, AOP proxying may wrap a bean instance with an
            interface-based     proxy   with   limited  exposure     of the  target   bean’s  actual   type  (just  its implemented
            interfaces).

            The recommended way to find out about the actual runtime type of a particular bean is a
            BeanFactory.getType      call  for the  specified   bean   name.   This   takes  all of the  above   cases   into account
            and  returns   the  type   of object   that a  BeanFactory.getBean       call is going   to return   for  the  same   bean
            name.

            2.1.4.   Dependencies

            A typical  enterprise    application    does   not  consist  of a  single  object  (or  bean   in the  Spring   parlance).
            Even   the  simplest   application    has   a few   objects   that  work   together    to present    what   the  end-user
            sees  as a  coherent    application.    This  next  section   explains    how   you   go  from   defining   a  number     of
            bean  definitions    that stand   alone  to  a fully realized   application    where   objects   collaborate    to achieve
            a goal.


            Dependency       Injection

            Dependency      injection   (DI) is a process   whereby     objects  define   their  dependencies      (that is, the  other
            objects  with  which    they  work)   only  through    constructor    arguments,     arguments     to a factory   method,
            or properties    that  are  set  on  the  object  instance    after  it  is  constructed  or  returned    from   a factory
            method. The container then injects those dependencies when it creates the bean. This process is
            fundamentally      the  inverse   (hence   the  name,   Inversion    of  Control)   of the  bean   itself controlling   the
            instantiation   or  location  of  its  dependencies    on  its own   by  using  direct  construction    of  classes  or the
            Service  Locator    pattern.


            Code   is cleaner   with  the  DI  principle,   and   decoupling    is more    effective  when    objects   are  provided
            with their dependencies. The object does not look up its dependencies and does not know the
            location   or class  of  the  dependencies.      As  a result,  your   classes   become    easier   to test, particularly
            when the dependencies are on interfaces or abstract base classes, which allow for stub or mock
            implementations       to be used   in unit  tests.


            DI  exists   in   two    major    variants:    Constructor-based        dependency       injection    and    Setter-based
            dependency     injection.



            Constructor-based    Dependency     Injection

            Constructor-based DI is accomplished by the container invoking a constructor with a number of
            arguments,      each   representing      a  dependency.       Calling   a   static   factory    method     with    specific
            arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a
            constructor    and  to  a static   factory  method     similarly.  The  following    example    shows    a class  that  can
            only  be dependency-injected        with  constructor     injection:

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  a MovieFinder
                    private    final   MovieFinder      movieFinder;


                    //  a  constructor     so  that   the   Spring   container     can   inject   a  MovieFinder
                    public   SimpleMovieLister(MovieFinder             movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              //  a  constructor      so  that   the  Spring    container     can  inject    a MovieFinder
              class    SimpleMovieLister(private          val   movieFinder:      MovieFinder)      {
                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Notice that there is nothing special about this class. It is a POJO that has no dependencies on
            container   specific  interfaces,   base   classes, or  annotations.


            Constructor     Argument      Resolution

            Constructor argument resolution matching occurs by using the argument’s type. If no potential
            ambiguity exists in the constructor arguments of a bean definition, the order in which the
            constructor    arguments     are  defined    in a bean   definition    is the order   in  which   those   arguments     are
            supplied   to the  appropriate     constructor    when   the  bean   is being   instantiated.   Consider    the following
            class:


            Java


              package    x.y;


              public    class   ThingOne     {


                    public   ThingOne(ThingTwo        thingTwo,     ThingThree     thingThree)      {
                         //  ...
                    }
              }

            Kotlin


              package    x.y


              class    ThingOne(thingTwo:        ThingTwo,    thingThree:      ThingThree)



            Assuming that the ThingTwo and ThingThree classes are not related by inheritance, no potential
            ambiguity    exists.  Thus,  the  following    configuration     works    fine, and   you  do  not  need   to  specify  the
            constructor    argument     indexes   or types   explicitly  in the  <constructor-arg/>      element.



              <beans>
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        ref="beanTwo"/>
                         <constructor-arg        ref="beanThree"/>
                    </bean>


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>


                    <bean   id="beanThree"       class="x.y.ThingThree"/>
              </beans>



            When    another   bean   is referenced,    the  type  is known,    and  matching     can  occur   (as was   the case   with
            the preceding example). When a simple type is used, such as <value>true</value>, Spring cannot
            determine    the  type  of  the  value,  and  so  cannot   match    by  type  without    help.  Consider    the following
            class:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    final   int   years;


                    //  The  Answer    to  Life,   the   Universe,     and  Everything
                    private    final   String    ultimateAnswer;


                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }

            Kotlin


              package    examples


              class    ExampleBean(
                    private    val  years:    Int,   //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    val  ultimateAnswer:       String    //  The   Answer   to  Life,    the  Universe,     and
              Everything
              )



            Constructor   argument    type  matching
            In the  preceding    scenario,    the  container    can  use  type  matching     with   simple   types  if you   explicitly
            specify  the  type  of  the  constructor    argument     by  using   the  type  attribute,  as  the  following    example
            shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       type="int"     value="7500000"/>
                    <constructor-arg       type="java.lang.String"          value="42"/>
              </bean>



            Constructor   argument    index
            You can use the index attribute to specify explicitly the index of constructor arguments, as the
            following   example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       index="0"     value="7500000"/>
                    <constructor-arg       index="1"     value="42"/>
              </bean>



            In addition to resolving the ambiguity of multiple simple values, specifying an index resolves
            ambiguity    where    a constructor    has  two  arguments     of  the same    type.

                             The  index   is  0-based.


            Constructor   argument    name
            You can also use the constructor parameter name for value disambiguation, as the following
            example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       name="years"      value="7500000"/>
                    <constructor-arg       name="ultimateAnswer"         value="42"/>
              </bean>



            Keep   in mind    that, to  make   this  work   out  of  the  box,  your   code  must    be  compiled    with   the  debug
            flag enabled    so that  Spring   can  look   up  the parameter     name    from   the  constructor.    If you  cannot    or

            do not  want   to  compile   your   code   with  the  debug   flag, you   can  use  the  @ConstructorProperties         JDK
            annotation to explicitly name your constructor arguments. The sample class would then have to
            look  as follows:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Fields    omitted


                    @ConstructorProperties({"years",             "ultimateAnswer"})
                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }



            Kotlin


              package    examples


              class    ExampleBean
              @ConstructorProperties("years",             "ultimateAnswer")
              constructor(val       years:    Int,   val  ultimateAnswer:       String)




            Setter-based  Dependency     Injection

            Setter-based DI is accomplished by the container calling setter methods on your beans after
            invoking a no-argument constructor or a no-argument static factory method to instantiate your
            bean.

            The following example shows a class that can only be dependency-injected by using pure setter
            injection.  This  class  is  conventional   Java.  It is  a  POJO that has  no  dependencies      on  container    specific
            interfaces,  base   classes,  or annotations.

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  the  MovieFinder
                    private    MovieFinder     movieFinder;


                    //  a  setter   method    so  that   the  Spring    container     can  inject    a  MovieFinder
                    public   void   setMovieFinder(MovieFinder           movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              class    SimpleMovieLister       {


                    //  a  late-initialized       property    so   that  the   Spring    container    can   inject   a
              MovieFinder
                    lateinit    var   movieFinder:      MovieFinder


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            The  ApplicationContext      supports    constructor-based       and  setter-based    DI  for the  beans   it manages.    It
            also supports setter-based DI after some dependencies have already been injected through the
            constructor    approach.    You   configure    the  dependencies      in the  form   of  a BeanDefinition,     which    you
            use  in conjunction     with  PropertyEditor     instances    to convert   properties    from   one  format   to  another.
            However,    most   Spring   users   do  not  work   with   these  classes  directly   (that is, programmatically)       but
            rather  with   XML   bean  definitions,   annotated    components      (that  is,  classes annotated    with  @Component,
            @Controller,   and   so forth),  or @Bean   methods    in  Java-based    @Configuration     classes.  These   sources   are
            then converted internally into instances of BeanDefinition and used to load an entire Spring IoC
            container   instance.

                                           Constructor-based              or  setter-based          DI?

               Since   you   can  mix   constructor-based       and  setter-based     DI, it is a  good   rule  of thumb     to use
               constructors     for  mandatory      dependencies      and  setter   methods    or  configuration     methods     for
               optional    dependencies.     Note   that  use  of  the  @Autowired      annotation     on  a setter   method    can
               be  used   to make   the  property    be  a required    dependency;     however,     constructor    injection   with
               programmatic       validation   of arguments      is  preferable.

               The    Spring    team    generally     advocates     constructor     injection,    as  it  lets  you    implement
               application components as immutable objects and ensures that required dependencies are
               not null. Furthermore, constructor-injected components are always returned to the client
               (calling) code in a fully initialized state. As a side note, a large number of constructor
               arguments     is a bad   code  smell,  implying    that  the class  likely  has  too many    responsibilities    and
               should   be  refactored    to better  address    proper   separation    of concerns.


               Setter  injection   should   primarily    only  be  used   for optional   dependencies      that  can  be  assigned
               reasonable default values within the class. Otherwise, not-null checks must be performed
               everywhere the code uses the dependency. One benefit of setter injection is that setter
               methods make objects of that class amenable to reconfiguration or re-injection later.
               Management       through    JMX   MBeans     is  therefore  a compelling    use  case  for  setter  injection.


               Use   the  DI  style that  makes     the  most   sense   for a  particular   class.  Sometimes,     when    dealing
               with   third-party   classes   for which   you   do  not  have  the  source,   the  choice  is made    for you.  For
               example,    if a third-party    class  does  not  expose   any   setter  methods,    then  constructor     injection
               may   be  the  only  available   form   of DI.





            Dependency    Resolution   Process

            The  container    performs    bean   dependency      resolution   as  follows:


              • The   ApplicationContext      is created   and   initialized  with  configuration     metadata     that  describes   all
                the  beans.  Configuration     metadata     can  be  specified   by XML,   Java   code,  or annotations.

              • For  each  bean,   its dependencies      are expressed     in the  form  of  properties,   constructor    arguments,
                or arguments to the static-factory method (if you use that instead of a normal constructor).
                These   dependencies      are  provided    to the bean,   when    the bean   is actually   created.

              • Each   property    or constructor    argument     is an  actual   definition   of the  value  to  set,  or  a reference
                to another    bean   in the  container.

              • Each   property    or constructor     argument     that  is  a  value  is  converted  from   its  specified format    to
                the  actual  type  of  that property    or  constructor    argument.     By default,   Spring   can  convert   a value
                supplied   in  string  format   to all built-in  types,  such  as int,  long, String,   boolean,  and   so forth.

            The  Spring   container    validates   the configuration     of each   bean   as the  container    is  created. However,
            the bean properties themselves are not set until the bean is actually created. Beans that are
            singleton-scoped and set to be pre-instantiated (the default) are created when the container is
            created. Scopes are defined in Bean Scopes. Otherwise, the bean is created only when it is
            requested. Creation of a bean potentially causes a graph of beans to be created, as the bean’s
            dependencies      and  its dependencies'      dependencies      (and  so  on)  are  created   and   assigned.    Note  that

            resolution   mismatches      among     those  dependencies      may    show   up  late — that    is,  on  first  creation of
            the affected   bean.


                                                       Circular       dependencies

               If you use predominantly constructor injection, it is possible to create an unresolvable
               circular   dependency      scenario.


               For  example:    Class  A  requires   an  instance   of class  B through    constructor    injection,   and  class  B
               requires an instance of class A through constructor injection. If you configure beans for
               classes   A  and  B  to be  injected   into  each   other,  the  Spring   IoC  container    detects   this  circular
               reference    at runtime,    and  throws    a BeanCurrentlyInCreationException.


               One   possible    solution   is to edit  the  source   code   of  some   classes   to be   configured    by  setters
               rather than constructors. Alternatively, avoid constructor injection and use setter injection
               only.   In   other    words,    although     it  is  not    recommended,        you    can    configure     circular
               dependencies      with  setter  injection.


               Unlike   the  typical  case  (with   no  circular  dependencies),      a circular   dependency      between    bean
               A and bean B forces one of the beans to be injected into the other prior to being fully
               initialized   itself  (a  classic  chicken-and-egg   scenario).



            You can generally trust Spring to do the right thing. It detects configuration problems, such as
            references to non-existent beans and circular dependencies, at container load-time. Spring sets
            properties    and  resolves    dependencies      as late  as  possible,   when    the  bean   is actually   created.   This
            means    that a  Spring   container    that  has  loaded   correctly   can  later  generate    an  exception    when    you
            request an object if there is a problem creating that object or one of its dependencies — for
            example,    the bean   throws    an  exception    as a  result  of a missing   or  invalid   property.   This  potentially
            delayed visibility of some configuration issues is why ApplicationContext implementations by
            default pre-instantiate singleton beans. At the cost of some upfront time and memory to create
            these   beans    before    they    are   actually   needed,     you    discover    configuration      issues   when     the
            ApplicationContext      is created,  not  later. You   can  still  override  this default   behavior    so that  singleton
            beans   initialize lazily, rather   than  being   eagerly   pre-instantiated.


            If  no circular  dependencies      exist,  when    one  or  more   collaborating     beans   are  being   injected   into  a
            dependent bean, each collaborating bean is totally configured prior to being injected into the
            dependent     bean.  This   means    that, if bean   A  has  a dependency      on  bean   B, the  Spring   IoC  container
            completely    configures    bean    B prior   to invoking    the  setter  method     on  bean   A. In  other   words,   the
            bean is instantiated (if it is not a pre-instantiated singleton), its dependencies are set, and the
            relevant lifecycle methods (such as a configured init method or the InitializingBean callback
            method)    are  invoked.



            Examples   of Dependency     Injection

            The  following    example    uses  XML-based      configuration     metadata     for setter-based    DI. A  small   part  of
            a Spring   XML   configuration     file specifies  some   bean   definitions   as  follows:

              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <property     name="beanOne">
                         <ref   bean="anotherExampleBean"/>
                    </property>


                    
                    <property     name="beanTwo"      ref="yetAnotherBean"/>
                    <property     name="integerProperty"         value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   void   setBeanOne(AnotherBean          beanOne)    {
                         this.beanOne      =  beanOne;
                    }


                    public   void   setBeanTwo(YetAnotherBean           beanTwo)    {
                         this.beanTwo      =  beanTwo;
                    }


                    public   void   setIntegerProperty(int          i)  {
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean     {
                    lateinit    var   beanOne:    AnotherBean
                    lateinit    var   beanTwo:    YetAnotherBean
                    var  i:  Int   =  0
              }



            In the  preceding    example,    setters  are  declared    to match   against   the  properties    specified  in  the XML

            file.  The  following  example    uses  constructor-based       DI:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <constructor-arg>
                         <ref   bean="anotherExampleBean"/>
                    </constructor-arg>


                    
                    <constructor-arg       ref="yetAnotherBean"/>


                    <constructor-arg       type="int"     value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   ExampleBean(
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {
                         this.beanOne      =  anotherBean;
                         this.beanTwo      =  yetAnotherBean;
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean(
                         private    val   beanOne:    AnotherBean,
                         private    val   beanTwo:    YetAnotherBean,
                         private    val   i:  Int)



            The constructor arguments specified in the bean definition are used as arguments to the
            constructor    of the  ExampleBean.


            Now   consider    a variant   of this  example,    where,   instead   of using   a constructor,    Spring   is told  to call
            a static  factory   method    to return   an  instance   of the  object:

              <bean    id="exampleBean"       class="examples.ExampleBean"            factory-method="createInstance">
                    <constructor-arg       ref="anotherExampleBean"/>
                    <constructor-arg       ref="yetAnotherBean"/>
                    <constructor-arg       value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    //  a  private    constructor
                    private    ExampleBean(...)       {
                         ...
                    }


                    //  a  static   factory    method;    the   arguments     to  this   method   can   be
                    //  considered     the   dependencies     of   the  bean   that   is  returned,
                    //  regardless     of  how   those   arguments     are  actually     used.
                    public   static    ExampleBean      createInstance      (
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {


                         ExampleBean      eb  =  new  ExampleBean      (...);
                         //  some   other    operations...
                         return    eb;
                    }
              }



            Kotlin


              class    ExampleBean     private    constructor()      {
                    companion     object   {
                         //  a  static    factory    method;    the  arguments     to  this   method    can  be
                         //  considered      the  dependencies      of  the   bean  that   is  returned,
                         //  regardless      of  how  those   arguments     are   actually    used.
                         @JvmStatic
                         fun   createInstance(anotherBean:           AnotherBean,      yetAnotherBean:       YetAnotherBean,
              i:  Int):    ExampleBean     {
                               val  eb  =  ExampleBean      (...)
                               //  some   other   operations...
                               return   eb
                         }
                    }
              }

            Arguments     to  the  static   factory  method     are  supplied    by  <constructor-arg/>      elements,    exactly   the
            same   as if a constructor    had   actually   been  used.   The  type  of  the class  being   returned    by  the factory
            method    does   not  have   to be  of  the same    type  as  the  class  that  contains   the  static   factory   method
            (although, in this example, it is). An instance (non-static) factory method can be used in an
            essentially   identical   fashion   (aside  from    the  use  of the  factory-bean     attribute   instead   of  the  class
            attribute),  so we   do not  discuss   those  details  here.


            Dependencies       and  Configuration       in Detail

            As mentioned      in the previous    section,  you   can  define  bean   properties    and  constructor    arguments      as
            references    to other  managed      beans   (collaborators)    or  as values   defined    inline. Spring’s   XML-based
            configuration     metadata    supports    sub-element      types  within   its <property/>     and   <constructor-arg/>
            elements    for this purpose.



            Straight Values  (Primitives,  Strings,  and  so on)

            The  value   attribute   of the  <property/>     element    specifies   a property    or  constructor     argument     as  a
            human-readable       string  representation.      Spring’s   conversion    service   is used   to convert    these  values
            from   a String  to  the actual   type  of the  property    or argument.     The  following    example    shows    various
            values  being   set:



              <bean    id="myDataSource"       class="org.apache.commons.dbcp.BasicDataSource"                   destroy-
              method="close">
                    
                    <property     name="driverClassName"         value="com.mysql.jdbc.Driver"/>
                    <property     name="url"     value="jdbc:mysql://localhost:3306/mydb"/>
                    <property     name="username"       value="root"/>
                    <property     name="password"       value="misterkaoli"/>
              </bean>



            The  following   example     uses  the  p-namespace      for even   more   succinct   XML   configuration:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                    https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="myDataSource"        class="org.apache.commons.dbcp.BasicDataSource"
                         destroy-method="close"
                         p:driverClassName="com.mysql.jdbc.Driver"
                         p:url="jdbc:mysql://localhost:3306/mydb"
                         p:username="root"
                         p:password="misterkaoli"/>


              </beans>



            The  preceding    XML    is more   succinct.   However,     typos  are  discovered     at runtime    rather   than  design

            time, unless you use an IDE (such as IntelliJ IDEA or the Spring Tools for Eclipse) that supports
            automatic property completion when you create bean definitions. Such IDE assistance is highly
            recommended.


            You  can  also  configure   a  java.util.Properties      instance,   as  follows:



              <bean    id="mappings"
                    class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">


                    
                    <property     name="properties">
                         <value>
                               jdbc.driver.className=com.mysql.jdbc.Driver
                               jdbc.url=jdbc:mysql://localhost:3306/mydb
                         </value>
                    </property>
              </bean>



            The Spring container converts the text inside the <value/> element into a java.util.Properties
            instance   by  using  the  JavaBeans     PropertyEditor     mechanism.      This  is a  nice  shortcut,   and  is one  of  a
            few  places   where    the  Spring   team   do  favor   the  use  of the  nested    <value/>   element    over   the  value
            attribute  style.


            The  idref  element

            The  idref   element    is simply   an  error-proof    way   to  pass  the  id (a  string  value   -  not a reference)    of
            another bean in the container to a <constructor-arg/> or <property/> element. The following
            example    shows   how    to use  it:



              <bean    id="theTargetBean"        class="..."/>


              <bean    id="theClientBean"        class="...">
                    <property     name="targetName">
                         <idref    bean="theTargetBean"/>
                    </property>
              </bean>



            The  preceding    bean   definition   snippet   is exactly  equivalent    (at runtime)    to the  following   snippet:



              <bean    id="theTargetBean"        class="..."     />


              <bean    id="client"     class="...">
                    <property     name="targetName"       value="theTargetBean"/>
              </bean>



            The  first form   is preferable    to the  second,   because    using  the  idref   tag lets the  container    validate   at
            deployment time that the referenced, named bean actually exists. In the second variation, no

            validation   is performed      on  the  value   that is passed    to the  targetName    property    of  the  client  bean.
            Typos are only discovered (with most likely fatal results) when the client bean is actually
            instantiated.   If the  client  bean   is a  prototype    bean,  this  typo  and   the  resulting   exception    may   only
            be discovered     long  after the  container    is  deployed.


                              The  local   attribute   on  the  idref   element    is no  longer   supported     in the  4.0  beans
                              XSD, since it does not provide value over a regular bean reference any more.
                             Change    your  existing   idref   local   references    to idref   bean  when    upgrading     to the
                              4.0 schema.


            A common      place   (at least  in  versions   earlier   than   Spring   2.0)  where    the  <idref/>   element    brings
            value is in the configuration of AOP interceptors in a ProxyFactoryBean bean definition. Using
            <idref/> elements when you specify the interceptor names prevents you from misspelling an
            interceptor   ID.



            References   to Other  Beans  (Collaborators)

            The  ref  element    is the  final element    inside   a <constructor-arg/>      or  <property/>    definition   element.
            Here, you set the value of the specified property of a bean to be a reference to another bean (a
            collaborator)    managed     by  the  container.    The  referenced     bean   is a  dependency      of the  bean   whose
            property    is to be  set, and   it is initialized   on  demand     as  needed    before   the  property    is set. (If the
            collaborator    is a singleton    bean,  it may   already    be  initialized  by  the  container.)    All references    are
            ultimately   a reference    to another    object.  Scoping   and   validation   depend    on  whether    you   specify  the
            ID or  name   of the  other   object  through    the bean  or  parent  attribute.


            Specifying   the  target  bean   through    the  bean  attribute   of the  <ref/>  tag  is the most   general    form  and
            allows  creation    of a reference    to any   bean   in the  same   container    or parent    container,   regardless    of
            whether it is in the same XML file. The value of the bean attribute may be the same as the id
            attribute   of the  target  bean   or  be  the  same   as  one   of the  values   in the  name   attribute   of the  target
            bean.  The  following    example    shows    how   to use  a ref  element:



              <ref   bean="someBean"/>



            Specifying    the  target  bean   through    the  parent   attribute   creates   a  reference    to a  bean   that  is in  a
            parent container of the current container. The value of the parent attribute may be the same as
            either  the id  attribute  of  the target  bean   or  one  of the  values   in the  name  attribute  of  the target  bean.
            The target bean must be in a parent container of the current one. You should use this bean
            reference variant mainly when you have a hierarchy of containers and you want to wrap an
            existing  bean   in  a parent   container    with   a proxy    that  has  the  same   name    as  the  parent   bean.   The
            following   pair  of listings  shows   how   to use  the  parent   attribute:



              
              <bean    id="accountService"        class="com.something.SimpleAccountService">
                    
              </bean>

              
              <bean    id="accountService"        
                    class="org.springframework.aop.framework.ProxyFactoryBean">
                    <property     name="target">
                         <ref   parent="accountService"/>           
                    </property>
                    
              </bean>




                              The  local  attribute   on  the  ref element    is no  longer   supported    in the  4.0 beans    XSD,
                             since it does not provide value over a regular bean reference any more. Change
                              your  existing   ref  local  references    to ref  bean  when    upgrading     to the 4.0  schema.



            Inner Beans

            A <bean/>   element    inside   the  <property/>    or  <constructor-arg/>      elements    defines   an  inner   bean,   as
            the following    example    shows:



              <bean    id="outer"     class="...">
                    
                    <property     name="target">
                         <bean    class="com.example.Person">           
                               <property     name="name"     value="Fiona      Apple"/>
                               <property     name="age"     value="25"/>
                         </bean>
                    </property>
              </bean>



            An  inner  bean   definition   does   not  require   a defined   ID  or name.    If specified,  the  container    does  not
            use such a value as an identifier. The container also ignores the scope flag on creation, because
            inner  beans   are  always   anonymous       and  are  always    created   with  the  outer  bean.   It  is  not  possible  to
            access inner beans independently or to inject them into collaborating beans other than into the
            enclosing   bean.


            As a  corner   case,  it  is  possible  to  receive  destruction  callbacks    from   a custom    scope — for    example,
            for a request-scoped      inner   bean   contained    within   a singleton    bean.  The   creation   of  the inner   bean
            instance is tied to its containing bean, but destruction callbacks let it participate in the request
            scope’s  lifecycle.  This  is  not  a common    scenario.   Inner   beans   typically  simply   share   their  containing
            bean’s  scope.



            Collections

            The <list/>, <set/>, <map/>, and <props/> elements set the properties and arguments of the Java
            Collection    types  List,  Set,  Map, and   Properties,    respectively.   The   following    example     shows   how    to
            use them:

              <bean    id="moreComplexObject"         class="example.ComplexObject">
                    
                    <property     name="adminEmails">
                         <props>
                               <prop   key="administrator">administrator@example.org</prop>
                               <prop   key="support">support@example.org</prop>
                               <prop   key="development">development@example.org</prop>
                         </props>
                    </property>
                    
                    <property     name="someList">
                         <list>
                               <value>a    list   element    followed    by   a reference</value>
                               <ref   bean="myDataSource"        />
                         </list>
                    </property>
                    
                    <property     name="someMap">
                         <map>
                               <entry   key="an    entry"    value="just      some  string"/>
                               <entry   key="a    ref"   value-ref="myDataSource"/>
                         </map>
                    </property>
                    
                    <property     name="someSet">
                         <set>
                               <value>just     some   string</value>
                               <ref   bean="myDataSource"        />
                         </set>
                    </property>
              </bean>



            The  value  of  a map   key  or  value,  or a set  value,  can  also  be any  of  the following    elements:



              bean   |  ref  |  idref   |  list   |  set  |  map   | props    | value    | null



            Collection    Merging

            The Spring container also supports merging collections. An application developer can define a
            parent   <list/>,  <map/>,  <set/>   or  <props/>   element    and  have   child  <list/>,  <map/>,   <set/>  or  <props/>
            elements inherit and override values from the parent collection. That is, the child collection’s
            values   are  the  result  of merging     the  elements    of the  parent    and  child   collections,   with  the  child’s
            collection  elements    overriding    values   specified   in the  parent   collection.


            This section on merging discusses the parent-child bean mechanism. Readers unfamiliar with
            parent   and  child  bean   definitions   may   wish   to read  the  relevant   section   before  continuing.


            The  following   example     demonstrates     collection   merging:

              <beans>
                    <bean   id="parent"      abstract="true"       class="example.ComplexObject">
                         <property     name="adminEmails">
                               <props>
                                    <prop    key="administrator">administrator@example.com</prop>
                                    <prop    key="support">support@example.com</prop>
                               </props>
                         </property>
                    </bean>
                    <bean   id="child"     parent="parent">
                         <property     name="adminEmails">
                               
                               <props   merge="true">
                                    <prop    key="sales">sales@example.com</prop>
                                    <prop    key="support">support@example.co.uk</prop>
                               </props>
                         </property>
                    </bean>
              <beans>



            Notice  the  use  of the  merge=true    attribute  on  the  <props/>   element    of the  adminEmails    property    of the
            child bean definition. When the child bean is resolved and instantiated by the container, the
            resulting   instance   has  an  adminEmails     Properties    collection   that  contains   the  result  of  merging    the
            child’s  adminEmails    collection   with   the  parent’s   adminEmails    collection.   The   following    listing shows
            the result:



              administrator=administrator@example.com
              sales=sales@example.com
              support=support@example.co.uk



            The  child  Properties    collection’s   value   set inherits   all property    elements    from   the  parent   <props/>,
            and  the  child’s value   for the  support   value  overrides    the  value  in  the parent   collection.


            This  merging    behavior     applies   similarly   to the  <list/>,   <map/>,   and  <set/>   collection   types.   In the
            specific  case  of the  <list/>   element,    the  semantics    associated    with   the List   collection   type  (that  is,
            the notion    of an  ordered   collection   of  values)  is maintained.     The   parent’s   values   precede    all of the
            child list’s values. In the case of the Map, Set, and Properties collection types, no ordering exists.
            Hence,   no  ordering    semantics    are  in effect  for  the collection   types   that  underlie   the  associated    Map,
            Set, and  Properties    implementation       types  that  the container    uses  internally.


            Limitations     of Collection    Merging

            You  cannot   merge    different   collection  types   (such  as  a Map and   a List).  If  you do  attempt   to do  so, an
            appropriate    Exception    is  thrown.  The  merge   attribute  must   be  specified   on  the lower,   inherited,   child
            definition.  Specifying    the  merge  attribute   on a  parent   collection  definition    is  redundant   and   does  not
            result in  the desired   merging.

            Strongly-typed      collection

            Thanks to Java’s support for generic types, you can use strongly typed collections. That is, it is
            possible   to declare   a Collection    type  such   that  it  can  only contain   (for example)     String   elements.   If
            you use Spring to dependency-inject a strongly-typed Collection into a bean, you can take
            advantage of Spring’s type-conversion support such that the elements of your strongly-typed
            Collection    instances   are  converted     to the  appropriate     type  prior  to  being   added   to  the Collection.
            The  following   Java   class and   bean  definition   show    how   to do  so:


            Java


              public    class   SomeClass     {


                    private    Map<String,     Float>    accounts;


                    public   void   setAccounts(Map<String,          Float>    accounts)     {
                         this.accounts       = accounts;
                    }
              }



            Kotlin


              class    SomeClass    {
                    lateinit    var   accounts:    Map<String,      Float>
              }




              <beans>
                    <bean   id="something"       class="x.y.SomeClass">
                         <property     name="accounts">
                               <map>
                                    <entry    key="one"     value="9.99"/>
                                    <entry    key="two"     value="2.75"/>
                                    <entry    key="six"     value="3.99"/>
                               </map>
                         </property>
                    </bean>
              </beans>



            When     the   accounts    property     of  the   something     bean    is  prepared     for   injection,   the   generics
            information about the element type of the strongly-typed Map<String, Float> is available by
            reflection.  Thus,   Spring’s   type  conversion     infrastructure     recognizes    the  various    value  elements     as
            being  of  type  Float,  and   the  string  values   (9.99,  2.75,  and  3.99)   are  converted    into  an  actual   Float
            type.



            Null and  Empty   String Values

            Spring   treats  empty    arguments     for  properties    and   the  like  as empty    Strings.   The   following    XML-
            based   configuration    metadata     snippet   sets the  email  property    to the empty    String   value  ("").

              <bean    class="ExampleBean">
                    <property     name="email"     value=""/>
              </bean>



            The  preceding    example    is equivalent    to the  following    Java  code:


            Java


              exampleBean.setEmail("");



            Kotlin


              exampleBean.email        =  ""



            The  <null/>   element    handles   null  values.  The   following   listing  shows   an  example:



              <bean    class="ExampleBean">
                    <property     name="email">
                         <null/>
                    </property>
              </bean>



            The  preceding    configuration     is  equivalent   to the following    Java  code:


            Java


              exampleBean.setEmail(null);



            Kotlin


              exampleBean.email        =  null




            XML  Shortcut   with  the p-namespace

            The  p-namespace      lets you   use  the bean  element’s    attributes   (instead   of nested   <property/>    elements)
            to describe   your   property   values   collaborating    beans,   or both.


            Spring supports extensible configuration formats with namespaces, which are based on an XML
            Schema    definition.   The   beans  configuration     format    discussed    in this  chapter   is defined    in an  XML
            Schema    document.     However,     the  p-namespace       is not  defined   in  an  XSD   file and  exists  only   in the
            core  of Spring.


            The following example shows two XML snippets (the first uses standard XML format and the
            second   uses  the  p-namespace)      that resolve   to the  same   result:

              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="classic"       class="com.example.ExampleBean">
                         <property     name="email"      value="someone@somewhere.com"/>
                    </bean>


                    <bean   name="p-namespace"        class="com.example.ExampleBean"
                         p:email="someone@somewhere.com"/>
              </beans>



            The  example     shows    an  attribute   in the  p-namespace       called  email  in  the  bean   definition.   This  tells
            Spring   to include   a property    declaration.    As  previously    mentioned,     the p-namespace       does  not  have
            a schema    definition,   so you  can  set  the name    of the  attribute   to the property    name.


            This  next  example    includes   two   more   bean   definitions   that  both  have   a reference    to another   bean:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="john-classic"         class="com.example.Person">
                         <property     name="name"      value="John     Doe"/>
                         <property     name="spouse"      ref="jane"/>
                    </bean>


                    <bean   name="john-modern"
                         class="com.example.Person"
                         p:name="John      Doe"
                         p:spouse-ref="jane"/>


                    <bean   name="jane"      class="com.example.Person">
                         <property     name="name"      value="Jane     Doe"/>
                    </bean>
              </beans>



            This example includes not only a property value using the p-namespace but also uses a special
            format    to   declare    property     references.     Whereas       the   first  bean    definition     uses   <property
            name="spouse" ref="jane"/> to create a reference from bean john to bean jane, the second bean
            definition   uses  p:spouse-ref="jane"       as an  attribute   to do  the exact   same   thing.  In this  case,  spouse  is
            the property name, whereas the -ref part indicates that this is not a straight value but rather a
            reference   to another    bean.

                              The  p-namespace       is  not  as  flexible  as  the  standard  XML    format.   For  example,    the
                              format   for  declaring    property    references    clashes   with   properties   that  end   in  Ref,
                             whereas    the  standard    XML   format    does  not.  We   recommend       that  you  choose   your
                              approach     carefully    and    communicate        this  to   your   team    members       to  avoid
                              producing    XML    documents     that  use  all  three approaches     at the  same   time.



            XML  Shortcut   with  the c-namespace

            Similar to the XML Shortcut with the p-namespace, the c-namespace, introduced in Spring 3.1,
            allows  inlined   attributes   for configuring     the constructor    arguments      rather  then   nested   constructor-
            arg elements.


            The  following    example    uses   the  c: namespace      to do  the  same    thing  as the  from   Constructor-based
            Dependency      Injection:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:c="http://www.springframework.org/schema/c"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>
                    <bean   id="beanThree"       class="x.y.ThingThree"/>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        name="thingTwo"       ref="beanTwo"/>
                         <constructor-arg        name="thingThree"       ref="beanThree"/>
                         <constructor-arg        name="email"      value="something@somewhere.com"/>
                    </bean>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne"         c:thingTwo-ref="beanTwo"
                         c:thingThree-ref="beanThree"            c:email="something@somewhere.com"/>


              </beans>



            The  c: namespace      uses   the same    conventions     as the  p: one   (a trailing  -ref  for  bean   references)    for
            setting  the  constructor    arguments     by  their  names.   Similarly,   it needs   to be  declared   in  the  XML   file
            even  though    it  is  not  defined  in  an  XSD  schema  (it  exists  inside  the  Spring core).

            For the  rare  cases   where   the  constructor    argument     names    are  not  available   (usually   if  the  bytecode
            was   compiled    without    debugging     information),     you   can  use  fallback   to  the  argument     indexes,    as
            follows:

              
              <bean    id="beanOne"     class="x.y.ThingOne"         c:_0-ref="beanTwo"        c:_1-ref="beanThree"
                    c:_2="something@somewhere.com"/>




                              Due  to  the XML    grammar,     the  index   notation    requires   the  presence    of the  leading
                              _, as XML attribute names cannot start with a number (even though some IDEs
                             allow it). A corresponding index notation is also available for <constructor-arg>
                              elements but not commonly used since the plain order of declaration is usually
                              sufficient  there.


            In practice, the constructor resolution mechanism is quite efficient in matching arguments, so
            unless  you   really need   to, we  recommend       using   the name    notation   throughout     your   configuration.



            Compound     Property  Names

            You can use compound or nested property names when you set bean properties, as long as all
            components      of the  path   except   the  final property    name    are  not   null. Consider    the  following    bean
            definition:



              <bean    id="something"      class="things.ThingOne">
                    <property     name="fred.bob.sammy"         value="123"     />
              </bean>



            The  something    bean   has  a fred  property,    which   has  a  bob property,    which   has  a  sammy  property,   and
            that final  sammy  property    is being  set  to a value   of 123. In  order  for  this to work,   the  fred  property    of
            something   and   the  bob property    of  fred  must   not  be  null  after  the bean   is constructed.    Otherwise,     a
            NullPointerException      is thrown.


            Using   depends-on

            If  a  bean is  a  dependency    of another    bean,  that  usually   means    that  one  bean   is set as  a property    of
            another. Typically you accomplish this with the <ref/> element in XML-based configuration
            metadata.    However,     sometimes     dependencies      between    beans   are  less  direct. An   example    is when    a
            static initializer in a class needs to be triggered, such as for database driver registration. The
            depends-on    attribute   can  explicitly  force   one  or  more   beans    to be  initialized  before   the  bean   using
            this element is initialized. The following example uses the depends-on attribute to express a
            dependency     on  a single   bean:



              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager"/>
              <bean    id="manager"     class="ManagerBean"         />



            To express    a dependency      on  multiple   beans,   supply   a list  of  bean  names  as  the value   of the  depends-
            on attribute   (commas,    whitespace,     and  semicolons     are valid  delimiters):

              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager,accountDao">
                    <property     name="manager"      ref="manager"      />
              </bean>


              <bean    id="manager"     class="ManagerBean"         />
              <bean    id="accountDao"       class="x.y.jdbc.JdbcAccountDao"             />




                              The  depends-on    attribute  can   specify  both   an initialization-time     dependency      and,  in
                              the case of singleton beans only, a corresponding destruction-time dependency.
                             Dependent beans that define a depends-on relationship with a given bean are
                              destroyed    first,  prior  to  the  given  bean itself being   destroyed.   Thus,   depends-on    can
                              also control   shutdown     order.



            Lazy-initialized     Beans

            By  default,  ApplicationContext      implementations       eagerly   create   and  configure    all singleton   beans    as
            part  of the  initialization  process.   Generally,    this pre-instantiation     is desirable,   because   errors   in the
            configuration or surrounding environment are discovered immediately, as opposed to hours or
            even days later. When this behavior is not desirable, you can prevent pre-instantiation of a
            singleton   bean   by  marking    the  bean   definition   as being   lazy-initialized.   A  lazy-initialized   bean   tells
            the IoC  container    to create  a bean   instance   when    it is  first  requested, rather   than  at startup.


            In XML, this behavior is controlled by the lazy-init attribute on the <bean/> element, as the
            following   example    shows:



              <bean    id="lazy"    class="com.something.ExpensiveToCreateBean"                  lazy-init="true"/>
              <bean    name="not.lazy"       class="com.something.AnotherBean"/>



            When the preceding configuration is consumed by an ApplicationContext, the lazy bean is not
            eagerly   pre-instantiated     when    the  ApplicationContext      starts,  whereas    the  not.lazy    bean   is eagerly
            pre-instantiated.


            However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-
            initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must
            satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean
            elsewhere    that  is  not  lazy-initialized.

            You can also control lazy-initialization at the container level by using the default-lazy-init
            attribute  on  the  <beans/>   element,   as  the following    example    shows:



              <beans    default-lazy-init="true">
                    
              </beans>

            Autowiring     Collaborators

            The  Spring   container    can   autowire    relationships     between    collaborating     beans.   You  can   let Spring
            resolve   collaborators    (other   beans)   automatically     for  your   bean   by  inspecting    the  contents    of the
            ApplicationContext.      Autowiring    has  the  following    advantages:

              • Autowiring can significantly reduce the need to specify properties or constructor arguments.
                (Other mechanisms such as a bean template discussed elsewhere in this chapter are also
                valuable    in this regard.)

              • Autowiring     can  update    a configuration    as  your  objects   evolve.  For  example,    if you  need   to add   a
                dependency      to  a class,  that dependency       can  be  satisfied  automatically     without    you   needing    to
                modify the configuration. Thus autowiring can be especially useful during development,
                without    negating    the option   of  switching    to explicit  wiring    when    the code   base   becomes     more
                stable.


            When using XML-based configuration metadata (see Dependency Injection), you can specify the
            autowire mode for a bean definition with the autowire attribute of the <bean/> element. The
            autowiring functionality has four modes. You specify autowiring per bean and can thus choose
            which   ones  to  autowire.   The   following   table  describes   the  four  autowiring     modes:


            Table 2. Autowiring    modes

            Mode                     Explanation
            no                       (Default)   No  autowiring.    Bean   references    must   be  defined   by  ref elements.
                                     Changing     the default   setting  is not  recommended       for  larger  deployments,
                                     because    specifying   collaborators     explicitly  gives  greater   control  and   clarity. To
                                     some    extent,  it  documents    the structure   of  a system.
            byName                   Autowiring     by  property    name.   Spring   looks  for a  bean  with   the same    name   as
                                     the  property    that needs   to be  autowired.    For  example,    if a bean   definition   is
                                     set to  autowire    by name    and  it contains   a master   property    (that is, it  has  a
                                     setMaster(..)     method),    Spring   looks  for a  bean  definition   named     master  and
                                     uses  it to set the  property.
            byType                   Lets  a property    be  autowired    if exactly  one   bean  of  the property    type  exists  in
                                     the  container.   If more   than   one  exists, a  fatal exception    is  thrown,  which
                                     indicates   that  you  may   not  use  byType   autowiring    for that  bean.   If  there are no
                                     matching     beans,  nothing    happens    (the  property   is not  set).
            constructor              Analogous     to byType   but  applies  to constructor    arguments.     If there  is not
                                     exactly   one  bean   of the  constructor    argument     type  in the  container,   a fatal
                                     error   is  raised.


            With byType or constructor autowiring mode, you can wire arrays and typed collections. In such
            cases,  all autowire    candidates     within   the  container    that  match    the  expected    type  are  provided     to
            satisfy  the  dependency.     You   can  autowire     strongly-typed     Map  instances   if the  expected    key   type  is
            String. An autowired Map instance’s values consist of all bean instances that match the expected
            type, and   the Map  instance’s   keys  contain   the  corresponding      bean   names.

            Limitations  and  Disadvantages    of Autowiring

            Autowiring works best when it is used consistently across a project. If autowiring is not used in
            general,  it might   be confusing    to developers     to use  it  to  wire  only  one  or  two  bean definitions.


            Consider   the  limitations   and   disadvantages     of autowiring:

              • Explicit  dependencies      in  property   and  constructor-arg      settings  always    override   autowiring.     You
                cannot    autowire    simple   properties    such  as  primitives,   Strings,   and   Classes   (and  arrays   of such
                simple   properties).   This  limitation   is by-design.

              • Autowiring     is less  exact  than   explicit  wiring.   Although,    as  noted   in  the  earlier  table,  Spring   is
                careful to avoid guessing in case of ambiguity that might have unexpected results. The
                relationships    between    your   Spring-managed       objects   are  no longer   documented      explicitly.

              • Wiring information may not be available to tools that may generate documentation from a
                Spring   container.

              • Multiple bean definitions within the container may match the type specified by the setter
                method    or  constructor    argument     to be  autowired.    For  arrays,  collections,   or Map  instances,   this is
                not  necessarily    a problem.    However,     for dependencies      that  expect   a single  value,  this  ambiguity
                is not  arbitrarily  resolved.   If no  unique   bean   definition   is available,   an  exception   is thrown.


            In the  latter scenario,   you  have   several   options:

              • Abandon     autowiring     in favor  of explicit  wiring.

              • Avoid   autowiring     for  a bean   definition    by  setting  its autowire-candidate       attributes   to false,   as
                described    in the  next  section.

              • Designate    a single  bean   definition   as the  primary    candidate    by  setting  the  primary  attribute   of its
                <bean/>   element    to true.

              • Implement the more fine-grained control available with annotation-based configuration, as
                described    in Annotation-based       Container    Configuration.



            Excluding   a  Bean from  Autowiring

            On a per-bean basis, you can exclude a bean from autowiring. In Spring’s XML format, set the
            autowire-candidate      attribute   of the  <bean/>  element    to false.  The   container    makes   that  specific  bean
            definition   unavailable     to the  autowiring     infrastructure     (including   annotation     style  configurations
            such  as @Autowired).


                              The  autowire-candidate       attribute   is designed    to only  affect  type-based     autowiring.
                              It does not affect explicit references by name, which get resolved even if the
                             specified bean is not marked as an autowire candidate. As a consequence,
                              autowiring    by  name    nevertheless    injects  a bean   if  the  name  matches.


            You can also limit autowire candidates based on pattern-matching against bean names. The top-
            level <beans/> element accepts one or more patterns within its default-autowire-candidates
            attribute. For example, to limit autowire candidate status to any bean whose name ends with
            Repository,   provide    a value   of *Repository.    To  provide    multiple   patterns,   define   them   in  a comma-
            separated    list.  An  explicit  value of true  or  false  for  a bean   definition’s   autowire-candidate      attribute

            always   takes  precedence.     For  such  beans,   the pattern   matching     rules  do  not apply.


            These techniques are useful for beans that you never want to be injected into other beans by
            autowiring. It does not mean that an excluded bean cannot itself be configured by using
            autowiring.    Rather,   the bean   itself is not a  candidate    for autowiring    other   beans.


            Method    Injection

            In most   application    scenarios,    most   beans   in the  container    are   singletons.   When    a  singleton   bean
            needs   to collaborate    with  another    singleton   bean   or a  non-singleton     bean   needs   to collaborate    with
            another non-singleton bean, you typically handle the dependency by defining one bean as a
            property    of the  other.  A  problem     arises  when    the  bean   lifecycles   are  different.  Suppose     singleton
            bean   A  needs   to use   non-singleton     (prototype)    bean   B, perhaps     on  each   method    invocation     on  A.
            The  container    creates   the singleton    bean   A only  once,   and  thus   only  gets  one  opportunity     to set the
            properties.   The   container    cannot   provide    bean   A  with  a  new   instance   of  bean   B every   time   one  is
            needed.

            A solution   is to  forego   some   inversion    of control.   You  can   make   bean   A  aware    of the  container    by
            implementing the ApplicationContextAware interface, and by making a getBean("B") call to the
            container ask for (a typically new) bean B instance every time bean A needs it. The following
            example    shows   this  approach:

            Java


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple;


              //  Spring-API      imports
              import    org.springframework.beans.BeansException;
              import    org.springframework.context.ApplicationContext;
              import    org.springframework.context.ApplicationContextAware;


              public    class   CommandManager       implements     ApplicationContextAware          {


                    private    ApplicationContext        applicationContext;


                    public   Object    process(Map      commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    protected     Command    createCommand()       {
                         //  notice    the   Spring   API   dependency!
                         return    this.applicationContext.getBean("command",                 Command.class);
                    }


                    public   void   setApplicationContext(
                               ApplicationContext        applicationContext)        throws    BeansException       {
                         this.applicationContext          =  applicationContext;
                    }
              }

            Kotlin


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple


              //  Spring-API      imports
              import    org.springframework.context.ApplicationContext
              import    org.springframework.context.ApplicationContextAware


              class    CommandManager      :  ApplicationContextAware          {


                    private    lateinit    var   applicationContext:        ApplicationContext


                    fun  process(commandState:          Map<*,   *>):   Any   {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  notice    the  Spring    API  dependency!
                    protected     fun  createCommand()       =
                               applicationContext.getBean("command",               Command::class.java)


                    override    fun   setApplicationContext(applicationContext:                ApplicationContext)         {
                         this.applicationContext          =  applicationContext
                    }
              }



            The preceding is not desirable, because the business code is aware of and coupled to the Spring
            Framework.      Method    Injection,   a somewhat      advanced     feature   of  the  Spring   IoC  container,   lets  you
            handle   this use  case  cleanly.



               You   can  read  more   about   the  motivation    for  Method    Injection   in this blog  entry.





            Lookup   Method   Injection

            Lookup    method    injection   is the  ability of  the  container   to  override   methods     on  container-managed
            beans   and  return   the  lookup    result  for another    named     bean   in the  container.    The  lookup    typically
            involves a prototype bean, as in the scenario described in the preceding section. The Spring
            Framework      implements     this  method    injection   by  using  bytecode    generation    from   the  CGLIB    library
            to dynamically     generate   a  subclass   that overrides    the  method.

                                • For  this  dynamic    subclassing    to  work,   the  class that  the  Spring   bean   container
                                  subclasses    cannot   be  final,  and   the  method    to  be  overridden     cannot   be  final,
                                  either.

                                • Unit-testing    a class  that  has   an  abstract   method     requires    you  to  subclass   the
                                  class  yourself   and  to supply   a stub  implementation       of the  abstract   method.
                               • Concrete    methods     are  also necessary     for component      scanning,    which    requires
                                  concrete   classes   to pick  up.

                                • A further key limitation is that lookup methods do not work with factory
                                  methods and in particular not with @Bean methods in configuration classes,
                                  since,  in  that  case, the  container    is not  in  charge   of  creating   the  instance   and
                                  therefore   cannot    create  a runtime-generated        subclass   on  the fly.


            In the case of the CommandManager class in the previous code snippet, the Spring container
            dynamically     overrides    the implementation       of the  createCommand()      method.    The  CommandManager     class
            does  not  have   any  Spring   dependencies,     as the  reworked     example    shows:


            Java


              package    fiona.apple;


              //  no   more  Spring    imports!


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              package    fiona.apple


              //  no   more  Spring    imports!


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    fun  createCommand():        Command
              }



            In the client class that contains the method to be injected (the CommandManager in this case), the
            method    to be  injected  requires    a signature   of the  following    form:



              <public|protected>        [abstract]      <return-type>      theMethodName(no-arguments);



            If  the  method   is abstract,   the  dynamically-generated         subclass   implements      the  method.    Otherwise,
            the dynamically-generated subclass overrides the concrete method defined in the original class.
            Consider   the  following    example:



              
              <bean    id="myCommand"      class="fiona.apple.AsyncCommand"              scope="prototype">
                    
              </bean>


              
              <bean    id="commandManager"        class="fiona.apple.CommandManager">
                    <lookup-method      name="createCommand"         bean="myCommand"/>
              </bean>



            The bean identified as commandManager calls its own createCommand() method whenever it needs a
            new   instance   of the  myCommand   bean.   You  must   be  careful  to deploy   the  myCommand    bean   as a prototype
            if that is actually what is needed. If it is a singleton, the same instance of the myCommand bean is
            returned   each   time.


            Alternatively, within the annotation-based component model, you can declare a lookup method
            through   the  @Lookup   annotation,    as the  following   example     shows:

            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup("myCommand")
                    protected     abstract    Command    createCommand();
              }



            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup("myCommand")
                    protected     abstract    fun  createCommand():        Command
              }



            Or, more    idiomatically,   you   can  rely on  the  target  bean   getting   resolved   against   the  declared   return
            type  of the lookup    method:


            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup
                    protected     abstract    fun  createCommand():        Command
              }



            Note that you should typically declare such annotated lookup methods with a concrete stub
            implementation,      in order   for them    to be  compatible    with   Spring’s  component      scanning    rules  where
            abstract classes get ignored by default. This limitation does not apply to explicitly registered or
            explicitly  imported    bean   classes.


                              Another way of accessing differently scoped target beans is an ObjectFactory/
                              Provider   injection  point.  See  Scoped    Beans   as Dependencies.
                 
                              You       may        also      find       the       ServiceLocatorFactoryBean             (in      the
                              org.springframework.beans.factory.config             package)    to be useful.



            Arbitrary  Method   Replacement

            A less useful form of method injection than lookup method injection is the ability to replace
            arbitrary   methods     in a  managed     bean    with  another    method     implementation.       You  can   safely  skip
            the rest  of this section   until you   actually  need   this functionality.


            With XML-based configuration metadata, you can use the replaced-method element to replace an
            existing  method     implementation       with   another,   for  a  deployed    bean.   Consider    the  following    class,
            which   has  a method    called  computeValue     that  we  want   to override:


            Java


              public    class   MyValueCalculator        {


                    public   String    computeValue(String         input)   {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }

            Kotlin


              class    MyValueCalculator       {


                    fun  computeValue(input:         String):    String    {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }



            A class that implements the org.springframework.beans.factory.support.MethodReplacer interface
            provides   the  new   method    definition,   as the  following   example     shows:


            Java


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              public    class   ReplacementComputeValue          implements     MethodReplacer       {


                    public   Object    reimplement(Object        o,  Method    m,  Object[]    args)    throws   Throwable     {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         String    input   =  (String)    args[0];
                         ...
                         return    ...;
                    }
              }



            Kotlin


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              class    ReplacementComputeValue          : MethodReplacer       {


                    override    fun   reimplement(obj:       Any,   method:    Method,    args:   Array<out     Any>):    Any  {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         val   input   =  args[0]    as  String;
                         ...
                         return    ...;
                    }
              }



            The  bean   definition    to deploy   the  original   class  and   specify   the  method    override    would    resemble
            the following    example:

              <bean    id="myValueCalculator"         class="x.y.z.MyValueCalculator">
                    
                    <replaced-method       name="computeValue"         replacer="replacementComputeValue">
                         <arg-type>String</arg-type>
                    </replaced-method>
              </bean>


              <bean    id="replacementComputeValue"           class="a.b.c.ReplacementComputeValue"/>



            You  can   use  one   or more    <arg-type/>    elements     within   the  <replaced-method/>       element    to indicate
            the method signature of the method being overridden. The signature for the arguments is
            necessary only if the method is overloaded and multiple variants exist within the class. For
            convenience,     the  type  string  for  an  argument     may   be  a  substring   of  the  fully qualified   type   name.
            For example,    the  following    all  match  java.lang.String:



              java.lang.String
              String
              Str



            Because   the  number     of arguments     is often  enough     to distinguish   between     each  possible   choice,   this
            shortcut can save a lot of typing, by letting you type only the shortest string that matches an
            argument     type.

            2.1.5.   Bean     Scopes

            When    you   create   a bean   definition,   you   create   a recipe   for  creating   actual   instances    of the  class
            defined   by  that  bean   definition.   The  idea  that  a bean   definition    is a recipe   is  important,   because   it
            means   that,  as with   a class, you  can  create   many    object  instances   from   a single  recipe.


            You  can  control   not  only  the  various   dependencies      and   configuration     values   that are  to  be plugged
            into an object that is created from a particular bean definition but also control the scope of the
            objects  created   from    a particular   bean   definition.   This   approach    is powerful     and  flexible,  because
            you  can  choose    the scope   of  the objects   you  create   through    configuration    instead   of  having   to bake
            in the  scope   of  an  object  at  the  Java  class  level.  Beans   can   be  defined   to  be  deployed    in  one  of  a
            number     of scopes.   The  Spring    Framework      supports    six scopes,   four   of which    are  available   only  if
            you  use  a web-aware      ApplicationContext.      You  can  also  create  a custom    scope.

            The  following   table  describes    the supported     scopes:


            Table 3. Bean   scopes

            Scope                    Description

            singleton                (Default)   Scopes   a single  bean   definition   to a single  object   instance   for each
                                     Spring   IoC  container.

            prototype                Scopes   a  single  bean  definition   to  any  number     of object  instances.

            Scope                    Description

            request                  Scopes   a  single  bean  definition   to  the lifecycle  of a single   HTTP   request.   That
                                     is, each  HTTP    request   has  its  own  instance   of a bean   created   off the  back  of  a
                                     single  bean   definition.   Only  valid  in  the context   of a web-aware      Spring
                                     ApplicationContext.

            session                  Scopes   a  single  bean  definition   to  the lifecycle  of an  HTTP    Session.  Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            application              Scopes   a  single  bean  definition   to  the lifecycle  of a ServletContext.     Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            websocket                Scopes   a  single  bean  definition   to  the lifecycle  of a WebSocket.    Only  valid  in the
                                     context   of a  web-aware     Spring   ApplicationContext.



                              As  of Spring   3.0,  a thread    scope   is available   but  is  not  registered   by   default.  For
                             more   information,     see  the  documentation       for  SimpleThreadScope.      For  instructions
                              on how    to register  this or  any  other  custom    scope,  see  Using   a Custom    Scope.



            The  Singleton    Scope

            Only  one   shared   instance    of a singleton    bean   is  managed,   and   all requests   for  beans   with   an  ID  or
            IDs that  match    that  bean   definition   result  in  that one   specific  bean   instance    being  returned    by  the
            Spring  container.


            To put  it another    way,  when    you  define   a bean   definition   and   it  is  scoped as a singleton,   the  Spring
            IoC container    creates   exactly   one  instance    of the  object  defined   by  that  bean   definition.   This  single
            instance   is stored   in a  cache   of such   singleton    beans,   and  all subsequent      requests   and   references
            for that  named    bean   return   the  cached    object.  The  following    image   shows    how   the  singleton   scope
            works:








































            Spring’s   concept   of  a singleton    bean   differs  from    the  singleton   pattern   as  defined    in the  Gang    of
            Four  (GoF)   patterns    book.  The   GoF   singleton   hard-codes     the  scope   of  an  object  such   that  one  and

            only  one  instance   of  a particular   class  is created   per  ClassLoader.     The  scope   of the  Spring   singleton
            is  best  described  as being   per-container     and   per-bean.   This  means    that,  if  you  define one  bean   for  a
            particular   class in  a single  Spring   container,   the  Spring   container    creates  one   and  only  one   instance
            of the  class  defined   by  that  bean   definition.   The   singleton   scope   is the  default   scope   in Spring.   To
            define  a bean   as  a singleton   in XML,   you   can  define  a bean   as  shown    in the  following   example:



              <bean    id="accountService"        class="com.something.DefaultAccountService"/>


              
              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="singleton"/>




            The  Prototype     Scope

            The non-singleton prototype scope of bean deployment results in the creation of a new bean
            instance every time a request for that specific bean is made. That is, the bean is injected into
            another    bean   or  you  request    it through    a getBean()    method     call on  the  container.    As  a  rule,  you
            should   use  the prototype    scope   for all stateful  beans   and   the singleton   scope   for  stateless  beans.


            The  following   diagram     illustrates  the Spring   prototype    scope:








































            (A data   access  object   (DAO)   is not  typically   configured    as  a prototype,    because    a  typical  DAO    does
            not hold   any  conversational     state. It was   easier  for us  to reuse  the  core  of the  singleton   diagram.)

            The  following   example     defines   a bean   as a prototype    in XML:



              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="prototype"/>



            In contrast   to the  other   scopes,  Spring   does   not  manage     the complete     lifecycle  of a prototype    bean.

            The  container    instantiates,   configures,    and  otherwise     assembles    a  prototype    object  and   hands   it to
            the client,  with   no  further   record   of that  prototype    instance.   Thus,   although    initialization   lifecycle
            callback   methods    are  called  on  all objects   regardless    of scope,  in  the case  of  prototypes,    configured
            destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped
            objects  and   release  expensive     resources    that  the  prototype    beans   hold.  To  get the  Spring   container
            to release  resources    held  by  prototype-scoped      beans,   try  using  a custom    bean   post-processor,     which
            holds  a reference    to beans   that  need   to be cleaned    up.


            In some   respects,   the  Spring   container’s   role  in  regard   to a prototype-scoped       bean  is a  replacement
            for the  Java  new  operator.    All lifecycle  management        past  that  point  must    be  handled    by  the  client.
            (For details  on  the  lifecycle  of a bean   in the  Spring   container,   see  Lifecycle   Callbacks.)


            Singleton    Beans   with   Prototype-bean       Dependencies

            When you use singleton-scoped beans with dependencies on prototype beans, be aware that
            dependencies     are  resolved    at instantiation    time.  Thus,   if  you dependency-inject      a  prototype-scoped
            bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-
            injected  into  the  singleton   bean.   The  prototype    instance    is  the  sole  instance that  is ever  supplied    to
            the singleton-scoped      bean.


            However,    suppose    you   want   the  singleton-scoped      bean   to acquire   a  new   instance   of the  prototype-
            scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into
            your   singleton     bean,    because    that   injection    occurs    only    once,   when     the   Spring    container
            instantiates the singleton bean and resolves and injects its dependencies. If you need a new
            instance   of a prototype    bean   at runtime    more   than   once,  see Method     Injection.


            Request,    Session,   Application,     and   WebSocket      Scopes

            The  request,   session,   application,    and   websocket   scopes   are   available   only  if you   use  a web-aware
            Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you use these
            scopes    with   regular     Spring    IoC   containers,     such   as   the   ClassPathXmlApplicationContext,           an
            IllegalStateException       that complains     about   an  unknown     bean   scope   is thrown.



            Initial  Web Configuration

            To support the scoping of beans at the request, session, application, and websocket levels (web-
            scoped beans), some minor initial configuration is required before you define your beans. (This
            initial setup  is not  required   for  the standard    scopes:   singleton   and   prototype.)


            How   you  accomplish     this  initial setup  depends    on  your   particular   Servlet  environment.


            If  you access  scoped    beans   within   Spring   Web    MVC,   in effect,  within   a request   that  is processed    by
            the  Spring   DispatcherServlet,      no  special   setup   is necessary.   DispatcherServlet       already   exposes    all
            relevant   state.


            If  you use  a  Servlet   web   container,    with  requests    processed    outside   of  Spring’s   DispatcherServlet
            (for     example,        when        using      JSF      or      Struts),     you       need       to     register      the
            org.springframework.web.context.request.RequestContextListener ServletRequestListener. This can
            be done    programmatically       by  using   the WebApplicationInitializer         interface.   Alternatively,    add  the
            following   declaration    to your   web   application’s   web.xml   file:

              <web-app>
                    ...
                    <listener>
                         <listener-class>
                               org.springframework.web.context.request.RequestContextListener
                         </listener-class>
                    </listener>
                    ...
              </web-app>



            Alternatively,     if   there    are    issues     with    your     listener     setup,    consider      using    Spring’s
            RequestContextFilter.        The    filter   mapping       depends      on   the    surrounding       web     application
            configuration,    so you   have   to change    it  as  appropriate.  The  following    listing shows    the  filter part  of
            a web   application:



              <web-app>
                    ...
                    <filter>
                         <filter-name>requestContextFilter</filter-name>
                         <filter-class>org.springframework.web.filter.RequestContextFilter</filter-
              class>
                    </filter>
                    <filter-mapping>
                         <filter-name>requestContextFilter</filter-name>
                         <url-pattern>/*</url-pattern>
                    </filter-mapping>
                    ...
              </web-app>



            DispatcherServlet,     RequestContextListener,        and   RequestContextFilter       all do  exactly   the  same   thing,
            namely    bind  the  HTTP    request   object  to  the  Thread  that  is servicing   that  request.   This  makes    beans
            that are  request-   and  session-scoped      available   further  down    the  call chain.



            Request  scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="loginAction"       class="com.something.LoginAction"              scope="request"/>



            The  Spring   container    creates   a new   instance   of  the LoginAction     bean   by using   the  loginAction    bean
            definition for each and every HTTP request. That is, the loginAction bean is scoped at the HTTP
            request   level. You  can   change   the  internal   state of  the instance    that is created   as  much   as  you  want,
            because other instances created from the same loginAction bean definition do not see these
            changes in state. They are particular to an individual request. When the request completes
            processing,   the  bean   that is scoped   to  the request   is discarded.


            When    using  annotation-driven       components      or Java  configuration,     the  @RequestScope    annotation     can

            be used   to assign  a  component     to the  request   scope.  The   following   example     shows   how   to do  so:


            Java


              @RequestScope
              @Component
              public    class   LoginAction      {
                    //  ...
              }



            Kotlin


              @RequestScope
              @Component
              class    LoginAction     {
                    //  ...
              }




            Session  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>



            The   Spring     container     creates    a  new     instance    of   the   UserPreferences       bean    by   using    the
            userPreferences bean definition for the lifetime of a single HTTP Session. In other words, the
            userPreferences     bean   is effectively   scoped   at the  HTTP    Session   level. As  with   request-scoped     beans,
            you  can  change    the  internal  state  of the  instance   that  is created   as much    as you   want,   knowing    that
            other  HTTP    Session   instances    that  are  also  using  instances    created   from   the  same    userPreferences
            bean  definition    do not  see  these  changes    in state,  because   they   are particular    to an  individual   HTTP
            Session.  When     the  HTTP   Session   is eventually    discarded,    the  bean   that  is scoped   to  that  particular
            HTTP   Session   is also discarded.


            When using annotation-driven components or Java configuration, you can use the @SessionScope
            annotation    to assign   a component      to the session   scope.


            Java


              @SessionScope
              @Component
              public    class   UserPreferences       {
                    //  ...
              }

            Kotlin


              @SessionScope
              @Component
              class    UserPreferences       {
                    //  ...
              }




            Application  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="appPreferences"        class="com.something.AppPreferences"               scope="application"/>



            The  Spring   container    creates  a  new   instance   of the  AppPreferences     bean   by  using  the  appPreferences
            bean  definition   once   for the  entire  web   application.    That  is, the appPreferences     bean   is scoped   at the
            ServletContext     level  and  stored   as a  regular   ServletContext     attribute.  This  is somewhat      similar   to a
            Spring  singleton    bean  but  differs  in two   important    ways:   It is  a singleton  per ServletContext,     not  per
            Spring   ApplicationContext      (for  which   there   may   be  several   in any   given  web   application),    and   it  is
            actually  exposed    and   therefore   visible  as a ServletContext     attribute.


            When      using     annotation-driven        components         or   Java     configuration,      you     can    use    the
            @ApplicationScope annotation to assign a component to the application scope. The following
            example    shows   how    to do so:


            Java


              @ApplicationScope
              @Component
              public    class   AppPreferences       {
                    //  ...
              }



            Kotlin


              @ApplicationScope
              @Component
              class    AppPreferences      {
                    //  ...
              }




            WebSocket    Scope

            WebSocket     scope   is associated   with   the  lifecycle  of a WebSocket      session  and   applies   to STOMP     over
            WebSocket     applications,   see  WebSocket     scope   for  more   details.

            Scoped  Beans   as Dependencies

            The  Spring   IoC  container     manages     not  only  the  instantiation    of  your   objects  (beans),   but  also  the
            wiring   up  of collaborators     (or dependencies).      If  you want   to inject  (for  example)    an  HTTP    request-
            scoped   bean   into  another    bean   of a  longer-lived    scope,  you   may   choose    to inject  an  AOP   proxy    in
            place  of  the  scoped   bean.   That   is,  you need   to  inject  a proxy    object  that  exposes    the  same   public
            interface as the scoped object but that can also retrieve the real target object from the relevant
            scope  (such   as an  HTTP   request)   and   delegate   method    calls  onto  the  real object.


                              You  may   also  use  <aop:scoped-proxy/>       between    beans   that  are  scoped   as  singleton,
                              with  the  reference    then   going   through    an  intermediate     proxy    that  is serializable
                              and  therefore   able  to  re-obtain   the target  singleton    bean  on  deserialization.


                              When declaring <aop:scoped-proxy/> against a bean of scope prototype, every
                              method    call on  the  shared    proxy   leads   to the  creation   of a  new   target  instance    to
                              which   the  call is  then being  forwarded.

                              Also, scoped    proxies   are  not  the only   way   to access  beans    from   shorter   scopes  in  a
                              lifecycle-safe fashion. You may also declare your injection point (that is, the
                             constructor    or setter  argument     or  autowired    field)  as ObjectFactory<MyTargetBean>,
                              allowing   for  a  getObject()    call to  retrieve   the  current   instance    on  demand     every
                              time  it  is  needed — without    holding    on to  the instance   or  storing  it separately.


                              As an extended variant, you may declare ObjectProvider<MyTargetBean> which
                              delivers    several     additional     access     variants,    including      getIfAvailable      and
                              getIfUnique.


                              The    JSR-330     variant     of   this    is   called    Provider     and     is   used    with     a
                              Provider<MyTargetBean> declaration and a corresponding get() call for every
                              retrieval  attempt.   See  here  for  more   details  on  JSR-330   overall.


            The  configuration     in  the following    example     is only  one   line, but  it is important    to  understand     the
            “why”   as well  as  the “how”    behind   it:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    
                    <bean   id="userPreferences"         class="com.something.UserPreferences"               scope="session">
                         
                         <aop:scoped-proxy/>         ①
                    </bean>


                    
                    <bean   id="userService"       class="com.something.SimpleUserService">
                         
                         <property     name="userPreferences"          ref="userPreferences"/>
                    </bean>
              </beans>


            ① The    line that  defines   the proxy.

            To create   such  a proxy,   you  insert  a child  <aop:scoped-proxy/>       element    into  a scoped   bean   definition
            (see Choosing the Type of Proxy to Create and XML Schema-based configuration). Why do
            definitions   of beans   scoped   at  the request,   session   and  custom-scope      levels  require   the  <aop:scoped-
            proxy/> element? Consider the following singleton bean definition and contrast it with what you
            need to define for the aforementioned scopes (note that the following userPreferences bean
            definition   as it  stands is incomplete):



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            In the  preceding    example,    the  singleton   bean   (userManager)    is injected   with  a  reference   to  the HTTP
            Session-scoped bean (userPreferences). The salient point here is that the userManager bean is a
            singleton:   it  is  instantiated exactly   once   per  container,   and   its dependencies      (in this case   only  one,
            the userPreferences bean) are also injected only once. This means that the userManager bean
            operates   only  on  the  exact  same   userPreferences      object  (that  is,  the  one  with which   it was  originally
            injected).

            This  is not  the  behavior    you   want   when    injecting   a  shorter-lived    scoped    bean   into  a longer-lived
            scoped   bean   (for  example,    injecting   an   HTTP   Session-scoped      collaborating     bean   as  a dependency
            into singleton    bean).  Rather,   you   need   a single  userManager     object,  and,  for  the lifetime   of an  HTTP
            Session,  you   need   a userPreferences      object  that  is specific  to the  HTTP    Session.   Thus,  the  container

            creates  an  object   that  exposes   the  exact   same   public   interface   as  the  UserPreferences     class  (ideally
            an  object  that  is a UserPreferences      instance),   which    can  fetch  the  real  UserPreferences      object  from
            the scoping mechanism (HTTP request, Session, and so forth). The container injects this proxy
            object  into the  userManager    bean,   which   is unaware     that  this UserPreferences     reference    is a proxy.   In
            this  example,     when     a   UserManager     instance     invokes    a   method     on   the   dependency-injected
            UserPreferences     object,  it is actually   invoking    a  method     on  the  proxy.   The  proxy    then  fetches   the
            real UserPreferences object from (in this case) the HTTP Session and delegates the method
            invocation    onto  the  retrieved   real UserPreferences      object.

            Thus, you need the following (correct and complete) configuration when injecting request- and
            session-scoped     beans   into collaborating     objects,  as the  following   example    shows:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session">
                    <aop:scoped-proxy/>
              </bean>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>




            Choosing    the  Type   of  Proxy   to  Create

            By default, when the Spring container creates a proxy for a bean that is marked up with the
            <aop:scoped-proxy/>      element,    a CGLIB-based     class  proxy   is created.


                              CGLIB   proxies   intercept    only  public   method    calls! Do   not  call non-public    methods
                             on such   a proxy.   They  are  not  delegated    to the  actual  scoped   target  object.


            Alternatively, you can configure the Spring container to create standard JDK interface-based
            proxies   for such   scoped   beans,   by  specifying   false   for the  value   of the  proxy-target-class      attribute
            of the  <aop:scoped-proxy/>      element.    Using   JDK  interface-based      proxies   means    that  you  do  not  need
            additional   libraries   in your   application    classpath    to affect  such   proxying.    However,     it also  means
            that the  class  of  the  scoped   bean   must    implement     at  least one   interface   and   that  all collaborators
            into which    the  scoped    bean   is injected   must   reference    the  bean   through    one  of  its interfaces.   The
            following   example    shows    a proxy   based   on  an  interface:



              
              <bean    id="userPreferences"        class="com.stuff.DefaultUserPreferences"                 scope="session">
                    <aop:scoped-proxy        proxy-target-class="false"/>
              </bean>


              <bean    id="userManager"       class="com.stuff.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            For   more    detailed    information      about    choosing     class-based     or  interface-based      proxying,     see
            Proxying    Mechanisms.

            Custom    Scopes

            The bean scoping mechanism is extensible. You can define your own scopes or even redefine
            existing  scopes,   although    the  latter is considered     bad  practice   and   you  cannot    override   the  built-in
            singleton   and   prototype   scopes.



            Creating  a Custom   Scope

            To   integrate    your    custom     scopes    into   the   Spring    container,     you    need    to   implement      the
            org.springframework.beans.factory.config.Scope               interface,  which    is  described  in  this section.  For  an
            idea  of how    to implement     your   own    scopes,  see  the  Scope   implementations       that  are  supplied    with
            the Spring Framework itself and the Scope javadoc, which explains the methods you need to
            implement     in more   detail.


            The  Scope   interface   has  four  methods     to  get objects   from   the  scope,   remove    them    from   the  scope,
            and  let them   be  destroyed.


            The session scope implementation, for example, returns the session-scoped bean (if it does not
            exist, the  method    returns   a new   instance   of  the bean,   after  having   bound    it  to  the  session  for  future
            reference).   The  following    method    returns   the  object  from   the underlying     scope:


            Java


              Object    get(String     name,   ObjectFactory<?>        objectFactory)



            Kotlin


              fun   get(name:     String,    objectFactory:      ObjectFactory<*>):        Any



            The session scope implementation, for example, removes the session-scoped bean from the
            underlying    session.   The   object  should    be  returned,    but  you  can   return   null  if the  object   with  the
            specified  name    is not  found.  The   following   method     removes    the  object  from   the underlying     scope:


            Java


              Object    remove(String      name)



            Kotlin


              fun   remove(name:      String):    Any



            The following method registers a callback that the scope should invoke when it is destroyed or
            when   the  specified   object  in the  scope   is  destroyed:


            Java


              void   registerDestructionCallback(String              name,    Runnable    destructionCallback)

            Kotlin


              fun   registerDestructionCallback(name:              String,    destructionCallback:        Runnable)



            See the  javadoc   or  a Spring   scope   implementation      for  more   information     on  destruction    callbacks.

            The  following   method     obtains   the conversation     identifier   for the  underlying    scope:


            Java


              String    getConversationId()



            Kotlin


              fun   getConversationId():         String



            This  identifier  is different   for  each   scope.  For  a  session   scoped   implementation,       this identifier   can
            be the  session   identifier.



            Using a Custom    Scope

            After  you  write   and   test one  or  more   custom    Scope   implementations,       you  need   to make    the  Spring
            container   aware    of your   new   scopes.   The  following    method    is the  central   method    to register   a new
            Scope  with  the  Spring   container:


            Java


              void   registerScope(String         scopeName,     Scope   scope);



            Kotlin


              fun   registerScope(scopeName:          String,    scope:    Scope)



            This  method     is declared   on   the  ConfigurableBeanFactory        interface,   which    is available   through    the
            BeanFactory property on most of the concrete ApplicationContext implementations that ship with
            Spring.


            The  first argument      to the  registerScope(..)       method    is the  unique    name    associated    with   a  scope.
            Examples of such names in the Spring container itself are singleton and prototype. The second
            argument      to   the   registerScope(..)        method      is   an   actual    instance     of   the   custom      Scope
            implementation      that  you  wish   to register  and   use.

            Suppose that you write your custom Scope implementation, and then register it as shown in the
            next  example.

                              The  next  example     uses  SimpleThreadScope,      which   is included    with  Spring   but  is not
                             registered by default. The instructions would be the same for your own custom
                              Scope  implementations.


            Java


              Scope    threadScope     =  new  SimpleThreadScope();
              beanFactory.registerScope("thread",               threadScope);



            Kotlin


              val   threadScope     =  SimpleThreadScope()
              beanFactory.registerScope("thread",               threadScope)



            You can then create bean definitions that adhere to the scoping rules of your custom Scope, as
            follows:



              <bean    id="..."    class="..."     scope="thread">



            With  a  custom   Scope   implementation,      you  are  not  limited   to programmatic      registration    of the  scope.
            You  can  also  do  the  Scope  registration   declaratively,    by  using  the  CustomScopeConfigurer       class,  as the
            following   example    shows:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    <bean   class="org.springframework.beans.factory.config.CustomScopeConfigurer">
                         <property     name="scopes">
                               <map>
                                    <entry    key="thread">
                                          <bean
              class="org.springframework.context.support.SimpleThreadScope"/>
                                    </entry>
                               </map>
                         </property>
                    </bean>


                    <bean   id="thing2"      class="x.y.Thing2"        scope="thread">
                         <property     name="name"      value="Rick"/>
                         <aop:scoped-proxy/>
                    </bean>


                    <bean   id="thing1"      class="x.y.Thing1">
                         <property     name="thing2"      ref="thing2"/>
                    </bean>


              </beans>




                              When    you  place   <aop:scoped-proxy/>       within   a <bean>   declaration    for a  FactoryBean
                             implementation,      it is the factory   bean   itself that  is scoped,   not  the  object  returned
                              from  getObject().


            2.1.6.   Customizing          the   Nature       of  a Bean

            The  Spring   Framework       provides    a number     of  interfaces   you   can  use  to  customize    the  nature   of  a
            bean.  This  section   groups   them   as follows:

              • Lifecycle   Callbacks

              • ApplicationContextAware        and  BeanNameAware

              • Other   Aware  Interfaces


            Lifecycle   Callbacks

            To  interact  with   the  container’s    management       of  the bean    lifecycle,  you  can   implement     the  Spring
            InitializingBean and DisposableBean interfaces. The container calls afterPropertiesSet() for the

            former   and   destroy()    for the  latter  to let the  bean   perform     certain  actions   upon    initialization  and
            destruction    of your  beans.


                              The  JSR-250   @PostConstruct      and  @PreDestroy     annotations     are  generally   considered
                              best practice   for receiving    lifecycle  callbacks   in a modern     Spring   application.   Using
                              these annotations means that your beans are not coupled to Spring-specific
                             interfaces.  For  details,  see Using   @PostConstruct     and   @PreDestroy.


                              If you do not want to use the JSR-250 annotations but you still want to remove
                              coupling,   consider   init-method    and   destroy-method     bean   definition   metadata.


            Internally,  the  Spring   Framework       uses  BeanPostProcessor       implementations       to process   any   callback
            interfaces it can find and call the appropriate methods. If you need custom features or other
            lifecycle  behavior    Spring  does   not  by default   offer, you   can  implement     a BeanPostProcessor      yourself.
            For more    information,    see  Container    Extension    Points.


            In addition to the initialization and destruction callbacks, Spring-managed objects may also
            implement     the  Lifecycle   interface   so  that those   objects  can  participate    in the  startup  and   shutdown
            process,  as  driven   by the  container’s    own   lifecycle.


            The  lifecycle  callback   interfaces   are  described    in this section.



            Initialization Callbacks

            The     org.springframework.beans.factory.InitializingBean                   interface     lets    a    bean      perform
            initialization    work    after   the   container     has   set   all  necessary     properties     on   the   bean.    The
            InitializingBean     interface   specifies   a single  method:



              void   afterPropertiesSet()         throws    Exception;



            We  recommend       that  you  do  not  use  the InitializingBean      interface,   because   it unnecessarily     couples
            the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a
            POJO   initialization  method.    In  the  case  of XML-based      configuration    metadata,    you   can  use  the  init-
            method attribute to specify the name of the method that has a void no-argument signature. With
            Java  configuration,    you   can  use  the  initMethod    attribute   of @Bean.  See  Receiving    Lifecycle   Callbacks.
            Consider   the  following    example:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            init-method="init"/>



            Java


              public    class   ExampleBean      {


                    public   void   init()    {
                         //  do   some  initialization       work
                    }
              }

            Kotlin


              class    ExampleBean     {


                    fun  init()    {
                         //  do   some  initialization       work
                    }
              }



            The  preceding    example     has  almost   exactly  the  same   effect  as the  following    example    (which   consists
            of two  listings):



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     InitializingBean        {


                    @Override
                    public   void   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            Kotlin


              class    AnotherExampleBean        : InitializingBean        {


                    override    fun   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            However,    the  first of the  two  preceding    examples     does  not  couple   the  code  to Spring.



            Destruction   Callbacks

            Implementing the org.springframework.beans.factory.DisposableBean interface lets a bean get a
            callback   when    the  container    that  contains   it is destroyed.    The   DisposableBean     interface   specifies   a
            single  method:



              void   destroy()     throws    Exception;



            We  recommend       that  you   do  not  use  the DisposableBean      callback   interface,  because    it unnecessarily
            couples   the  code  to Spring.   Alternatively,    we  suggest   using   the @PreDestroy     annotation    or  specifying
            a generic   method     that  is supported     by  bean   definitions.   With   XML-based      configuration     metadata,
            you  can   use  the  destroy-method     attribute   on  the  <bean/>.   With   Java  configuration,     you   can  use  the

            destroyMethod      attribute    of  @Bean.   See    Receiving     Lifecycle    Callbacks.    Consider     the   following
            definition:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            destroy-method="cleanup"/>



            Java


              public    class   ExampleBean      {


                    public   void   cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    ExampleBean     {


                    fun  cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            The  preceding    definition   has  almost   exactly   the same    effect as  the following    definition:



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     DisposableBean       {


                    @Override
                    public   void   destroy()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    AnotherExampleBean        : DisposableBean       {


                    override    fun   destroy()    {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }

            However,    the  first of the  two  preceding    definitions   does   not  couple   the code   to Spring.


                              You  can  assign   the destroy-method     attribute   of a <bean>   element    a special  (inferred)
                              value, which instructs Spring to automatically detect a public close or shutdown
                              method       on     the    specific     bean      class.     (Any     class     that    implements
                              java.lang.AutoCloseable or java.io.Closeable would therefore match.) You can
                             also  set this  special  (inferred)    value   on  the  default-destroy-method        attribute   of  a
                              <beans> element to apply this behavior to an entire set of beans (see Default
                              Initialization  and   Destroy   Methods).    Note   that this  is  the  default behavior   with   Java
                              configuration.



            Default  Initialization and  Destroy  Methods

            When you write initialization and destroy method callbacks that do not use the Spring-specific
            InitializingBean      and  DisposableBean      callback   interfaces,   you   typically   write  methods     with   names
            such as init(), initialize(), dispose(), and so on. Ideally, the names of such lifecycle callback
            methods    are  standardized      across  a  project  so  that  all developers    use   the same    method    names    and
            ensure   consistency.


            You can configure the Spring container to “look” for named initialization and destroy callback
            method names on every bean. This means that you, as an application developer, can write your
            application    classes  and   use  an  initialization   callback   called  init(),   without   having    to configure    an
            init-method="init"      attribute   with  each   bean   definition.   The  Spring    IoC container    calls  that  method
            when   the  bean   is created   (and  in accordance     with   the standard    lifecycle  callback   contract   described
            previously).   This  feature   also enforces    a consistent   naming     convention    for  initialization   and  destroy
            method    callbacks.

            Suppose that your initialization callback methods are named init() and your destroy callback
            methods    are  named    destroy().   Your   class then   resembles    the  class  in the following    example:


            Java


              public    class   DefaultBlogService        implements     BlogService      {


                    private    BlogDao    blogDao;


                    public   void   setBlogDao(BlogDao        blogDao)     {
                         this.blogDao      =  blogDao;
                    }


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    public   void   init()    {
                         if  (this.blogDao       ==  null)   {
                               throw   new   IllegalStateException("The           [blogDao]    property     must   be  set.");
                         }
                    }
              }

            Kotlin


              class    DefaultBlogService        : BlogService      {


                    private    var  blogDao:     BlogDao?    =  null


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    fun  init()    {
                         if  (blogDao     ==  null)   {
                               throw   IllegalStateException("The           [blogDao]     property    must   be  set.")
                         }
                    }
              }



            You  could  then   use  that class  in a bean   resembling     the  following:



              <beans    default-init-method="init">


                    <bean   id="blogService"       class="com.something.DefaultBlogService">
                         <property     name="blogDao"       ref="blogDao"      />
                    </bean>


              </beans>



            The  presence    of the  default-init-method      attribute   on  the  top-level  <beans/>    element   attribute   causes
            the  Spring   IoC  container    to recognize     a method     called  init  on  the  bean    class  as the  initialization
            method    callback.   When    a  bean   is  created  and  assembled,     if the bean    class has   such  a  method,    it  is
            invoked   at the  appropriate     time.


            You can configure destroy method callbacks similarly (in XML, that is) by using the default-
            destroy-method     attribute  on  the  top-level  <beans/>    element.


            Where    existing   bean   classes   already   have   callback    methods    that  are   named    at  variance    with  the
            convention,    you   can  override   the  default   by  specifying   (in  XML,   that  is) the method     name    by using
            the init-method    and   destroy-method     attributes   of the  <bean/>  itself.


            The  Spring   container    guarantees    that  a configured    initialization   callback   is called  immediately     after
            a bean   is supplied   with   all dependencies.     Thus,   the  initialization  callback    is  called on  the raw   bean
            reference,   which   means    that  AOP   interceptors    and   so forth  are  not  yet  applied   to the  bean.  A  target
            bean  is fully  created   first and  then  an  AOP   proxy   (for  example)    with  its interceptor    chain   is  applied.
            If  the  target bean   and  the  proxy    are  defined   separately,   your   code   can  even   interact   with  the  raw
            target  bean,   bypassing    the  proxy.   Hence,   it would    be  inconsistent    to  apply   the  interceptors    to the
            init method, because doing so would couple the lifecycle of the target bean to its proxy or
            interceptors and leave strange semantics when your code interacts directly with the raw target
            bean.

---

### Spring Ai Commons/Src/Test/Resources/Bikes.Json (spring-ai-commons/src/test/resources/bikes.json)

[
  {
    "name": "E-Adrenaline 8.0 EX1",
    "shortDescription": "a versatile and comfortable e-MTB designed for adrenaline enthusiasts who want to explore all types of terrain. It features a powerful motor and advanced suspension to provide a smooth and responsive ride, with a variety of customizable settings to fit any rider's needs.",
    "description": "## Overview\r\nIt's right for you if...\r\nYou want to push your limits on challenging trails and terrain, with the added benefit of an electric assist to help you conquer steep climbs and rough terrain. You also want a bike with a comfortable and customizable fit, loaded with high-quality components and technology.\r\n\r\nThe tech you get\r\nA lightweight, full ADV Mountain Carbon frame with a customizable geometry, including an adjustable head tube and chainstay length. A powerful and efficient motor with a 375Wh battery that can assist up to 28 mph when it's on, and provides a smooth and seamless transition when it's off. A SRAM EX1 8-speed drivetrain, a RockShox Lyrik Ultimate fork, and a RockShox Super Deluxe Ultimate rear shock.\r\n\r\nThe final word\r\nOur E-Adrenaline 8.0 EX1 is the perfect bike for adrenaline enthusiasts who want to explore all types of terrain. It's versatile, comfortable, and loaded with advanced technology to provide a smooth and responsive ride, no matter where your adventures take you.\r\n\r\n\r\n## Features\r\nVersatile and customizable\r\nThe E-Adrenaline 8.0 EX1 features a customizable geometry, including an adjustable head tube and chainstay length, so you can fine-tune your ride to fit your needs and preferences. It also features a variety of customizable settings, including suspension tuning, motor assistance levels, and more.\r\n\r\nPowerful and efficient\r\nThe bike is equipped with a powerful and efficient motor that provides a smooth and seamless transition between human power and electric assist. It can assist up to 28 mph when it's on, and provides zero drag when it's off.\r\n\r\nAdvanced suspension\r\nThe E-Adrenaline 8.0 EX1 features a RockShox Lyrik Ultimate fork and a RockShox Super Deluxe Ultimate rear shock, providing advanced suspension technology to absorb shocks and bumps on any terrain. The suspension is also customizable to fit your riding style and preferences.\r\n\r\n\r\n## Specs\r\nFrameset\r\nFrame ADV Mountain Carbon main frame & stays, adjustable head tube and chainstay length, tapered head tube, Knock Block, Control Freak internal routing, Boost148, 150mm travel\r\nFork RockShox Lyrik Ultimate, DebonAir spring, Charger 2.1 RC2 damper, remote lockout, tapered steerer, 42mm offset, Boost110, 15mm Maxle Stealth, 160mm travel\r\nShock RockShox Super Deluxe Ultimate, DebonAir spring, Thru Shaft 3-position damper, 230x57.5mm\r\n\r\nWheels\r\nWheel front Bontrager Line Elite 30, ADV Mountain Carbon, Tubeless Ready, 6-bolt, Boost110, 15mm thru axle\r\nWheel rear Bontrager Line Elite 30, ADV Mountain Carbon, Tubeless Ready, 54T Rapid Drive, 6-bolt, Shimano MicroSpline freehub, Boost148, 12mm thru axle\r\nSkewer rear Bontrager Switch thru axle, removable lever\r\nTire Bontrager XR5 Team Issue, Tubeless Ready, Inner Strength sidewall, aramid bead, 120tpi, 29x2.50''\r\nTire part Bontrager TLR sealant, 6oz\r\n\r\nDrivetrain\r\nShifter SRAM EX1, 8 speed\r\nRear derailleur SRAM EX1, 8 speed\r\nCrank Bosch Performance CX, magnesium motor body, 250 watt, 75 Nm torque\r\nChainring SRAM EX1, 18T, steel\r\nCassette SRAM EX1, 11-48, 8 speed\r\nChain SRAM EX1, 8 speed\r\n\r\nComponents\r\nSaddle Bontrager Arvada, hollow chromoly rails, 138mm width\r\nSeatpost Bontrager Line Elite Dropper, internal routing, 31.6mm\r\nHandlebar Bontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\r\nGrips Bontrager XR Trail Elite, alloy lock-on\r\nStem Bontrager Line Pro, 35mm, Knock Block, Blendr compatible, 0 degree, 50mm length\r\nHeadset Knock Block Integrated, 62-degree radius, cartridge bearing, 1-1\/8'' top, 1.5'' bottom\r\nBrake SRAM G2 RSC hydraulic disc, carbon levers\r\nBrake rotor SRAM Centerline, centerlock, round edge, 200mm\r\n\r\nAccessories\r\nE-bike system Bosch Performance CX, magnesium motor body, 250 watt, 75 Nm torque\r\nBattery Bosch PowerTube 625, 625Wh\r\nCharger Bosch 4A standard charger\r\nController Bosch Kiox with Anti-theft solution, Bluetooth connectivity, 1.9'' display\r\nTool Bontrager Switch thru axle, removable lever\r\n\r\nWeight\r\nWeight M - 20.25 kg \/ 44.6 lbs (with TLR sealant, no tubes)\r\nWeight limit This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\r\n\r\n## Sizing & fit\r\n\r\n| Size |       Rider Height       |        Inseam        |\r\n|:----:|:------------------------:|:--------------------:|\r\n|   S  | 155 - 170 cm 5'1\" - 5'7\" | 73 - 80 cm 29\" - 31.5\" |\r\n|   M  | 163 - 178 cm 5'4\" - 5'10\" | 77 - 83 cm 30.5\" - 32.5\" |\r\n|   L  | 176 - 191 cm 5'9\" - 6'3\" | 83 - 89 cm 32.5\" - 35\" |\r\n|  XL  | 188 - 198 cm 6'2\" - 6'6\" | 88 - 93 cm 34.5\" - 36.5\" |\r\n\r\n\r\n## Geometry\r\n\r\nAll measurements provided in cm unless otherwise noted.\r\nSizing table\r\n| Frame size letter         | S     | M     | L     | XL    |\r\n|---------------------------|-------|-------|-------|-------|\r\n| Actual frame size         | 15.8  | 17.8  | 19.8  | 21.8  |\r\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\r\n| A \u2014 Seat tube             | 40.0  | 42.5  | 47.5  | 51.0  |\r\n| B \u2014 Seat tube angle       | 72.5\u00B0 | 72.8\u00B0 | 73.0\u00B0 | 73.0\u00B0 |\r\n| C \u2014 Head tube length      | 9.5   | 10.5  | 11.0  | 11.5  |\r\n| D \u2014 Head angle            | 67.8\u00B0 | 67.8\u00B0 | 67.8\u00B0 | 67.8\u00B0 |\r\n| E \u2014 Effective top tube    | 59.0  | 62.0  | 65.0  | 68.0  |\r\n| F \u2014 Bottom bracket height | 32.5  | 32.5  | 32.5  | 32.5  |\r\n| G \u2014 Bottom bracket drop   | 5.5   | 5.5   | 5.5   | 5.5   |\r\n| H \u2014 Chainstay length      | 45.0  | 45.0  | 45.0  | 45.0  |\r\n| I \u2014 Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\r\n| J \u2014 Trail                 | 11.0  | 11.0  | 11.0  | 11.0  |\r\n| K \u2014 Wheelbase             | 113.0 | 117.0 | 120.0 | 123.0 |\r\n| L \u2014 Standover             | 77.0  | 77.0  | 77.0  | 77.0  |\r\n| M \u2014 Frame reach           | 41.0  | 44.5  | 47.5  | 50.0  |\r\n| N \u2014 Frame stack           | 61.0  | 62.0  | 62.5  | 63.0  |",
    "price": 1499.99,
    "tags": [
      "bicycle"
    ]
  },
  {
    "name": "Enduro X Pro",
    "shortDescription": "The Enduro X Pro is the ultimate mountain bike for riders who demand the best. With its full carbon frame and top-of-the-line components, this bike is ready to tackle any trail, from technical downhill descents to grueling uphill climbs.",
    "text": "## Overview\nIt's right for you if...\nYou're an experienced mountain biker who wants a high-performance bike that can handle any terrain. You want a bike with the best components available, including a full carbon frame, suspension system, and hydraulic disc brakes.\n\nThe tech you get\nOur top-of-the-line full carbon frame with aggressive geometry and a slack head angle for maximum control. It's equipped with a Fox Factory suspension system with 170mm of travel in the front and 160mm in the rear, a Shimano XTR 12-speed drivetrain, and hydraulic disc brakes for maximum stopping power. The bike also features a dropper seatpost for easy adjustments on the fly.\n\nThe final word\nThe Enduro X Pro is the ultimate mountain bike for riders who demand the best. With its full carbon frame, top-of-the-line components, and aggressive geometry, this bike is ready to take on any trail. Whether you're a seasoned pro or just starting out, the Enduro X Pro will help you take your riding to the next level.\n\n## Features\nFull carbon frame\nAggressive geometry with a slack head angle\nFox Factory suspension system with 170mm of travel in the front and 160mm in the rear\nShimano XTR 12-speed drivetrain\nHydraulic disc brakes for maximum stopping power\nDropper seatpost for easy adjustments on the fly\n\n## Specifications\nFrameset\nFrame\tFull carbon frame\nFork\tFox Factory suspension system with 170mm of travel\nRear suspension\tFox Factory suspension system with 160mm of travel\n\nWheels\nWheel size\t27.5\" or 29\"\nTires\tTubeless-ready Maxxis tires\n\nDrivetrain\nShifters\tShimano XTR 12-speed\nFront derailleur\tN/A\nRear derailleur\tShimano XTR\nCrankset\tShimano XTR\nCassette\tShimano XTR 12-speed\nChain\tShimano XTR\n\nComponents\nBrakes\tHydraulic disc brakes\nHandlebar\tAlloy handlebar\nStem\tAlloy stem\nSeatpost\tDropper seatpost\n\nAccessories\nPedals\tNot included\n\nWeight\nWeight\tApproximately 27-29 lbs\n\n## Sizing\n| Size |        Rider Height       |\n|:----:|:-------------------------:|\n|  S  |  5'4\" - 5'8\" (162-172cm) |\n|  M  |  5'8\" - 5'11\" (172-180cm) |\n|  L  |  5'11\" - 6'3\" (180-191cm) |\n|  XL |  6'3\" - 6'6\" (191-198cm) |\n\n## Geometry\n| Size |        S        |        M       |        L         |        XL       |\n|:----:|:---------------:|:---------------:|:-----------------:|:---------------:|\n| A - Seat tube length |   390mm   |   425mm   |     460mm     |    495mm   |\n| B - Effective top tube length |  585mm  |  610mm  |    635mm     |  660mm |\n| C - Head tube angle |  65.5°  |  65.5°  |  65.5°  |  65.5°  |\n| D - Seat tube angle |  76°  |  76°  |  76°  |  76°  |\n| E - Chainstay length |  435mm  |  435mm  |  435mm  |  435mm  |\n| F - Head tube length |  100mm  |  110mm  |  120mm  |  130mm  |\n| G - BB drop |  20mm  |  20mm  |  20mm  |  20mm  |\n| H - Wheelbase |  1155mm  |  1180mm  |  1205mm  |  1230mm  |\n| I - Standover height |  780mm  |  800mm  |  820mm  |  840mm  |\n| J - Reach |  425mm  |  450mm  |  475mm  |  500mm  |\n| K - Stack |  610mm  |  620mm  |  630mm  |  640mm  |",
    "price": 599.99,
    "tags": [
      "bicycle"
    ]
  },
  {
    "name": "Blaze X1",
    "shortDescription": "Blaze X1 is a high-performance road bike that offers superior speed and agility, making it perfect for competitive racing or fast-paced group rides. The bike features a lightweight carbon frame, aerodynamic tube shapes, a 12-speed Shimano Ultegra drivetrain, and hydraulic disc brakes for precise stopping power. With its sleek design and cutting-edge technology, Blaze X1 is a bike that is built to perform and dominate on any road.",
    "description": "## Overview\nIt's right for you if...\nYou're a competitive road cyclist or an enthusiast who enjoys fast-paced group rides. You want a bike that is lightweight, agile, and delivers exceptional speed.\n\nThe tech you get\nBlaze X1 features a lightweight carbon frame with a tapered head tube and aerodynamic tube shapes for maximum speed and efficiency. The bike is equipped with a 12-speed Shimano Ultegra drivetrain for smooth and precise shifting, Shimano hydraulic disc brakes for powerful and reliable stopping power, and Bontrager Aeolus Elite 35 carbon wheels for increased speed and agility.\n\nThe final word\nBlaze X1 is a high-performance road bike that is designed to deliver exceptional speed and agility. With its cutting-edge technology and top-of-the-line components, it's a bike that is built to perform and dominate on any road.\n\n## Features\nSpeed and efficiency\nBlaze X1's lightweight carbon frame and aerodynamic tube shapes offer maximum speed and efficiency, allowing you to ride faster and farther with ease.\n\nPrecision stopping power\nShimano hydraulic disc brakes provide precise and reliable stopping power, even in wet or muddy conditions.\n\nAgility and control\nBontrager Aeolus Elite 35 carbon wheels make Blaze X1 incredibly agile and responsive, allowing you to navigate tight turns and corners with ease.\n\nSmooth and precise shifting\nThe 12-speed Shimano Ultegra drivetrain offers smooth and precise shifting, so you can easily find the right gear for any terrain.\n\n## Specifications\nFrameset\nFrame\tADV Carbon, tapered head tube, BB90, direct mount rim brakes, internal cable routing, DuoTrap S compatible, 130x9mm QR\nFork\tADV Carbon, tapered steerer, direct mount rim brakes, internal brake routing, 100x9mm QR\n\nWheels\nWheel front\tBontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, 100x9mm QR\nWheel rear\tBontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, Shimano 11-speed freehub, 130x9mm QR\nTire front\tBontrager R3 Hard-Case Lite, aramid bead, 120 tpi, 700x25c\nTire rear\tBontrager R3 Hard-Case Lite, aramid bead, 120 tpi, 700x25c\nMax tire size\t25c Bontrager tires (with at least 4mm of clearance to frame)\n\nDrivetrain\nShifter\tShimano Ultegra R8020, 12 speed\nFront derailleur\tShimano Ultegra R8000, braze-on\nRear derailleur\tShimano Ultegra R8000, short cage, 30T max cog\nCrank\tSize: 50, 52, 54\nShimano Ultegra R8000, 50/34 (compact), 170mm length\nSize: 56, 58, 60, 62\nShimano Ultegra R8000, 50/34 (compact), 172.5mm length\nBottom bracket\tBB90, Shimano press-fit\nCassette\tShimano Ultegra R8000, 11-30, 12 speed\nChain\tShimano Ultegra HG701, 12 speed\n\nComponents\nSaddle\tBontrager Montrose Elite, titanium rails, 138mm width\nSeatpost\tBontrager carbon seatmast cap, 20mm offset\nHandlebar\tBontrager Elite Aero VR-CF, alloy, 31.8mm, internal cable routing, 40cm width\nGrips\tBontrager Supertack Perf tape\nStem\tBontrager Elite, 31.8mm, Blendr-compatible, 7 degree, 80mm length\nBrake Shimano Ultegra hydraulic disc brake\n\nWeight\nWeight\t56 - 8.91 kg / 19.63 lbs (with tubes)\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size | Rider height |\n|------|-------------|\n| 50   | 162-166cm   |\n| 52   | 165-170cm   |\n| 54   | 168-174cm   |\n| 56   | 174-180cm   |\n| 58   | 179-184cm   |\n| 60   | 184-189cm   |\n| 62   | 189-196cm   |\n\n## Geometry\n| Frame size | 50cm | 52cm | 54cm | 56cm | 58cm | 60cm | 62cm |\n|------------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A - Seat tube | 443mm | 460mm | 478mm | 500mm | 520mm | 540mm | 560mm |\n| B - Seat tube angle | 74.1° | 73.9° | 73.7° | 73.4° | 73.2° | 73.0° | 72.8° |\n| C - Head tube length | 100mm | 110mm | 130mm | 150mm | 170mm | 190mm | 210mm |\n| D - Head angle | 71.4° | 72.0° | 72.5° | 73.0° | 73.3° | 73.6° | 73.8° |\n| E - Effective top tube | 522mm | 535mm | 547mm | 562mm | 577mm | 593mm | 610mm |\n| F - Bottom bracket height | 268mm | 268mm | 268mm | 268mm | 268mm | 268mm | 268mm |\n| G - Bottom bracket drop | 69mm | 69mm | 69mm | 69mm | 69mm | 69mm | 69mm |\n| H - Chainstay length | 410mm | 410mm | 410mm | 410mm | 410mm | 410mm | 410mm |\n| I - Offset | 50mm | 50mm | 50mm | 50mm | 50mm | 50mm | 50mm |\n| J - Trail | 65mm | 62mm | 59mm | 56mm | 55mm | 53mm | 52mm |\n| K - Wheelbase | 983mm | 983mm | 990mm | 1005mm | 1019mm | 1036mm | 1055mm |\n| L - Standover | 741mm | 765mm | 787mm | 806mm | 825mm | 847mm | 869mm |",
    "price": 799.99,
    "tags": [
      "bicycle",
      "mountain bike"
    ]
  },
  {
    "name": "Celerity X5",
    "shortDescription": "Celerity X5 is a versatile and reliable road bike that is designed for experienced and amateur riders alike. It's designed to provide smooth and comfortable rides over long distances. With an ultra-lightweight and responsive carbon fiber frame, Shimano 105 groupset, hydraulic disc brakes, and 28mm wide tires, this bike ensures efficient power transfer, precise handling, and superior stopping power.",
    "description": "## Overview\n\nIt's right for you if...    \nYou are looking for a high-performance road bike that offers a perfect balance of speed, comfort, and control. You enjoy long-distance rides and need a bike that is designed to handle various road conditions with ease. You also appreciate the latest technology and reliable components that make your riding experience more enjoyable.\n\nThe tech you get    \nCelerity X5 is equipped with a full carbon fiber frame that ensures maximum strength and durability while keeping the weight down. It features a Shimano 105 groupset with 11-speed gearing for precise and efficient shifting. Hydraulic disc brakes offer superior stopping power, and 28mm wide tires provide comfort and stability on various road surfaces. Internal cable routing enhances the bike's sleek appearance.\n\nThe final word    \nIf you are looking for a high-performance road bike that offers comfort, speed, and control, Celerity X5 is the perfect choice. With its lightweight carbon fiber frame, reliable components, and advanced technology, this bike is designed to help you enjoy long-distance rides with ease.\n\n## Features    \n\nLightweight and responsive    \nCelerity X5 comes with a full carbon fiber frame that is not only lightweight but also responsive, providing excellent handling and control.\n\nHydraulic disc brakes    \nThis bike is equipped with hydraulic disc brakes that provide superior stopping power in all weather conditions, ensuring your safety and confidence on the road.\n\nComfortable rides    \nThe 28mm wide tires and carbon seat post provide ample cushioning, ensuring a smooth and comfortable ride over long distances.\n\nSleek appearance    \nThe bike's internal cable routing enhances its sleek appearance while also protecting the cables from the elements, ensuring smooth shifting for longer periods.\n\n## Specifications    \n\nFrameset    \nFrame\tCelerity X5 Full Carbon Fiber Frame, Internal Cable Routing, Tapered Headtube, Press Fit Bottom Bracket, 12x142mm Thru-Axle    \nFork\tCelerity X5 Full Carbon Fiber Fork, Internal Brake Routing, 12x100mm Thru-Axle    \n\nWheels    \nWheelset\tAlexRims CXD7 Wheelset    \nTire\tSchwalbe Durano Plus 700x28mm    \nInner Tubes\tSchwalbe SV15 700x18-28mm    \nSkewers\tCelerity X5 Thru-Axle Skewers    \n\nDrivetrain    \nShifter\tShimano 105 R7025 Hydraulic Disc Shifters    \nFront Derailleur\tShimano 105 R7000    \nRear Derailleur\tShimano 105 R7000    \nCrankset\tShimano 105 R7000 50-34T    \nBottom Bracket\tShimano BB72-41B    \nCassette\tShimano 105 R7000 11-30T    \nChain\tShimano HG601 11-Speed Chain    \n\nComponents    \nSaddle\tSelle Royal Asphalt Saddle    \nSeatpost\tCelerity X5 Carbon Seatpost    \nHandlebar\tCelerity X5 Compact Handlebar    \nStem\tCelerity X5 Aluminum Stem    \nHeadset\tFSA Orbit IS-2    \n\nBrakes    \nBrakes\tShimano 105 R7025 Hydraulic Disc Brakes    \nRotors\tShimano SM-RT70 160mm Rotors    \n\nAccessories    \nPedals\tCelerity X5 Road Pedals    \n\nWeight    \nWeight\t8.2 kg / 18.1 lbs    \nWeight Limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 120 kg (265 lbs).\n\n## Sizing    \n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  49  |  155 - 162 cm 5'1\" - 5'4\" | 71 - 76 cm 28\" - 30\" |\n|  52  |  162 - 170 cm 5'4\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|  54  |  170 - 178 cm 5'7\" - 5'10\" | 77 - 83 cm 30\" - 32\" |\n|  56  |  178 - 185 cm 5'10\" - 6'1\" | 82 - 88 cm 32\" - 34\" |\n|  58  |  185 - 193 cm 6'1\" - 6'4\" | 86 - 92 cm 34\" - 36\" |\n|  61  |  193 - 200 cm 6'4\" - 6'7\" | 90 - 95 cm 35\" - 37\" |\n\n## Geometry    \n| Frame size number                     | 49 cm | 52 cm | 54 cm | 56 cm | 58 cm | 61 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 47.5  | 50.0  | 52.0  | 54.0  | 56.0  | 58.5  |\n| B — Seat tube angle                   | 75.0° | 74.5° | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length                  | 12.0  | 14.5  | 16.5  | 18.5  | 20.5  | 23.5  |\n| D — Head angle                        | 70.0° | 71.0° | 71.5° | 72.0° | 72.5° | 72.5° |\n| E — Effective top tube                | 52.5  | 53.5  | 54.5  | 56.0  | 57.5  | 59.5  |\n| G — Bottom bracket drop               | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length                  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  |\n| K — Wheelbase                         | 98.4  | 98.9  | 99.8  | 100.8 | 101.7 | 103.6 |\n| L — Standover                         | 72.0  | 74.0  | 76.0  | 78.0  | 80.0  | 82.0  |\n| M — Frame reach                       | 36.2  | 36.8  | 37.3  | 38.1  | 38.6  | 39.4  |\n| N — Frame stack                       | 52.0  | 54.3  | 56.2  | 58.1  | 59.8  | 62.4  |\n| Saddle rail height min                | 67.0  | 69.5  | 71.5  | 74.0  | 76.0  | 78.0  |\n| Saddle rail height max                | 75.0  | 77.5  | 79.5  | 82.0  | 84.0  | 86.0  |",
    "price": 399.99,
    "tags": [
      "bicycle",
      "city bike"
    ]
  },
  {
    "name": "Velocity V8",
    "shortDescription": "Velocity V8 is a high-performance road bike that is designed to deliver speed, agility, and control on the road. With its lightweight aluminum frame, carbon fiber fork, Shimano Tiagra groupset, and hydraulic disc brakes, this bike is perfect for experienced riders who are looking for a fast and responsive bike that can handle various road conditions.",
    "description": "## Overview\n\nIt's right for you if...    \nYou are an experienced rider who is looking for a high-performance road bike that is lightweight, agile, and responsive. You want a bike that can handle long-distance rides, steep climbs, and fast descents with ease. You also appreciate the latest technology and reliable components that make your riding experience more enjoyable.\n\nThe tech you get    \nVelocity V8 features a lightweight aluminum frame with a carbon fiber fork that ensures a comfortable ride without sacrificing stiffness and power transfer. It comes with a Shimano Tiagra groupset with 10-speed gearing for precise and efficient shifting. Hydraulic disc brakes offer superior stopping power in all weather conditions, while 28mm wide tires provide comfort and stability on various road surfaces. Internal cable routing enhances the bike's sleek appearance.\n\nThe final word    \nIf you are looking for a high-performance road bike that is lightweight, fast, and responsive, Velocity V8 is the perfect choice. With its lightweight aluminum frame, reliable components, and advanced technology, this bike is designed to help you enjoy fast and comfortable rides on the road.\n\n## Features    \n\nLightweight and responsive    \nVelocity V8 comes with a lightweight aluminum frame that is not only lightweight but also responsive, providing excellent handling and control.\n\nHydraulic disc brakes    \nThis bike is equipped with hydraulic disc brakes that provide superior stopping power in all weather conditions, ensuring your safety and confidence on the road.\n\nComfortable rides    \nThe 28mm wide tires and carbon fork provide ample cushioning, ensuring a smooth and comfortable ride over long distances.\n\nSleek appearance    \nThe bike's internal cable routing enhances its sleek appearance while also protecting the cables from the elements, ensuring smooth shifting for longer periods.\n\n## Specifications    \n\nFrameset    \nFrame\tVelocity V8 Aluminum Frame, Internal Cable Routing, Tapered Headtube, Press Fit Bottom Bracket, 12x142mm Thru-Axle    \nFork\tVelocity V8 Carbon Fiber Fork, Internal Brake Routing, 12x100mm Thru-Axle    \n\nWheels    \nWheelset\tAlexRims CXD7 Wheelset    \nTire\tSchwalbe Durano Plus 700x28mm    \nInner Tubes\tSchwalbe SV15 700x18-28mm    \nSkewers\tVelocity V8 Thru-Axle Skewers    \n\nDrivetrain    \nShifter\tShimano Tiagra Hydraulic Disc Shifters    \nFront Derailleur\tShimano Tiagra    \nRear Derailleur\tShimano Tiagra    \nCrankset\tShimano Tiagra 50-34T    \nBottom Bracket\tShimano BB-RS500-PB    \nCassette\tShimano Tiagra 11-32T    \nChain\tShimano HG54 10-Speed Chain    \n\nComponents    \nSaddle\tVelocity V8 Saddle    \nSeatpost\tVelocity V8 Aluminum Seatpost    \nHandlebar\tVelocity V8 Compact Handlebar    \nStem\tVelocity V8 Aluminum Stem    \nHeadset\tFSA Orbit IS-2    \n\nBrakes    \nBrakes\tShimano Tiagra Hydraulic Disc Brakes    \nRotors\tShimano SM-RT64 160mm Rotors    \n\nAccessories    \nPedals\tVelocity V8 Road Pedals    \n\nWeight    \nWeight\t9.4 kg / 20.7 lbs    \nWeight Limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 120 kg (265 lbs).\n\n## Sizing    \n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  49  |  155 - 162 cm 5'1\" - 5'4\" | 71 - 76 cm 28\" - 30\" |\n|  52  |  162 - 170 cm 5'4\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|  54  |  170 - 178 cm 5'7\" - 5'10\" | 77 - 83 cm 30\" - 32\" |\n|  56  |  178 - 185 cm 5'10\" - 6'1\" | 82 - 88 cm 32\" - 34\" |\n|  58  |  185 - 193 cm 6'1\" - 6'4\" | 86 - 92 cm 34\" - 36\" |\n|  61  |  193 - 200 cm 6'4\" - 6'7\" | 90 - 95 cm 35\" - 37\" |\n\n## Geometry    \n| Frame size number                     | 49 cm | 52 cm | 54 cm | 56 cm | 58 cm | 61 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 47.5  | 50.0  | 52.0  | 54.0  | 56.0  | 58.5  |\n| B — Seat tube angle                   | 75.0° | 74.5° | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length                  | 12.0  | 14.5  | 16.5  | 18.5  | 20.5  | 23.5  |\n| D — Head angle                        | 70.0° | 71.0° | 71.5° | 72.0° | 72.5° | 72.5° |\n| E — Effective top tube                | 52.5  | 53.5  | 54.5  | 56.0  | 57.5  | 59.5  |\n| G — Bottom bracket drop               | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length                  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  | 41.5  |\n| K — Wheelbase                         | 98.4  | 98.9  | 99.8  | 100.8 | 101.7 | 103.6 |\n| L — Standover                         | 72.0  | 74.0  | 76.0  | 78.0  | 80.0  | 82.0  |\n| M — Frame reach                       | 36.2  | 36.8  | 37.3  | 38.1  | 38.6  | 39.4  |\n| N — Frame stack                       | 52.0  | 54.3  | 56.2  | 58.1  | 59.8  | 62.4  |\n| Saddle rail height min                | 67.0  | 69.5  | 71.5  | 74.0  | 76.0  | 78.0  |\n| Saddle rail height max                | 75.0  | 77.5  | 79.5  | 82.0  | 84.0  | 86.0  |",
    "price": 1899.99,
    "tags": [
      "bicycle",
      "electric bike"
    ]
  },
  {
    "name": "VeloCore X9 eMTB",
    "shortDescription": "The VeloCore X9 eMTB is a light, agile and versatile electric mountain bike designed for adventure and performance. Its purpose-built frame and premium components offer an exhilarating ride experience on both technical terrain and smooth singletrack.",
    "description": "## Overview\nIt's right for you if...\nYou love exploring new trails and testing your limits on challenging terrain. You want an electric mountain bike that offers power when you need it, without sacrificing performance or agility. You're looking for a high-quality bike with top-notch components and a sleek design.\n\nThe tech you get\nA lightweight, full carbon frame with custom geometry, a 140mm RockShox Pike Ultimate fork with Charger 2.1 damper, and a Fox Float DPS Performance shock. A Shimano STEPS E8000 motor and 504Wh battery that provide up to 62 miles of range and 20 mph assistance. A Shimano XT 12-speed drivetrain, Shimano SLX brakes, and DT Swiss wheels.\n\nThe final word\nThe VeloCore X9 eMTB delivers power and agility in equal measure. It's a versatile and capable electric mountain bike that can handle any trail with ease. With premium components, a custom carbon frame, and a sleek design, this bike is built for adventure.\n\n## Features\nAgile and responsive\n\nThe VeloCore X9 eMTB is designed to be nimble and responsive on the trail. Its custom carbon frame offers a perfect balance of stiffness and compliance, while the suspension system provides smooth and stable performance on technical terrain.\n\nPowerful and efficient\n\nThe Shimano STEPS E8000 motor and 504Wh battery provide up to 62 miles of range and 20 mph assistance. The motor delivers smooth and powerful performance, while the battery offers reliable and consistent power for long rides.\n\nCustomizable ride experience\n\nThe VeloCore X9 eMTB comes with an intuitive and customizable Shimano STEPS display that allows you to adjust the level of assistance, monitor your speed and battery life, and customize your ride experience to suit your needs.\n\nPremium components\n\nThe VeloCore X9 eMTB is equipped with high-end components, including a Shimano XT 12-speed drivetrain, Shimano SLX brakes, and DT Swiss wheels. These components offer reliable and precise performance, allowing you to push your limits with confidence.\n\n## Specs\nFrameset\nFrame\tVeloCore carbon fiber frame, Boost, tapered head tube, internal cable routing, 140mm travel\nFork\tRockShox Pike Ultimate, Charger 2.1 damper, DebonAir spring, 15x110mm Boost Maxle Ultimate, 46mm offset, 140mm travel\nShock\tFox Float DPS Performance, EVOL, 3-position adjust, Kashima Coat, 210x50mm\n\nWheels\nWheel front\tDT Swiss XM1700 Spline, 30mm internal width, 15x110mm Boost axle\nWheel rear\tDT Swiss XM1700 Spline, 30mm internal width, Shimano Microspline driver, 12x148mm Boost axle\nTire front\tMaxxis Minion DHF, 29x2.5\", EXO+ casing, tubeless ready\nTire rear\tMaxxis Minion DHR II, 29x2.4\", EXO+ casing, tubeless ready\n\nDrivetrain\nShifter\tShimano XT M8100, 12-speed\nRear derailleur\tShimano XT M8100, Shadow Plus, long cage, 51T max cog\nCrankset\tShimano STEPS E8000, 165mm length, 34T chainring\nCassette\tShimano XT M8100, 10-51T, 12-speed\nChain\tShimano CN-M8100, 12-speed\nPedals\tNot included\n\nComponents\nSaddle\tBontrager Arvada, hollow chromoly rails\nSeatpost\tDrop Line, internal routing, 31.6mm (15.5: 100mm, 17.5 & 18.5: 125mm, 19.5 & 21.5: 150mm)\nHandlebar\tBontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\nStem\tBontrager Line Pro, 35mm, Knock Block, 0 degree, 50mm length\nGrips\tBontrager XR Trail Elite, alloy lock-on\nHeadset\tIntegrated, sealed cartridge bearing, 1-1/8\" top, 1.5\" bottom\nBrakeset\tShimano SLX M7120, 4-piston hydraulic disc\n\nAccessories\nBattery\tShimano STEPS BT-E8010, 504Wh\nCharger\tShimano STEPS EC-E8004, 4A\nController\tShimano STEPS E8000 display\nBike weight\tM - 22.5 kg / 49.6 lbs (with tubes)\n\n## Sizing & fit\n\n| Size |       Rider Height       |\n|:----:|:------------------------:|\n|   S  | 162 - 170 cm 5'4\" - 5'7\" |\n|   M  | 170 - 178 cm 5'7\" - 5'10\"|\n|   L  | 178 - 186 cm 5'10\" - 6'1\"|\n|  XL  | 186 - 196 cm 6'1\" - 6'5\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\n| Frame size         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| A — Seat tube             | 40.6  | 43.2  | 47.0  | 51.0  |\n| B — Seat tube angle       | 75.0° | 75.0° | 75.0° | 75.0° |\n| C — Head tube length      | 9.6   | 10.6  | 11.6  | 12.6  |\n| D — Head angle            | 66.5° | 66.5° | 66.5° | 66.5° |\n| E — Effective top tube    | 60.4  | 62.6  | 64.8  | 66.9  |\n| F — Bottom bracket height | 33.2  | 33.2  | 33.2  | 33.2  |\n| G — Bottom bracket drop   | 3.0   | 3.0   | 3.0   | 3.0   |\n| H — Chainstay length      | 45.5  | 45.5  | 45.5  | 45.5  |\n| I — Offset                | 4.6   | 4.6   | 4.6   | 4.6   |\n| J — Trail                 | 11.9  | 11.9  | 11.9  | 11.9  |\n| K — Wheelbase             | 117.0 | 119.3 | 121.6 | 123.9 |\n| L — Standover             | 75.9  | 75.9  | 78.6  | 78.6  |\n| M — Frame reach           | 43.6  | 45.6  | 47.6  | 49.6  |\n| N — Frame stack           | 60.5  | 61.5  | 62.4  | 63.4  |",
    "price": 1299.99,
    "tags": [
      "bicycle",
      "touring bike"
    ]
  },
  {
    "name": "Zephyr 8.8 GX Eagle AXS Gen 3",
    "shortDescription": "Zephyr 8.8 GX Eagle AXS is a light and nimble full-suspension mountain bike. It's designed to handle technical terrain with ease and has a smooth and efficient ride feel. The sleek and powerful Bosch Performance Line CX motor and removable Powertube battery provide a boost to your pedaling and give you long-lasting riding time. The bike also features high-end components and advanced technology for an ultimate mountain biking experience.",
    "description": "## Overview\nIt's right for you if...\nYou're an avid mountain biker looking for a high-performance e-MTB that can tackle challenging trails. You want a bike with a powerful motor, efficient suspension, and advanced technology to enhance your riding experience. You also need a bike that's reliable and durable for long-lasting use.\n\nThe tech you get\nA lightweight, full carbon frame with 150mm of rear travel and a 160mm RockShox Pike Ultimate fork with Charger 2.1 RCT3 damper, remote lockout, and DebonAir spring. A Bosch Performance Line CX motor and removable Powertube 625Wh battery that can assist up to 20mph when it's on and gives zero drag when it's off, plus an easy-to-use handlebar-mounted Bosch Purion controller. A SRAM GX Eagle AXS wireless electronic drivetrain, a RockShox Reverb Stealth dropper, and DT Swiss HX1501 Spline One wheels.\n\nThe final word\nZephyr 8.8 GX Eagle AXS is a high-performance e-MTB that's designed to handle technical terrain with ease. With a powerful Bosch motor and long-lasting battery, you can conquer challenging climbs and enjoy long rides. The bike also features high-end components and advanced technology for an ultimate mountain biking experience.\n\n## Features\nPowerful motor\n\nThe Bosch Performance Line CX motor provides a boost to your pedaling and can assist up to 20mph. It has four power modes and a walk-assist function for easy navigation on steep climbs. The motor is also reliable and durable for long-lasting use.\n\nEfficient suspension\n\nZephyr 8.8 has a 150mm of rear travel and a 160mm RockShox Pike Ultimate fork with Charger 2.1 RCT3 damper, remote lockout, and DebonAir spring. The suspension is efficient and responsive, allowing you to handle technical terrain with ease.\n\nRemovable battery\n\nThe Powertube 625Wh battery is removable for easy charging and storage. It provides long-lasting riding time and can be replaced with a spare battery for even longer rides. The battery is also durable and weather-resistant for all-season riding.\n\nAdvanced technology\n\nZephyr 8.8 is equipped with advanced technology, including a Bosch Purion controller for easy motor control, a SRAM GX Eagle AXS wireless electronic drivetrain for precise shifting, and a RockShox Reverb Stealth dropper for adjustable saddle height. The bike also has DT Swiss HX1501 Spline One wheels for reliable performance on any terrain.\n\nCarbon frame\n\nThe full carbon frame is lightweight and durable, providing a smooth and efficient ride. It's also designed with a tapered head tube, internal cable routing, and Boost148 spacing for enhanced stiffness and responsiveness.\n\n## Specs\nFrameset\nFrame\tCarbon main frame & stays, tapered head tube, internal routing, Boost148, 150mm travel\nFork\tRockShox Pike Ultimate, Charger 2.1 RCT3 damper, DebonAir spring, remote lockout, tapered steerer, Boost110, 15mm Maxle Stealth, 160mm travel\nShock\tRockShox Deluxe RT3, DebonAir spring, 205mm x 57.5mm\nMax compatible fork travel\t170mm\n\nWheels\nWheel front\tDT Swiss HX1501 Spline One, Centerlock, 30mm inner width, 110x15mm Boost\nWheel rear\tDT Swiss HX1501 Spline One, Centerlock, 30mm inner width, SRAM XD driver, 148x12mm Boost\nTire\tBontrager XR4 Team Issue, Tubeless Ready, Inner Strength sidewall, aramid bead, 120tpi, 29x2.40''\nMax tire size\t29x2.60\"\n\nDrivetrain\nShifter\tSRAM GX Eagle AXS, wireless, 12 speed\nRear derailleur\tSRAM GX Eagle AXS\nCrank\tBosch Gen 4, 32T\nChainring\tSRAM X-Sync 2, 32T, direct-mount\nCassette\tSRAM PG-1275 Eagle, 10-52, 12 speed\nChain\tSRAM GX Eagle, 12 speed\n\nComponents\nSaddle\tBontrager Arvada, hollow titanium rails, 138mm width\nSeatpost\tRockShox Reverb Stealth, 31.6mm, internal routing, 150mm (S), 170mm (M/L), 200mm (XL)\nHandlebar\tBontrager Line Pro, ADV Carbon, 35mm, 27.5mm rise, 780mm width\nGrips\tBontrager XR Trail Elite, alloy lock-on\nStem\tBontrager Line Pro, Knock Block, 35mm, 0 degree, 50mm length\nHeadset\tIntegrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\nBrake\tSRAM Code RSC hydraulic disc, 200mm (front), 180mm (rear)\nBrake rotor\tSRAM CenterLine, centerlock, round edge, 200mm (front), 180mm (rear)\n\nAccessories\nE-bike system\tBosch Performance Line CX\nBattery\tBosch Powertube 625Wh\nCharger\tBosch 4A compact charger\nController\tBosch Purion\nTool\tBontrager multi-tool, integrated storage bag\n\nWeight\nWeight\tM - 24.08 kg / 53.07 lbs (with TLR sealant, no tubes)\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n\n## Sizing & fit\n\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 153 - 162 cm 5'0\" - 5'4\" | 67 - 74 cm 26\" - 29\" |\n|   M  | 161 - 172 cm 5'3\" - 5'8\" | 74 - 79 cm 29\" - 31\" |\n|   L  | 171 - 180 cm 5'7\" - 5'11\" | 79 - 84 cm 31\" - 33\" |\n|  XL  | 179 - 188 cm 5'10\" - 6'2\" | 84 - 89 cm 33\" - 35\" |\n\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 15.5  | 17.5  | 19.5  | 21.5  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.4  | 41.9  | 44.5  | 47.6  |\n| B — Seat tube angle       | 76.1° | 76.1° | 76.1° | 76.1° |\n| C — Head tube length      | 9.6   | 10.5  | 11.5  | 12.5  |\n| D — Head angle            | 65.5° | 65.5° | 65.5° | 65.5° |\n| E — Effective top tube    | 58.6  | 61.3  | 64.0  | 66.7  |\n| F — Bottom bracket height | 34.0  | 34.0  | 34.0  | 34.0  |\n| G — Bottom bracket drop   | 1.0   | 1.0   | 1.0   | 1.0   |\n| H — Chainstay length      | 45.0  | 45.0  | 45.0  | 45.0  |\n| I — Offset                | 4.6   | 4.6   | 4.6   | 4.6   |\n| J — Trail                 | 10.5  | 10.5  | 10.5  | 10.5  |\n| K — Wheelbase             | 119.5 | 122.3 | 125.0 | 127.8 |\n| L — Standover             | 72.7  | 74.7  | 77.6  | 81.0  |\n|",
    "price": 1499.99,
    "tags": [
      "bicycle",
      "electric bike",
      "city bike"
    ]
  },
  {
    "name": "Velo 99 XR1 AXS",
    "shortDescription": "Velo 99 XR1 AXS is a next-generation bike designed for fast-paced adventure seekers and speed enthusiasts. Built for high-performance racing, the bike boasts state-of-the-art technology and premium components. It is the ultimate bike for riders who want to push their limits and get their adrenaline pumping.",
    "description": "## Overview\nIt's right for you if...\nYou are a passionate cyclist looking for a bike that can keep up with your speed, agility, and endurance. You are an adventurer who loves to explore new terrains and challenge yourself on the toughest courses. You want a bike that is lightweight, durable, and packed with the latest technology.\n\nThe tech you get\nA lightweight, full carbon frame with advanced aerodynamics and integrated cable routing for a clean look. A high-performance SRAM XX1 Eagle AXS wireless electronic drivetrain, featuring a 12-speed cassette and a 32T chainring. A RockShox SID Ultimate fork with a remote lockout, 120mm travel, and Charger Race Day damper. A high-end SRAM G2 Ultimate hydraulic disc brake with carbon levers. A FOX Transfer SL dropper post for quick and easy height adjustments. DT Swiss XRC 1501 carbon wheels for superior speed and handling.\n\nThe final word\nVelo 99 XR1 AXS is a premium racing bike that can help you achieve your goals and reach new heights. It is designed for speed, agility, and performance, and it is packed with the latest technology and premium components. If you are a serious cyclist who wants the best, this is the bike for you.\n\n## Features\nAerodynamic design\n\nThe Velo 99 XR1 AXS features a state-of-the-art frame design that reduces drag and improves speed. It has an aerodynamic seatpost, integrated cable routing, and a sleek, streamlined look that sets it apart from other bikes.\n\nWireless electronic drivetrain\n\nThe SRAM XX1 Eagle AXS drivetrain features a wireless electronic system that provides precise, instant shifting and unmatched efficiency. It eliminates the need for cables and makes the bike lighter and faster.\n\nHigh-performance suspension\n\nThe RockShox SID Ultimate fork and Charger Race Day damper provide 120mm of smooth, responsive suspension that can handle any terrain. The fork also has a remote lockout for quick adjustments on the fly.\n\nSuperior braking power\n\nThe SRAM G2 Ultimate hydraulic disc brake system delivers unmatched stopping power and control. It has carbon levers for a lightweight, ergonomic design and precision control.\n\nCarbon wheels\n\nThe DT Swiss XRC 1501 carbon wheels are ultra-lightweight, yet incredibly strong and durable. They provide superior speed and handling, making the bike more agile and responsive.\n\n## Specs\nFrameset\nFrame\tFull carbon frame, integrated cable routing, aerodynamic design, Boost148\nFork\tRockShox SID Ultimate, Charger Race Day damper, remote lockout, tapered steerer, Boost110, 15mm Maxle Stealth, 120mm travel\n\nWheels\nWheel front\tDT Swiss XRC 1501 carbon wheel, Boost110, 15mm thru axle\nWheel rear\tDT Swiss XRC 1501 carbon wheel, SRAM XD driver, Boost148, 12mm thru axle\nTire\tSchwalbe Racing Ray, Performance Line, Addix, 29x2.25\"\nTire part\tSchwalbe Doc Blue Professional, 500ml\nMax tire size\t29x2.3\"\n\nDrivetrain\nShifter\tSRAM Eagle AXS, wireless, 12-speed\nRear derailleur\tSRAM XX1 Eagle AXS\nCrank\tSRAM XX1 Eagle, 32T, carbon\nChainring\tSRAM X-SYNC, 32T, alloy\nCassette\tSRAM Eagle XG-1299, 10-52, 12-speed\nChain\tSRAM XX1 Eagle, 12-speed\nMax chainring size\t1x: 32T\n\nComponents\nSaddle\tBontrager Montrose Elite, carbon rails, 138mm width\nSeatpost\tFOX Transfer SL, 125mm travel, internal routing, 31.6mm\nHandlebar\tBontrager Kovee Pro, ADV Carbon, 35mm, 5mm rise, 720mm width\nGrips\tBontrager XR Endurance Elite\nStem\tBontrager Kovee Pro, 35mm, Blendr compatible, 7 degree, 60mm length\nHeadset\tIntegrated, cartridge bearing, 1-1/8\" top, 1.5\" bottom\nBrake\tSRAM G2 Ultimate hydraulic disc, carbon levers, 180mm rotors\n\nAccessories\nBike computer\tBontrager Trip 300\nTool\tBontrager Flatline Pro pedal wrench, T25 Torx\n\n\n## Sizing & fit\n\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 158 - 168 cm 5'2\" - 5'6\" | 74 - 78 cm 29\" - 31\" |\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 78 - 82 cm 31\" - 32\" |\n|   L  | 173 - 183 cm 5'8\" - 6'0\" | 82 - 86 cm 32\" - 34\" |\n|  XL  | 180 - 193 cm 5'11\" - 6'4\" | 86 - 90 cm 34\" - 35\" |\n\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 15.5  | 17.5  | 19.5  | 21.5  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.9  | 43.0  | 47.0  | 51.0  |\n| B — Seat tube angle       | 74.5° | 74.5° | 74.5° | 74.5° |\n| C — Head tube length      | 9.0   | 10.0  | 11.0  | 12.0  |\n| D — Head angle            | 68.0° | 68.0° | 68.0° | 68.0° |\n| E — Effective top tube    | 57.8  | 59.7  | 61.6  | 63.6  |\n| F — Bottom bracket height | 33.0  | 33.0  | 33.0  | 33.0  |\n| G — Bottom bracket drop   | 5.0   | 5.0   | 5.0   | 5.0   |\n| H — Chainstay length      | 43.0  | 43.0  | 43.0  | 43.0  |\n| I — Offset                | 4.2   | 4.2   | 4.2   | 4.2   |\n| J — Trail                 | 9.7   | 9.7   | 9.7   | 9.7   |\n| K — Wheelbase             | 112.5 | 114.5 | 116.5 | 118.6 |\n| L — Standover             | 75.9  | 77.8  | 81.5  | 84.2  |\n| M — Frame reach           | 41.6  | 43.4  | 45.2  | 47.1  |\n| N — Frame stack           | 58.2  | 58.9  | 59.3  | 59.9  |",
    "price": 1099.99,
    "tags": [
      "bicycle",
      "mountain bike"
    ]
  },
  {
    "name": "AURORA 11S E-MTB",
    "shortDescription": "The AURORA 11S is a powerful and stylish electric mountain bike designed to take you on thrilling off-road adventures. With its sturdy frame and premium components, this bike is built to handle any terrain. It features a high-performance motor, long-lasting battery, and advanced suspension system that guarantee a smooth and comfortable ride.",
    "description": "## Overview\nIt's right for you if...\nYou want a top-of-the-line e-MTB that is both powerful and stylish. You also want a bike that can handle any terrain, from steep climbs to rocky descents. With its advanced features and premium components, the AURORA 11S is designed for serious off-road riders who demand the best.\n\nThe tech you get\nA sturdy aluminum frame with advanced suspension system that provides 120mm of travel. A 750W brushless motor that delivers up to 28mph, and a 48V/14Ah lithium-ion battery that provides up to 60 miles of range on a single charge. An advanced 11-speed Shimano drivetrain with hydraulic disc brakes for precise shifting and reliable stopping power. \n\nThe final word\nThe AURORA 11S is a top-of-the-line e-MTB that delivers exceptional performance and style. Whether you're tackling steep climbs or hitting rocky descents, this bike is built to handle any terrain with ease. With its advanced features and premium components, the AURORA 11S is the perfect choice for serious off-road riders who demand the best.\n\n## Features\nPowerful and efficient\n\nThe AURORA 11S is equipped with a high-performance 750W brushless motor that delivers up to 28mph. The motor is powered by a long-lasting 48V/14Ah lithium-ion battery that provides up to 60 miles of range on a single charge.\n\nAdvanced suspension system\n\nThe bike's advanced suspension system provides 120mm of travel, ensuring a smooth and comfortable ride on any terrain. The front suspension is a Suntour XCR32 Air fork, while the rear suspension is a KS-281 hydraulic shock absorber.\n\nPremium components\n\nThe AURORA 11S features an advanced 11-speed Shimano drivetrain with hydraulic disc brakes. The bike is also equipped with a Tektro HD-E725 hydraulic disc brake system that provides reliable stopping power.\n\nSleek and stylish design\n\nWith its sleek and stylish design, the AURORA 11S is sure to turn heads on the trail. The bike's sturdy aluminum frame is available in a range of colors, including black, blue, and red.\n\n## Specs\nFrameset\nFrame Material: Aluminum\nFrame Size: S, M, L\nFork: Suntour XCR32 Air, 120mm Travel\nShock Absorber: KS-281 Hydraulic Shock Absorber\n\nWheels\nWheel Size: 27.5 inches\nTires: Kenda K1151 Nevegal, 27.5x2.35\nRims: Alloy Double Wall\nSpokes: 32H, Stainless Steel\n\nDrivetrain\nShifters: Shimano SL-M7000\nRear Derailleur: Shimano RD-M8000\nCrankset: Prowheel 42T, Alloy Crank Arm\nCassette: Shimano CS-M7000, 11-42T\nChain: KMC X11EPT\n\nBrakes\nBrake System: Tektro HD-E725 Hydraulic Disc Brake\nBrake Rotors: 180mm Front, 160mm Rear\n\nE-bike system\nMotor: 750W Brushless\nBattery: 48V/14Ah Lithium-Ion\nCharger: 48V/3A Smart Charger\nController: Intelligent Sinusoidal Wave\n\nWeight\nWeight: 59.5 lbs\n\n## Sizing & fit\n| Size | Rider Height | Standover Height |\n|------|-------------|-----------------|\n| S    | 5'2\"-5'6\"   | 28.5\"           |\n| M    | 5'7\"-6'0\"   | 29.5\"           |\n| L    | 6'0\"-6'4\"   | 30.5\"           |\n\n## Geometry\nAll measurements provided in cm.\nSizing table\n| Frame size letter | S   | M   | L   |\n|-------------------|-----|-----|-----|\n| Wheel Size        | 27.5\"| 27.5\"| 27.5\"|\n| Seat tube length  | 44.5| 48.5| 52.5|\n| Head tube angle   | 68° | 68° | 68° |\n| Seat tube angle   | 74.5°| 74.5°| 74.5°|\n| Effective top tube | 57.5| 59.5| 61.5|\n| Head tube length  | 12.0| 12.0| 13.0|\n| Chainstay length  | 45.5| 45.5| 45.5|\n| Bottom bracket height | 30.0| 30.0| 30.0|\n| Wheelbase         | 115.0|116.5|118.5|",
    "price": 1999.99,
    "tags": [
      "bicycle",
      "road bike"
    ]
  },
  {
    "name": "VeloTech V9.5 AXS Gen 3",
    "shortDescription": "VeloTech V9.5 AXS is a sleek and fast carbon bike that combines high-end tech with a comfortable ride. It's designed to provide the ultimate experience for the most serious riders. The bike comes with a lightweight and powerful motor that can be activated when needed, and you get a spec filled with premium parts.",
    "description": "## Overview\nIt's right for you if...\nYou want a bike that is fast, efficient, and delivers an adrenaline-filled experience. You are looking for a bike that is built with cutting-edge technology, and you want a ride that is both comfortable and exciting.\n\nThe tech you get\nA lightweight and durable full carbon frame with a fork that has 100mm of travel. The bike comes with a powerful motor that can deliver up to 20 mph of assistance. The drivetrain is a wireless electronic system that is precise and reliable. The bike is also equipped with hydraulic disc brakes, tubeless-ready wheels, and comfortable grips.\n\nThe final word\nThe VeloTech V9.5 AXS is a high-end bike that delivers an incredible experience for serious riders. It combines the latest technology with a comfortable ride, making it perfect for long rides, tough climbs, and fast descents.\n\n## Features\nFast and efficient\nThe VeloTech V9.5 AXS comes with a powerful motor that can provide up to 20 mph of assistance. The motor is lightweight and efficient, providing a boost when you need it without adding bulk. The bike's battery is removable, allowing you to ride without assistance when you don't need it.\n\nSmart software for the trail\nThe VeloTech V9.5 AXS is equipped with intelligent software that delivers a smooth and responsive ride. The software allows the motor to respond immediately as you start to pedal, delivering more power over a wider cadence range. You can also customize your user settings to suit your preferences.\n\nComfortable ride\nThe VeloTech V9.5 AXS is designed to provide a comfortable ride, even on long rides. The bike's fork has 100mm of travel, providing ample cushioning for rough terrain. The bike's grips are also designed to provide a comfortable and secure grip, even on the most challenging rides.\n\n## Specs\nFrameset\nFrame\tCarbon fiber frame with internal cable routing and Boost148\nFork\t100mm of travel with remote lockout\nShock\tN/A\n\nWheels\nWheel front\tCarbon fiber tubeless-ready wheel\nWheel rear\tCarbon fiber tubeless-ready wheel\nSkewer rear\t12mm thru-axle\nTire\tTubeless-ready tire\nTire part\tTubeless sealant\n\nDrivetrain\nShifter\tWireless electronic shifter\nRear derailleur\tWireless electronic derailleur\nCrank\tCarbon fiber crankset with chainring\nCrank arm\tCarbon fiber crank arm\nChainring\tAlloy chainring\nCassette\t12-speed cassette\nChain\t12-speed chain\n\nComponents\nSaddle\tCarbon fiber saddle\nSeatpost\tCarbon fiber seatpost\nHandlebar\tCarbon fiber handlebar\nGrips\tComfortable and secure grips\nStem\tCarbon fiber stem\nHeadset\tCarbon fiber headset\nBrake\tHydraulic disc brakes\nBrake rotor\tDisc brake rotor\n\nAccessories\nE-bike system\tPowerful motor with removable battery\nBattery\tLithium-ion battery\nCharger\tFast charging adapter\nController\tHandlebar-mounted controller\nTool\tBasic toolkit\n\nWeight\nWeight\tM - 17.5 kg / 38.5 lbs (with tubeless sealant)\n\nWeight limit\nThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing & fit\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   S  | 160 - 170 cm 5'3\" - 5'7\" | 74 - 79 cm 29\" - 31\" |\n|   M  | 170 - 180 cm 5'7\" - 5'11\" | 79 - 84 cm 31\" - 33\" |\n|   L  | 180 - 190 cm 5'11\" - 6'3\" | 84 - 89 cm 33\" - 35\" |\n|  XL  | 190 - 200 cm 6'3\" - 6'7\" | 89 - 94 cm 35\" - 37\" |\n\n## Geometry\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Actual frame size         | 50.0  | 53.3  | 55.6  | 58.8  |\n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |\n| A — Seat tube             | 39.4  | 43.2  | 48.3  | 53.3  |\n| B — Seat tube angle       | 72.3° | 72.6° | 72.8° | 72.8° |\n| C — Head tube length      | 9.0   | 10.0  | 10.5  | 11.0  |\n| D — Head angle            | 67.5° | 67.5° | 67.5° | 67.5° |\n| E — Effective top tube    | 58.0  | 61.7  | 64.8  | 67.0  |\n| F — Bottom bracket height | 32.3  | 32.3  | 32.3  | 32.3  |\n| G — Bottom bracket drop   | 5.0   | 5.0   | 5.0   | 5.0   |\n| H — Chainstay length      | 44.7  | 44.7  | 44.7  | 44.7  |\n| I — Offset                | 4.2   | 4.2   | 4.2   | 4.2   |\n| J — Trail                 | 10.9  | 10.9  | 10.9  | 10.9  |\n| K — Wheelbase             | 112.6 | 116.5 | 119.7 | 121.9 |\n| L — Standover             | 76.8  | 76.8  | 76.8  | 76.8  |\n| M — Frame reach           | 40.5  | 44.0  | 47.0  | 49.0  |\n| N — Frame stack           | 60.9  | 61.8  | 62.2  | 62.7  |",
    "price": 1699.99,
    "tags": [
      "bicycle",
      "electric bike",
      "city bike"
    ]
  },
  {
    "name": "Axiom D8 E-Mountain Bike",
    "shortDescription": "The Axiom D8 is an electrifying mountain bike that is built for adventure. It boasts a light aluminum frame, a powerful motor and the latest tech to tackle the toughest of terrains. The D8 provides assistance without adding bulk to the bike, giving you the flexibility to ride like a traditional mountain bike or have an extra push when you need it.",
    "description": "## Overview  \nIt's right for you if...  \nYou're looking for an electric mountain bike that can handle a wide variety of terrain, from flowing singletrack to technical descents. You also want a bike that offers a powerful motor that provides assistance without adding bulk to the bike. The D8 is designed to take you anywhere, quickly and comfortably.\n\nThe tech you get  \nA lightweight aluminum frame with 140mm of travel, a Suntour fork with hydraulic lockout, and a reliable and powerful Bafang M400 mid-motor that provides a boost up to 20 mph. The bike features a Shimano Deore drivetrain, hydraulic disc brakes, and a dropper seat post. With the latest tech on-board, the D8 is designed to take you to new heights.\n\nThe final word  \nThe Axiom D8 is an outstanding electric mountain bike that is designed for adventure. It's built with the latest tech and provides the flexibility to ride like a traditional mountain bike or have an extra push when you need it. Whether you're a beginner or an experienced rider, the D8 is the perfect companion for your next adventure.\n\n## Features  \nBuilt for Adventure  \n\nThe D8 features a lightweight aluminum frame that is built to withstand rugged terrain. It comes equipped with 140mm of travel and a Suntour fork that can handle even the toughest of trails. With this bike, you're ready to take on anything the mountain can throw at you.\n\nPowerful Motor  \n\nThe Bafang M400 mid-motor provides reliable and powerful assistance without adding bulk to the bike. You can quickly and easily switch between the different assistance levels to find the perfect balance between range and power.\n\nShimano Deore Drivetrain  \n\nThe Shimano Deore drivetrain is reliable and offers smooth shifting on any terrain. You can easily adjust the gears to match your riding style and maximize your performance on the mountain.\n\nDropper Seat Post  \n\nThe dropper seat post allows you to easily adjust your seat height on the fly, so you can maintain the perfect position for any terrain. With the flick of a switch, you can quickly and easily lower or raise your seat to match the terrain.\n\nHydraulic Disc Brakes  \n\nThe D8 features powerful hydraulic disc brakes that offer reliable stopping power in any weather condition. You can ride with confidence knowing that you have the brakes to stop on a dime.\n\n## Specs  \nFrameset  \nFrame\tAluminum frame with 140mm of travel  \nFork\tSuntour fork with hydraulic lockout, 140mm of travel  \nShock\tN/A  \nMax compatible fork travel\t140mm  \n  \nWheels  \nWheel front\tAlloy wheel  \nWheel rear\tAlloy wheel  \nSkewer rear\tThru axle  \nTire\t29\" x 2.35\"  \nTire part\tN/A  \nMax tire size\t29\" x 2.6\"  \n  \nDrivetrain  \nShifter\tShimano Deore  \nRear derailleur\tShimano Deore  \nCrank\tBafang M400  \nCrank arm\tN/A  \nChainring\tN/A  \nCassette\tShimano Deore  \nChain\tShimano Deore  \nMax chainring size\tN/A  \n  \nComponents  \nSaddle\tAxiom D8 saddle  \nSeatpost\tDropper seat post  \nHandlebar\tAxiom D8 handlebar  \nGrips\tAxiom D8 grips  \nStem\tAxiom D8 stem  \nHeadset\tAxiom D8 headset  \nBrake\tHydraulic disc brakes  \nBrake rotor\t180mm  \n\nAccessories  \nE-bike system\tBafang M400 mid-motor  \nBattery\tLithium-ion battery, 500Wh  \nCharger\tLithium-ion charger  \nController\tBafang M400 controller  \nTool\tN/A  \n  \nWeight  \nWeight\tM - 22 kg / 48.5 lbs  \nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 136 kg (300 lbs).  \n  \n  \n## Sizing & fit  \n  \n| Size |       Rider Height       |        Inseam        |  \n|:----:|:------------------------:|:--------------------:|  \n|   S  | 152 - 165 cm 5'0\" - 5'5\" | 70 - 76 cm 27\" - 30\" |  \n|   M  | 165 - 178 cm 5'5\" - 5'10\" | 76 - 81 cm 30\" - 32\" |  \n|   L  | 178 - 185 cm 5'10\" - 6'1\" | 81 - 86 cm 32\" - 34\" |  \n|  XL  | 185 - 193 cm 6'1\" - 6'4\" | 86 - 91 cm 34\" - 36\" |  \n  \n  \n## Geometry  \n  \nAll measurements provided in cm unless otherwise noted.  \nSizing table  \n| Frame size letter         | S     | M     | L     | XL    |  \n|---------------------------|-------|-------|-------|-------|  \n| Actual frame size         | 41.9  | 46.5  | 50.8  | 55.9  |  \n| Wheel size                | 29\"   | 29\"   | 29\"   | 29\"   |  \n| A — Seat tube             | 42.0  | 46.5  | 51.0  | 56.0  |  \n| B — Seat tube angle       | 74.0° | 74.0° | 74.0° | 74.0° |  \n| C — Head tube length      | 11.0  | 12.0  | 13.0  | 15.0  |  \n| D — Head angle            | 68.0° | 68.0° | 68.0° | 68.0° |  \n| E — Effective top tube    | 57.0  | 60.0  | 62.0  | 65.0  |  \n| F — Bottom bracket height | 33.0  | 33.0  | 33.0  | 33.0  |  \n| G — Bottom bracket drop   | 3.0   | 3.0   | 3.0   | 3.0   |  \n| H — Chainstay length      | 46.0  | 46.0  | 46.0  | 46.0  |  \n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |  \n| J — Trail                 | 10.9  | 10.9  | 10.9  | 10.9  |  \n| K — Wheelbase             | 113.0 | 116.0 | 117.5 | 120.5 |  \n| L — Standover             | 73.5  | 75.5  | 76.5  | 79.5  |  \n| M — Frame reach           | 41.0  | 43.5  | 45.0  | 47.5  |  \n| N — Frame stack           | 60.5  | 61.5  | 62.5  | 64.5  |",
    "price": 1399.99,
    "tags": [
      "bicycle",
      "electric bike",
      "mountain bike"
    ]
  },
  {
    "name": "Velocity X1",
    "shortDescription": "Velocity X1 is a high-performance road bike designed for speed enthusiasts. It features a lightweight yet durable frame, aerodynamic design, and top-quality components, making it the perfect choice for those who want to take their cycling experience to the next level.",
    "description": "## Overview\nIt's right for you if...\nYou're an experienced cyclist looking for a bike that can keep up with your need for speed. You want a bike that's lightweight, aerodynamic, and built to perform, whether you're training for a race or just pushing yourself to go faster.\n\nThe tech you get\nA lightweight aluminum frame with a carbon fork, Shimano Ultegra groupset with a wide range of gearing, hydraulic disc brakes, aerodynamic carbon wheels, and a vibration-absorbing handlebar with ergonomic grips.\n\nThe final word\nVelocity X1 is the ultimate road bike for speed enthusiasts. Its lightweight frame, aerodynamic design, and top-quality components make it the perfect choice for those who want to take their cycling experience to the next level.\n\n\n## Features\n\nAerodynamic design\nVelocity X1 is built with an aerodynamic design to help you go faster with less effort. It features a sleek profile, hidden cables, and a carbon fork that cuts through the wind, reducing drag and increasing speed.\n\nHydraulic disc brakes\nVelocity X1 comes equipped with hydraulic disc brakes, providing excellent stopping power in all weather conditions. They're also low maintenance, with minimal adjustments needed over time.\n\nCarbon wheels\nThe Velocity X1's aerodynamic carbon wheels provide excellent speed and responsiveness, helping you achieve your fastest times yet. They're also lightweight, reducing overall bike weight and making acceleration and handling even easier.\n\nShimano Ultegra groupset\nThe Shimano Ultegra groupset provides smooth shifting and reliable performance, ensuring you get the most out of every ride. With a wide range of gearing options, it's ideal for tackling any terrain, from steep climbs to fast descents.\n\n\n## Specifications\nFrameset\nFrame with Fork\tAluminium frame, internal cable routing, 135x9mm QR\nFork\tCarbon, hidden cable routing, 100x9mm QR\n\nWheels\nWheel front\tCarbon, 30mm deep rim, 23mm width, 100x9mm QR\nWheel rear\tCarbon, 30mm deep rim, 23mm width, 135x9mm QR\nSkewer front\t100x9mm QR\nSkewer rear\t135x9mm QR\nTire\tContinental Grand Prix 5000, 700x25mm, folding bead\nMax tire size\t700x28mm without fenders\n\nDrivetrain\nShifter\tShimano Ultegra R8020, 11 speed\nRear derailleur\tShimano Ultegra R8000, 11 speed\n*Crank\tSize: S, M\nShimano Ultegra R8000, 50/34T, 170mm length\nSize: L, XL\nShimano Ultegra R8000, 50/34T, 175mm length\nBottom bracket\tShimano BB-RS500-PB, PressFit\nCassette\tShimano Ultegra R8000, 11-30T, 11 speed\nChain\tShimano Ultegra HG701, 11 speed\nPedal\tNot included\nMax chainring size\t50/34T\n\nComponents\nSaddle\tBontrager Montrose Comp, steel rails, 138mm width\nSeatpost\tBontrager Comp, 6061 alloy, 27.2mm, 8mm offset, 330mm length\n*Handlebar\tSize: S, M, L\nBontrager Elite Aero VR-CF, alloy, 31.8mm, 93mm reach, 123mm drop, 400mm width\nSize: XL\nBontrager Elite Aero VR-CF, alloy, 31.8mm, 93mm reach, 123mm drop, 420mm width\nGrips\tBontrager Supertack Perf tape\n*Stem\tSize: S, M, L\nBontrager Elite Blendr, 31.8mm clamp, 7 degree, 90mm length\nSize: XL\nBontrager Elite Blendr, 31.8mm clamp, 7 degree, 100mm length\nBrake\tShimano Ultegra R8070 hydraulic disc, flat mount\nBrake rotor\tShimano RT800, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 8.15 kg / 17.97 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|   S  |   162 - 170 cm 5'4\" - 5'7\" | 74 - 78 cm 29\" - 31\" |\n|   M  |   170 - 178 cm 5'7\" - 5'10\" | 77 - 82 cm 30\" - 32\" |\n|   L  |  178 - 186 cm 5'10\" - 6'1\" | 82 - 86 cm 32\" - 34\" |\n|  XL  |  186 - 196 cm 6'1\" - 6'5\" | 87 - 92 cm 34\" - 36\" |\n\n\n## Geometry\n| Frame size letter         | S     | M     | L     | XL    |\n|---------------------------|-------|-------|-------|-------|\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 50.0  | 52.0  | 54.0  | 56.0  |\n| B — Seat tube angle       | 74.0° | 73.5° | 73.0° | 72.5° |\n| C — Head tube length      | 13.0  | 15.0  | 17.0  | 19.0  |\n| D — Head angle            | 71.0° | 72.0° | 72.0° | 72.5° |\n| E — Effective top tube    | 53.7  | 55.0  | 56.5  | 58.0  |\n| F — Bottom bracket height | 27.5  | 27.5  | 27.5  | 27.5  |\n| G — Bottom bracket drop   | 7.3   | 7.3   | 7.3   | 7.3   |\n| H — Chainstay length      | 41.0  | 41.0  | 41.0  | 41.0  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 6.0   | 6.0   | 6.0   | 5.8   |\n| K — Wheelbase             | 98.2  | 99.1  | 100.1 | 101.0 |\n| L — Standover             | 75.2  | 78.2  | 81.1  | 84.1  |\n| M — Frame reach           | 37.5  | 38.3  | 39.1  | 39.9  |\n| N — Frame stack           | 53.3  | 55.4  | 57.4  | 59.5  |",
    "price": 1799.99,
    "tags": [
      "bicycle",
      "touring bike"
    ]
  },
  {
    "name": "Velocity V9",
    "shortDescription": "Velocity V9 is a high-performance hybrid bike that combines speed and comfort for riders who demand the best of both worlds. The lightweight aluminum frame, along with the carbon fork and seat post, provide optimal stiffness and absorption to tackle any terrain. A 2x Shimano Deore drivetrain, hydraulic disc brakes, and 700c wheels with high-quality tires make it a versatile ride for commuters, fitness riders, and weekend adventurers alike.",
    "description": "## Overview\nIt's right for you if...\nYou want a fast, versatile bike that can handle anything from commuting to weekend adventures. You value comfort as much as speed and performance. You want a reliable and durable bike that will last for years to come.\n\nThe tech you get\nA lightweight aluminum frame with a carbon fork and seat post, a 2x Shimano Deore drivetrain with a wide range of gearing, hydraulic disc brakes, and 700c wheels with high-quality tires. The Velocity V9 is designed for riders who demand both performance and comfort in one package.\n\nThe final word\nThe Velocity V9 is the perfect bike for riders who want speed and performance without sacrificing comfort. The lightweight aluminum frame and carbon components provide optimal stiffness and absorption, while the 2x Shimano Deore drivetrain and hydraulic disc brakes ensure precise shifting and stopping power. Whether you're commuting, hitting the trails, or training for your next race, the Velocity V9 has everything you need to achieve your goals.\n\n## Features\n\n2x drivetrain\nA 2x drivetrain means more versatility and a wider range of gearing options. Whether you're climbing hills or sprinting on the flats, the Velocity V9 has the perfect gear for any situation.\n\nCarbon components\nThe Velocity V9 features a carbon fork and seat post to provide optimal stiffness and absorption. This means you can ride faster and more comfortably over any terrain.\n\nHydraulic disc brakes\nHydraulic disc brakes provide unparalleled stopping power and modulation in any weather condition. You'll feel confident and in control no matter where you ride.\n\n## Specifications\nFrameset\nFrame with Fork\tAluminum frame with carbon fork and seat post, internal cable routing, fender mounts, 135x5mm ThruSkew\nFork\tCarbon fork, hidden fender mounts, flat mount disc, 5x100mm thru-skew\n\nWheels\nWheel front\tDouble wall aluminum rims, 700c, quick release hub\nWheel rear\tDouble wall aluminum rims, 700c, quick release hub\nTire\tKenda Kwick Tendril, puncture resistant, reflective sidewall, 700x32c\nMax tire size\t700x35c without fenders, 700x32c with fenders\n\nDrivetrain\nShifter\tShimano Deore, 10 speed\nFront derailleur\tShimano Deore\nRear derailleur\tShimano Deore\nCrank\tShimano Deore, 46-30T, 170mm (S/M), 175mm (L/XL)\nBottom bracket\tShimano BB52, 68mm, threaded\nCassette\tShimano Deore, 11-36T, 10 speed\nChain\tShimano HG54, 10 speed\nPedal\tWellgo alloy platform\n\nComponents\nSaddle\tVelo VL-2158, steel rails\nSeatpost\tCarbon seat post, 27.2mm\nHandlebar\tAluminum, 31.8mm clamp, 15mm rise, 680mm width\nGrips\tVelo ergonomic grips\nStem\tAluminum, 31.8mm clamp, 7 degree, 90mm length\nBrake\tShimano hydraulic disc, MT200 lever, MT200 caliper\nBrake rotor\tShimano RT56, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 11.5 kg / 25.35 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  |  186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size         | S     | M     | L     | XL    |\n|--------------------|-------|-------|-------|-------|\n| Wheel size         | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube      | 44.0  | 48.0  | 52.0  | 56.0  |\n| B — Seat tube angle | 74.5° | 74.0° | 73.5° | 73.0° |\n| C — Head tube length | 14.5  | 16.0  | 18.0  | 20.0  |\n| D — Head angle       | 71.0° | 71.0° | 71.5° | 71.5° |\n| E — Effective top tube | 56.5  | 57.5  | 58.5  | 59.5  |\n| F — Bottom bracket height | 27.0  | 27.0  | 27.0  | 27.0  |\n| G — Bottom bracket drop | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length | 43.0  | 43.0  | 43.0  | 43.0  |\n| I — Offset | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail | 7.0   | 7.0   | 6.6   | 6.6   |\n| K — Wheelbase | 105.4 | 106.3 | 107.2 | 108.2 |\n| L — Standover | 73.2  | 77.1  | 81.2  | 85.1  |\n| M — Frame reach | 39.0  | 39.8  | 40.4  | 41.3  |\n| N — Frame stack | 57.0  | 58.5  | 60.0  | 61.5  |",
    "price": 2199.99,
    "tags": [
      "bicycle",
      "electric bike",
      "mountain bike"
    ]
  },
  {
    "name": "Aero Pro X",
    "shortDescription": "Aero Pro X is a high-end racing bike designed for serious cyclists who demand speed, agility, and superior performance. The lightweight carbon frame and fork, combined with the aerodynamic design, provide optimal stiffness and efficiency to maximize your speed. The bike features a 2x Shimano Ultegra drivetrain, hydraulic disc brakes, and 700c wheels with high-quality tires. Whether you're competing in a triathlon or climbing steep hills, Aero Pro X delivers exceptional performance and precision handling.",
    "description": "## Overview\nIt's right for you if...\nYou are a competitive cyclist looking for a bike that is designed for racing. You want a bike that delivers exceptional speed, agility, and precision handling. You demand superior performance and reliability from your equipment.\n\nThe tech you get\nA lightweight carbon frame with an aerodynamic design, a carbon fork with hidden fender mounts, a 2x Shimano Ultegra drivetrain with a wide range of gearing, hydraulic disc brakes, and 700c wheels with high-quality tires. Aero Pro X is designed for serious cyclists who demand nothing but the best.\n\nThe final word\nAero Pro X is the ultimate racing bike for serious cyclists. The lightweight carbon frame and aerodynamic design deliver maximum speed and efficiency, while the 2x Shimano Ultegra drivetrain and hydraulic disc brakes ensure precise shifting and stopping power. Whether you're competing in a triathlon or a criterium race, Aero Pro X delivers the performance you need to win.\n\n## Features\n\nAerodynamic design\nThe Aero Pro X features an aerodynamic design that reduces drag and maximizes efficiency. The bike is optimized for speed and agility, so you can ride faster and farther with less effort.\n\nHydraulic disc brakes\nHydraulic disc brakes provide unrivaled stopping power and modulation in any weather condition. You'll feel confident and in control no matter where you ride.\n\nCarbon components\nThe Aero Pro X features a carbon fork with hidden fender mounts to provide optimal stiffness and absorption. This means you can ride faster and more comfortably over any terrain.\n\n## Specifications\nFrameset\nFrame with Fork\tCarbon frame with an aerodynamic design, internal cable routing, 3s chain keeper, 142x12mm thru-axle\nFork\tCarbon fork with hidden fender mounts, flat mount disc, 100x12mm thru-axle\n\nWheels\nWheel front\tDouble wall carbon rims, 700c, thru-axle hub\nWheel rear\tDouble wall carbon rims, 700c, thru-axle hub\nTire\tContinental Grand Prix 5000, folding bead, 700x25c\nMax tire size\t700x28c without fenders, 700x25c with fenders\n\nDrivetrain\nShifter\tShimano Ultegra, 11 speed\nFront derailleur\tShimano Ultegra\nRear derailleur\tShimano Ultegra\nCrank\tShimano Ultegra, 52-36T, 170mm (S), 172.5mm (M), 175mm (L/XL)\nBottom bracket\tShimano BB72, 68mm, PressFit\nCassette\tShimano Ultegra, 11-30T, 11 speed\nChain\tShimano HG701, 11 speed\nPedal\tNot included\n\nComponents\nSaddle\tBontrager Montrose Elite, carbon rails, 138mm width\nSeatpost\tCarbon seat post, 27.2mm, 20mm offset\nHandlebar\tBontrager XXX Aero, carbon, 31.8mm clamp, 75mm reach, 125mm drop\nGrips\tBontrager Supertack Perf tape\nStem\tBontrager Pro, 31.8mm clamp, 7 degree, 90mm length\nBrake\tShimano hydraulic disc, Ultegra lever, Ultegra caliper\nBrake rotor\tShimano RT800, centerlock, 160mm\nRotor size\tMax brake rotor sizes: 160mm front & rear\n\nWeight\nWeight\tM - 8.36 kg / 18.42 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size |        Rider Height       |\n|:----:|:-------------------------:|\n|   S  |  155 - 165 cm 5'1\" - 5'5\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" |\n|  XL  |  186 - 197 cm 6'1\" - 6'6\" |\n\n## Geometry\n| Frame size         | S     | M     | L     | XL    |\n|--------------------|-------|-------|-------|-------|\n| Wheel size         | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube      | 50.6  | 52.4  | 54.3  | 56.2  |\n| B — Seat tube angle | 75.5° | 74.5° | 73.5° | 72.5° |\n| C — Head tube length | 12.0  | 14.0  | 16.0  | 18.0  |\n| D — Head angle       | 72.5° | 73.0° | 73.5° | 74.0° |\n| E — Effective top tube | 53.8  | 55.4  | 57.0  | 58.6  |\n| F — Bottom bracket height | 26.5  | 26.5  | 26.5  | 26.5  |\n| G — Bottom bracket drop | 7.0   | 7.0   | 7.0   | 7.0   |\n| H — Chainstay length | 41.0  | 41.0  | 41.0  | 41.0  |\n| I — Offset | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail | 6.0   | 6.0   | 6.0   | 6.0   |\n| K — Wheelbase | 97.1  | 98.7  | 100.2 | 101.8 |\n| L — Standover | 73.8  | 76.2  | 78.5  | 80.8  |\n| M — Frame reach | 38.8  | 39.5  | 40.2  | 40.9  |\n| N — Frame stack | 52.8  | 54.7  | 56.6  | 58.5  |",
    "price": 1599.99,
    "tags": [
      "bicycle",
      "road bike"
    ]
  },
  {
    "name": "Voltex+ Ultra Lowstep",
    "shortDescription": "Voltex+ Ultra Lowstep is a high-performance electric hybrid bike designed for riders who seek speed, comfort, and reliability during their everyday rides. Equipped with a powerful and efficient Voltex Drive Pro motor and a fully-integrated 600Wh battery, this e-bike allows you to cover longer distances on a single charge. The Voltex+ Ultra Lowstep comes with premium components that prioritize comfort and safety, such as a suspension seatpost, wide and stable tires, and integrated lights.",
    "description": "## Overview\n\nIt's right for you if...\nYou want an e-bike that provides a boost for faster rides and effortless usage. Durability is crucial, and you need a bike with one of the most powerful and efficient motors.\n\nThe tech you get\nA lightweight Delta Carbon Fiber frame with an ultra-lowstep design, a Voltex Drive Pro (350W, 75Nm) motor capable of maintaining speeds up to 30 mph, an extended range 600Wh battery integrated into the frame, and a Voltex Control Panel. Additionally, it features a 12-speed Shimano drivetrain, hydraulic disc brakes for optimal all-weather stopping power, a suspension seatpost, wide puncture-resistant tires for added stability, ergonomic grips, a kickstand, lights, and a cargo rack.\n\nThe final word\nThis bike offers enhanced enjoyment and ease of use on long commutes, leisure rides, and adventures. With its extended-range battery, powerful Voltex motor, user-friendly controller, and a seatpost that smooths out road vibrations, it guarantees an exceptional riding experience.\n\n## Features\n\nUltra-fast assistance\n\nExperience speeds up to 30 mph with the cutting-edge Voltex Drive Pro motor, allowing you to breeze through errands, commutes, and joyrides.\n\n## Specs\n\nFrameset\n- Frame: Delta Carbon Fiber, Removable Integrated Battery (RIB), sleek welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: Voltex Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: Voltex Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: Voltex E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore XT M8100, 12-speed\n- Rear derailleur: Shimano Deore XT M8100, long cage\n- Crank: Voltex alloy, 170mm length\n- Chainring: FSA, 44T, aluminum with guard\n- Cassette: Shimano Deore XT M8100, 10-51, 12-speed\n- Chain: KMC E12 Turbo\n- Pedal: Voltex Urban pedals\n\nComponents\n- Saddle: Voltex Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar: Voltex alloy, 31.8mm, comfort sweep, 620mm width (XS, S, M), 660mm width (L)\n- Grips: Voltex Satellite Elite, alloy lock-on\n- Stem: Voltex alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length (XS, S), 105mm length (M, L)\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT520 hydraulic disc\n- Brake rotor: Shimano RT56, 6-bolt, 180mm (XS, S, M, L), 160mm (XS, S, M, L)\n\nAccessories\n- Battery: Voltex PowerTube 600Wh\n- Charger: Voltex compact 2A, 100-240V\n- Computer: Voltex Control Panel\n- Motor: Voltex Drive Pro, 75Nm, 30mph\n- Light: Voltex Solo for e-bike, taillight (XS, S, M, L), Voltex MR8, 180 lumen, 60 lux, LED, headlight (XS, S, M, L)\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: Voltex-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender: Voltex wide (XS, S, M, L), Voltex plastic (XS, S, M, L)\n\nWeight\n- Weight: M - 20.50 kg / 45.19 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 330 pounds (150 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 38.0  | 43.0  | 48.0  | 53.0  |\n| B — Seat tube angle       | 70.5° | 70.5° | 70.5° | 70.5° |\n| C — Head tube length      | 15.0  | 15.0  | 17.0  | 19.0  |\n| D — Head angle            | 69.2° | 69.2° | 69.2° | 69.2° |\n| E — Effective top tube    | 57.2  | 57.7  | 58.8  | 60.0  |\n| F — Bottom bracket height | 30.3  | 30.3  | 30.3  | 30.3  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.5  | 48.5  | 48.5  | 48.5  |\n| I — Offset                | 5.0   | 5.0   | 5.0   | 5.0   |\n| J — Trail                 | 9.0   | 9.0   | 9.0   | 9.0   |\n| K — Wheelbase             | 111.8 | 112.3 | 113.6 | 114.8 |\n| L — Standover             | 42.3  | 42.3  | 42.3  | 42.3  |\n| M — Frame reach           | 36.0  | 38.0  | 38.0  | 38.0  |\n| N — Frame stack           | 62.0  | 62.0  | 63.9  | 65.8  |\n| Stem length               | 8.0   | 8.5   | 8.5   | 10.5  |\n\nPlease note that the specifications and features listed above are subject to change and may vary based on different models and versions of the Voltex+ Ultra Lowstep bike.",
    "price": 2999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "SwiftRide Hybrid",
    "shortDescription": "SwiftRide Hybrid is a versatile and efficient bike designed for riders who want a smooth and enjoyable ride on various terrains. It incorporates advanced technology and high-quality components to provide a comfortable and reliable cycling experience.",
    "description": "## Overview\n\nIt's right for you if...\nYou are looking for a bike that combines the benefits of an electric bike with the versatility of a hybrid. You value durability, speed, and ease of use.\n\nThe tech you get\nThe SwiftRide Hybrid features a lightweight and durable aluminum frame, making it easy to handle and maneuver. It is equipped with a powerful electric motor that offers a speedy assist, helping you reach speeds of up to 25 mph. The bike comes with a removable and fully-integrated 500Wh battery, providing a long-range capacity for extended rides. It also includes a 10-speed Shimano drivetrain, hydraulic disc brakes for precise stopping power, wide puncture-resistant tires for stability, and integrated lights for enhanced visibility.\n\nThe final word\nThe SwiftRide Hybrid is designed for riders who want a bike that can handle daily commutes, recreational rides, and adventures. With its efficient motor, intuitive controls, and comfortable features, it offers an enjoyable and hassle-free riding experience.\n\n## Features\n\nEfficient electric assist\nExperience the thrill of effortless riding with the powerful electric motor that provides a speedy assist, making your everyday rides faster and more enjoyable.\n\n## Specs\n\nFrameset\n- Frame: Lightweight Aluminum, Removable Integrated Battery (RIB), rack & fender mounts, internal routing, 135x5mm QR\n- Fork: SwiftRide Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: SwiftRide Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: SwiftRide E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: SwiftRide City pedals\n\nComponents\n- Saddle: SwiftRide Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - SwiftRide alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - SwiftRide alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: SwiftRide Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - SwiftRide alloy quill, 31.8mm clamp, adjustable rise, 85mm length\n  - Size: M, L - SwiftRide alloy quill, 31.8mm clamp, adjustable rise, 105mm length\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: SwiftRide PowerTube 500Wh\n- Charger: SwiftRide compact 2A, 100-240V\n- Computer: SwiftRide Purion\n- Motor: SwiftRide Performance Line Sport, 65Nm, 25mph\n- Light:\n  - Size: XS, S, M, L - SwiftRide SOLO for e-bike, taillight\n  - Size: XS, S, M, L - SwiftRide MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: SwiftRide-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - SwiftRide wide\n  - Size: XS, S, M, L - SwiftRide plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm (4'10\" - 5'1\") | 69 - 73 cm (27\" - 29\") |\n|   S  |  155 - 165 cm (5'1\" - 5'5\") | 72 - 78 cm (28\" - 31\") |\n|   M  |  165 - 175 cm (5'5\" - 5'9\") | 77 - 83 cm (30\" - 33\") |\n|   L  |  175 - 186 cm (5'9\" - 6'1\") | 82 - 88 cm (32\" - 35\") |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 3999.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "RoadRunner E-Speed Lowstep",
    "shortDescription": "RoadRunner E-Speed Lowstep is a high-performance electric hybrid designed for riders seeking speed and excitement on their daily rides. It is equipped with a powerful and reliable ThunderBolt drive unit that offers exceptional acceleration. The bike features a fully-integrated 500Wh battery, allowing riders to cover longer distances on a single charge. With its comfortable and safe components, including a suspension seatpost, wide and stable tires, and integrated lights, the RoadRunner E-Speed Lowstep ensures a smooth and enjoyable ride.",
    "description": "## Overview\n\nIt's right for you if...\nYou're looking for an e-bike that provides an extra boost to reach your destination quickly and effortlessly. You prioritize durability and want a bike with one of the fastest motors available.\n\nThe tech you get\nA lightweight and sturdy ThunderBolt aluminum frame with a lowstep geometry. The bike is equipped with a ThunderBolt Performance Sport (250W, 65Nm) drive unit capable of reaching speeds up to 28 mph. It features a long-range 500Wh battery fully integrated into the frame and a ThunderBolt controller. Additionally, the bike has a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThe RoadRunner E-Speed Lowstep is designed to provide enjoyment and ease of use on longer commutes, recreational rides, and adventurous journeys. Its long-range battery, fast ThunderBolt motor, intuitive controller, and road-smoothing suspension seatpost make it the perfect choice for riders seeking both comfort and speed.\n\n## Features\n\nSuper speedy assist\n\nThe ThunderBolt Performance Sport drive unit allows you to accelerate up to 28mph, making errands, commutes, and joyrides a breeze.\n\n## Specs\n\nFrameset\n- Frame: ThunderBolt Smooth Aluminum, Removable Integrated Battery (RIB), sleek welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: RoadRunner Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Hub front: ThunderBolt DC-20, alloy, 6-bolt, 5x100mm QR\n- Skewer front: 132x5mm QR, ThruSkew\n- Hub rear: ThunderBolt DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Skewer rear: 153x5mm bolt-on\n- Rim: ThunderBolt Connection, double-wall, 32-hole, 20 mm width, Schrader valve\n- Tire: ThunderBolt E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: RoadRunner City pedals\n\nComponents\n- Saddle: RoadRunner Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - RoadRunner alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - RoadRunner alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: RoadRunner Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - RoadRunner alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\n  - Size: M, L - RoadRunner alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\n- Headset: VP sealed cartridge, 1-1/8'', threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: ThunderBolt PowerTube 500Wh\n- Charger: ThunderBolt compact 2A, 100-240V\n- Computer: ThunderBolt Purion\n- Motor: ThunderBolt Performance Line Sport, 65Nm, 28mph\n- Light:\n  - Size: XS, S, M, L - ThunderBolt SOLO for e-bike, taillight\n  - Size: XS, S, M, L - ThunderBolt MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: MIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - RoadRunner wide\n  - Size: XS, S, M, L - RoadRunner plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 4999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "Hyperdrive Turbo X1",
    "shortDescription": "Hyperdrive Turbo X1 is a high-performance electric bike designed for riders seeking an exhilarating experience on their daily rides. It features a powerful and efficient Hyperdrive Sport drive unit and a sleek, integrated 500Wh battery for extended range. This e-bike is equipped with top-of-the-line components prioritizing comfort and safety, including a suspension seatpost, wide and stable tires, and integrated lights.",
    "description": "## Overview\n\nIt's right for you if...\nYou crave the thrill of an e-bike that can accelerate rapidly, reaching high speeds effortlessly. You value durability and are looking for a bike that is equipped with one of the fastest motors available.\n\nThe tech you get\nA lightweight Hyper Alloy frame with a lowstep geometry, a Hyperdrive Sport (300W, 70Nm) drive unit capable of maintaining speeds up to 30 mph, a long-range 500Wh battery seamlessly integrated into the frame, and an intuitive Hyper Control controller. Additionally, it features a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for enhanced stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThis bike is designed for riders seeking enjoyment and convenience on longer commutes, recreational rides, and thrilling adventures. With its long-range battery, high-speed motor, user-friendly controller, and smooth-riding suspension seatpost, the Hyperdrive Turbo X1 guarantees an exceptional e-biking experience.\n\n## Features\n\nHyperboost Acceleration\nExperience adrenaline-inducing rides with the powerful Hyperdrive Sport drive unit that enables quick acceleration and effortless cruising through errands, commutes, and joyrides.\n\n## Specs\n\nFrameset\nFrame\tHyper Alloy, Removable Integrated Battery (RIB), seamless welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\nFork\tHyper Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\nMax compatible fork travel\t50mm\n\nWheels\nHub front\tFormula DC-20, alloy, 6-bolt, 5x100mm QR\nSkewer front\t132x5mm QR, ThruSkew\nHub rear\tFormula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\nSkewer rear\t153x5mm bolt-on\nRim\tHyper Connection, double-wall, 32-hole, 20 mm width, Schrader valve\nTire\tHyper E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\nMax tire size\t700x50mm with or without fenders\n\nDrivetrain\nShifter\tShimano Deore M4100, 10 speed\nRear derailleur\tShimano Deore M5120, long cage\nCrank\tProWheel alloy, 170mm length\nChainring\tFSA, 42T, steel w/guard\nCassette\tShimano Deore M4100, 11-42, 10 speed\nChain\tKMC E10\nPedal\tHyper City pedals\n\nComponents\nSaddle\tHyper Boulevard\nSeatpost\tAlloy, suspension, 31.6mm, 300mm length\n*Handlebar\tSize: XS, S, M\nHyper alloy, 31.8mm, comfort sweep, 620mm width\nSize: L\nHyper alloy, 31.8mm, comfort sweep, 660mm width\nGrips\tHyper Satellite Elite, alloy lock-on\n*Stem\tSize: XS, S\nHyper alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\nSize: M, L\nHyper alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\nHeadset\tVP sealed cartridge, 1-1/8'', threaded\nBrake\tShimano MT200 hydraulic disc\n*Brake rotor\tSize: XS, S, M, L\nShimano RT26, 6-bolt,180mm\nSize: XS, S, M, L\nShimano RT26, 6-bolt,160mm\n\nAccessories\nBattery\tHyper PowerTube 500Wh\nCharger\tHyper compact 2A, 100-240V\nComputer\tHyper Control\nMotor\tHyperdrive Sport, 70Nm, 30mph\n*Light\tSize: XS, S, M, L\nSpanninga SOLO for e-bike, taillight\nSize: XS, S, M, L\nHerrmans MR8, 180 lumen, 60 lux, LED, headlight\nKickstand\tAdjustable length rear mount alloy kickstand\nCargo rack\tMIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n*Fender\tSize: XS, S, M, L\nSKS wide\nSize: XS, S, M, L\nSKS plastic\n\nWeight\nWeight\tM - 22.30 kg / 49.17 lbs\nWeight limit\tThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\n\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 1999.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  },
  {
    "name": "Horizon+ Evo Lowstep",
    "shortDescription": "The Horizon+ Evo Lowstep is a versatile electric hybrid bike designed for riders seeking a thrilling and efficient riding experience on a variety of terrains. With its powerful Bosch Performance Line Sport drive unit and integrated 500Wh battery, this e-bike enables riders to cover long distances with ease. Equipped with features prioritizing comfort and safety, such as a suspension seatpost, stable tires, and integrated lights, the Horizon+ Evo Lowstep is a reliable companion for everyday rides.",
    "description": "## Overview\n\nIt's right for you if...\nYou desire the convenience and speed of an e-bike to enhance your riding, and you want an intuitive and durable bicycle. You prioritize having one of the fastest motors developed by Bosch.\n\nThe tech you get\nA lightweight Alpha Smooth Aluminum frame with a lowstep geometry, a Bosch Performance Line Sport (250W, 65Nm) drive unit capable of sustaining speeds up to 28 mph, a fully encased 500Wh battery integrated into the frame, and a Bosch Purion controller. Additionally, it features a 10-speed Shimano drivetrain, hydraulic disc brakes for reliable stopping power in all weather conditions, a suspension seatpost, wide puncture-resistant tires for improved stability, ergonomic grips, a kickstand, lights, and a rack and fenders.\n\nThe final word\nThe Horizon+ Evo Lowstep offers an enjoyable and user-friendly riding experience for longer commutes, recreational rides, and adventures. It boasts an extended range battery, a high-performance Bosch motor, an intuitive controller, and a suspension seatpost for a smooth ride on various road surfaces.\n\n## Features\n\nSuper speedy assist\nExperience effortless cruising through errands, commutes, and joyrides with the new Bosch Performance Sport drive unit, allowing acceleration of up to 28 mph.\n\n## Specs\n\nFrameset\n- Frame: Alpha Platinum Aluminum, Removable Integrated Battery (RIB), smooth welds, rack & fender mounts, internal routing, kickstand mount, 135x5mm QR\n- Fork: Horizon Alloy, threaded steel steerer, rack mounts, post mount disc, 460mm axle-to-crown, ThruSkew 5mm QR\n- Max compatible fork travel: 50mm\n\nWheels\n- Front Hub: Formula DC-20, alloy, 6-bolt, 5x100mm QR\n- Front Skewer: 132x5mm QR, ThruSkew\n- Rear Hub: Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5mm QR\n- Rear Skewer: 153x5mm bolt-on\n- Rim: Bontrager Connection, double-wall, 32-hole, 20mm width, Schrader valve\n- Tire: Bontrager E6 Hard-Case Lite, reflective, wire bead, 60tpi, 700x50c\n- Max tire size: 700x50mm with or without fenders\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10-speed\n- Rear Derailleur: Shimano Deore M5120, long cage\n- Crank: ProWheel alloy, 170mm length\n- Chainring: FSA, 42T, steel w/guard\n- Cassette: Shimano Deore M4100, 11-42, 10-speed\n- Chain: KMC E10\n- Pedal: Bontrager City pedals\n\nComponents\n- Saddle: Bontrager Boulevard\n- Seatpost: Alloy, suspension, 31.6mm, 300mm length\n- Handlebar:\n  - Size: XS, S, M - Bontrager alloy, 31.8mm, comfort sweep, 620mm width\n  - Size: L - Bontrager alloy, 31.8mm, comfort sweep, 660mm width\n- Grips: Bontrager Satellite Elite, alloy lock-on\n- Stem:\n  - Size: XS, S - Bontrager alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 85mm length\n  - Size: M, L - Bontrager alloy quill, 31.8mm clamp, adjustable rise, Blendr compatible, 105mm length\n- Headset: VP sealed cartridge, 1-1/8\", threaded\n- Brake: Shimano MT200 hydraulic disc\n- Brake rotor:\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 180mm\n  - Size: XS, S, M, L - Shimano RT26, 6-bolt, 160mm\n\nAccessories\n- Battery: Bosch PowerTube 500Wh\n- Charger: Bosch compact 2A, 100-240V\n- Computer: Bosch Purion\n- Motor: Bosch Performance Line Sport, 65Nm, 28mph\n- Light:\n  - Size: XS, S, M, L - Spanninga SOLO for e-bike, taillight\n  - Size: XS, S, M, L - Herrmans MR8, 180 lumen, 60 lux, LED, headlight\n- Kickstand: Adjustable length rear mount alloy kickstand\n- Cargo rack: MIK-compatible alloy rear rack, maximum load 25 kg / 55 lbs\n- Fender:\n  - Size: XS, S, M, L - SKS wide\n  - Size: XS, S, M, L - SKS plastic\n\nWeight\n- Weight: M - 22.30 kg / 49.17 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  XS  | 147 - 155 cm 4'10\" - 5'1\" | 69 - 73 cm 27\" - 29\" |\n|   S  |  155 - 165 cm 5'1\" - 5'5\" | 72 - 78 cm 28\" - 31\" |\n|   M  |  165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  |  175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n\n## Geometry\n\nAll measurements provided in cm unless otherwise noted.\nSizing table\n| Frame size number         | 40 cm | 45 cm | 50 cm | 55 cm |\n|---------------------------|-------|-------|-------|-------|\n| Frame size letter         | XS    | S     | M     | L     |\n| Wheel size                | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube             | 39.0  | 44.0  | 50.0  | 55.0  |\n| B — Seat tube angle       | 71.0° | 71.0° | 71.0° | 71.0° |\n| C — Head tube length      | 16.0  | 16.0  | 18.0  | 20.0  |\n| D — Head angle            | 68.2° | 68.2° | 68.2° | 68.2° |\n| E — Effective top tube    | 58.2  | 58.7  | 59.8  | 61.0  |\n| F — Bottom bracket height | 29.4  | 29.4  | 29.4  | 29.4  |\n| G — Bottom bracket drop   | 6.5   | 6.5   | 6.5   | 6.5   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.5   | 4.5   | 4.5   | 4.5   |\n| J — Trail                 | 9.5   | 9.5   | 9.5   | 9.5   |\n| K — Wheelbase             | 112.2 | 112.7 | 114.0 | 115.2 |\n| L — Standover             | 43.3  | 43.3  | 43.3  | 43.3  |\n| M — Frame reach           | 36.5  | 38.5  | 38.5  | 38.5  |\n| N — Frame stack           | 63.0  | 63.0  | 64.9  | 66.8  |\n| Stem length               | 8.5   | 9.0   | 9.0   | 11.0  |",
    "price": 4499.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "FastRider X1",
    "shortDescription": "FastRider X1 is a high-performance e-bike designed for riders seeking speed and long-distance capabilities. Equipped with a powerful motor and a high-capacity battery, the FastRider X1 is perfect for daily commuters and e-bike enthusiasts. It boasts a sleek and functional design, making it a great alternative to car transportation. The bike also features a smartphone controller for easy navigation and entertainment options.",
    "description": "## Overview\nIt's right for you if...\nYou're looking for an e-bike that offers both speed and endurance. The FastRider X1 comes with a high-performance motor and a long-lasting battery, making it ideal for long-distance rides.\n\nThe tech you get\nThe FastRider X1 features a state-of-the-art motor and a spacious battery, ensuring a fast and efficient ride.\n\nThe final word\nWith the powerful motor and long-range battery, the FastRider X1 allows you to cover more distance at higher speeds.\n\n## Features\nConnect Your Ride with the FastRider App\nDownload the FastRider app and transform your smartphone into an on-board computer. Easily dock and charge your phone with the smartphone controller, and use the thumb pad on your handlebar to make calls, listen to music, get turn-by-turn directions, and more. The app also allows you to connect with fitness and health apps, syncing your routes and ride data.\n\nGoodbye, Car. Hello, Extended Range!\nWith the option to add the Range Boost feature, you can attach a second long-range battery to your FastRider X1, doubling the distance and time between charges. This enhancement allows you to ride longer, commute farther, and take on more adventurous routes.\n\nWhat is the range?\nTo estimate the distance you can travel on a single charge, use our range calculator tool. It automatically fills in the variables for this specific bike model and assumes an average rider, but you can adjust the settings to get the most accurate estimate for your needs.\n\n## Specifications\nFrameset\n- Frame: High-performance hydroformed alloy, Removable Integrated Battery, Range Boost-compatible, internal cable routing, Motor Armour, post-mount disc, 135x5 mm QR\n- Fork: FastRider rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru axle, post mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: FastRider sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: FastRider Switch thru axle, removable lever\n- Rear Hub: FastRider alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: FastRider MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: Size: M, L, XL - 14g stainless steel, black\n- Tire: FastRider E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear derailleur: Size: M, L, XL - Shimano Deore M5120, long cage\n- Crank: Size: M - FastRider alloy, 170mm length / Size: L, XL - FastRider alloy, 175mm length\n- Chainring: FastRider 46T narrow/wide alloy, w/alloy guard\n- Cassette: Size: M, L, XL - Shimano Deore M4100, 11-42, 10 speed\n- Chain: Size: M, L, XL - KMC E10 / Size: M, L, XL - KMC X10e\n- Pedal: Size: M, L, XL - FastRider City pedals / Size: M, L, XL - Wellgo C157, boron axle, plastic body / Size: M, L, XL - slip-proof aluminum pedals with reflectors\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: FastRider Commuter Comp\n- Seatpost: FastRider Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Size: M - FastRider alloy, 31.8mm, 15mm rise, 600mm width / Size: L, XL - FastRider alloy, 31.8mm, 15mm rise, 660mm width\n- Grips: FastRider Satellite Elite, alloy lock-on\n- Stem: Size: M - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length / Size: L - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length / Size: XL - FastRider alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\n- Headset: Size: M, L, XL - FSA IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom / Size: M, L, XL - FSA Integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\n- Battery: FastRider PowerTube 625Wh\n- Charger: FastRider standard 4A, 100-240V\n- Motor: FastRider Performance Speed, 85 Nm, 28 mph / 45 kph\n- Light: Size: M, L, XL - FastRider taillight, 50 lumens / Size: M, L, XL - FastRider headlight, 500 lumens\n- Kickstand: Size: M, L, XL - Rear mount, alloy / Size: M, L, XL - Adjustable length alloy kickstand\n- Cargo rack: FastRider integrated rear rack, aluminum\n- Fender: FastRider custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n\nWeight limit\n- This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         | M     | L     | XL    |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 5499.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "SonicRide 8S",
    "shortDescription": "SonicRide 8S is a high-performance e-bike designed for riders who crave speed and long-distance capabilities. The advanced SonicDrive motor provides powerful assistance up to 28 mph, combined with a durable and long-lasting battery for extended rides. With its sleek design and thoughtful features, the SonicRide 8S is perfect for those who prefer the freedom of riding a bike over driving a car. Plus, it comes equipped with a smartphone controller for easy navigation, music, and more.",
    "description": "## Overview\nIt's right for you if...\nYou want a fast and efficient e-bike that can take you long distances. The SonicRide 8S features a hydroformed aluminum frame with a concealed 625Wh battery, a high-powered SonicDrive motor, and a Smartphone Controller. It also includes essential accessories such as lights, fenders, and a rear rack.\n\nThe tech you get\nThe SonicRide 8S is equipped with the fastest SonicDrive motor, ensuring exhilarating rides at high speeds. The long-range battery is perfect for commuters and riders looking to explore new horizons.\n\nThe final word\nWith the SonicDrive motor and long-lasting battery, you can enjoy extended rides at higher speeds.\n\n## Features\n\nConnect Your Ride with SonicRide App\nDownload the SonicRide app and transform your phone into an onboard computer. Simply attach it to the Smartphone Controller for docking and charging. Use the thumb pad on your handlebar to control calls, music, directions, and more. The Bluetooth® wireless technology allows you to connect with fitness and health apps, syncing your routes and ride data.\n\nSay Goodbye to Limited Range with Range Boost!\nExperience the convenience of Range Boost, an additional long-range 500Wh battery that seamlessly attaches to your bike's down tube. This upgrade allows you to double your distance and time between charges, enabling longer commutes and more adventurous rides. Range Boost is compatible with select SonicRide electric bike models.\n\nWhat is the range?\nFor an accurate estimate of how far you can ride on a single charge, use SonicRide's range calculator. We have pre-filled the variables for this specific bike model and the average rider, but you can adjust them to obtain the most accurate estimate.\n\n## Specifications\nFrameset\n- Frame: High-performance hydroformed alloy, Removable Integrated Battery, Range Boost-compatible, internal cable routing, Motor Armour, post-mount disc, 135x5 mm QR\n- Fork: SonicRide rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru axle, post mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: SonicRide sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: SonicRide Switch thru axle, removable lever\n- Rear Hub: SonicRide alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: SonicRide MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: Size: M, L, XL - 14g stainless steel, black\n- Tire: SonicRide E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear Derailleur: Size: M, L, XL - Shimano Deore M5120, long cage\n- Crank: Size: M - SonicRide alloy, 170mm length; Size: L, XL - SonicRide alloy, 175mm length\n- Chainring: SonicRide 46T narrow/wide alloy, with alloy guard\n- Cassette: Size: M, L, XL - Shimano Deore M4100, 11-42, 10 speed\n- Chain: Size: M, L, XL - KMC E10; Size: M, L, XL - KMC X10e\n- Pedal: Size: M, L, XL - SonicRide City pedals; Size: M, L, XL - Wellgo C157, boron axle, plastic body; Size: M, L, XL - slip-proof aluminum pedals with reflectors\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: SonicRide Commuter Comp\n- Seatpost: SonicRide Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Size: M - SonicRide alloy, 31.8mm, 15mm rise, 600mm width; Size: L, XL - SonicRide alloy, 31.8mm, 15mm rise, 660mm width\n- Grips: SonicRide Satellite Elite, alloy lock-on\n- Stem: Size: M - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length; Size: L - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length; Size: XL - SonicRide alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\n- Headset: Size: M, L, XL - SonicRide IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom; Size: M, L, XL - SonicRide Integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\n- Battery: SonicRide PowerTube 625Wh\n- Charger: SonicRide standard 4A, 100-240V\n- Motor: SonicRide Performance Speed, 85 Nm, 28 mph / 45 kph\n- Light: Size: M, L, XL - SonicRide Lync taillight, 50 lumens; Size: M, L, XL - SonicRide Lync headlight, 500 lumens\n- Kickstand: Size: M, L, XL - Rear mount, alloy; Size: M, L, XL - Adjustable length alloy kickstand\n- Cargo rack: SonicRide integrated rear rack, aluminum\n- Fender: SonicRide custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm / 5'5\" - 5'9\" | 77 - 83 cm / 30\" - 33\" |\n|   L  | 175 - 186 cm / 5'9\" - 6'1\" | 82 - 88 cm / 32\" - 35\" |\n|  XL  | 186 - 197 cm / 6'1\" - 6'6\" | 87 - 93 cm / 34\" - 37\" |\n\n## Geometry\n| Frame size letter         |   M   |   L   |   XL  |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |",
    "price": 5999.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "SwiftVolt Pro",
    "shortDescription": "SwiftVolt Pro is a high-performance e-bike designed for riders seeking a thrilling and fast riding experience. Equipped with a powerful SwiftDrive motor that provides assistance up to 30 mph and a long-lasting battery, this bike is perfect for long-distance commuting and passionate e-bike enthusiasts. The sleek and innovative design features cater specifically to individuals who prioritize cycling over driving. Additionally, the bike is seamlessly integrated with your smartphone, allowing you to use it for navigation, music, and more.",
    "description": "## Overview\nThis bike is ideal for you if:\n- You desire a sleek and modern hydroformed aluminum frame that houses a 700Wh battery.\n- You want to maintain high speeds of up to 30 mph with the assistance of the SwiftDrive motor.\n- You appreciate the convenience of using your smartphone as a controller, which can be docked and charged on the handlebar.\n\n## Features\n\nConnect with SwiftSync App\nBy downloading the SwiftSync app, your smartphone becomes an interactive on-board computer. Attach it to the handlebar-mounted controller for easy access and charging. With the thumb pad, you can make calls, listen to music, receive turn-by-turn directions, and connect with fitness and health apps to track your routes and ride data via Bluetooth® wireless technology.\n\nEnhanced Range with BoostMax\nBoostMax offers the capability to attach a second 700Wh Swift battery to the downtube of your bike, effectively doubling the distance and time between charges. This allows for extended rides, longer commutes, and more significant adventures. BoostMax is compatible with select Swift electric bike models.\n\nRange Estimation\nFor an estimate of how far you can ride on a single charge, consult the Swift range calculator. The variables are automatically populated based on this bike model and the average rider, but you can modify them to obtain the most accurate estimate.\n\n## Specifications\nFrameset\n- Frame: Lightweight hydroformed alloy, Removable Integrated Battery, BoostMax-compatible, internal cable routing, post-mount disc, 135x5 mm QR\n- Fork: SwiftVolt rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru-axle, post-mount disc brake\n- Max compatible fork travel: 63mm\n\nWheels\n- Front Hub: Swift sealed bearing, 32-hole 15mm alloy thru-axle\n- Front Skewer: Swift Switch thru-axle, removable lever\n- Rear Hub: Swift alloy, sealed bearing, 6-bolt, 135x5mm QR\n- Rear Skewer: 148x5mm bolt-on\n- Rim: SwiftRim, tubeless compatible, 32-hole, 35mm width, Presta valve\n- Spokes: 14g stainless steel, black\n- Tire: Swift E6 Hard-Case Lite, reflective strip, 27.5x2.40''\n- Max tire size: 27.5x2.40\"\n\nDrivetrain\n- Shifter: Shimano Deore M4100, 10 speed\n- Rear Derailleur: Shimano Deore M5120, long cage\n- Crank: Swift alloy, 170mm length\n- Chainring: Swift 46T narrow/wide alloy, w/alloy guard\n- Cassette: Shimano Deore M4100, 11-42, 10 speed\n- Chain: KMC E10\n- Pedal: Swift City pedals\n- Max chainring size: 1x: 48T\n\nComponents\n- Saddle: Swift Commuter Comp\n- Seatpost: Swift Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\n- Handlebar: Swift alloy, 31.8mm, 15mm rise, 600mm width (M), 660mm width (L, XL)\n- Grips: Swift Satellite Elite, alloy lock-on\n- Stem: Swift alloy, 31.8mm, Blendr compatible, 7 degree, 70mm length (M), 90mm length (L), 100mm length (XL)\n- Headset: FSA IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\n- Brakes: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\n- Brake Rotor: Shimano RT56, 6-bolt, 180mm\n- Rotor size: Max 180mm front & rear\n\nAccessories\n- Battery: Swift PowerTube 700Wh\n- Charger: Swift standard 4A, 100-240V\n- Motor: SwiftDrive, 90 Nm, 30 mph / 48 kph\n- Light: Swift Lync taillight, 50 lumens (M, L, XL), Swift Lync headlight, 500 lumens (M, L, XL)\n- Kickstand: Rear mount, alloy (M, L, XL), Adjustable length alloy kickstand (M, L, XL)\n- Cargo rack: SwiftVolt integrated rear rack, aluminum\n- Fender: Swift custom aluminum\n\nWeight\n- Weight: M - 25.54 kg / 56.3 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |     Rider Height      |     Inseam    |\n|:----:|:---------------------:|:-------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         | M     | L     | XL    |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 2499.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  },
  {
    "name": "AgileEon 9X",
    "shortDescription": "AgileEon 9X is a high-performance e-bike designed for riders seeking speed and endurance. Equipped with a robust motor and an extended battery life, this bike is perfect for long-distance commuters and avid e-bike enthusiasts. It boasts innovative features tailored for individuals who prioritize cycling over driving. Additionally, the bike integrates seamlessly with your smartphone, allowing you to access navigation, music, and more.",
    "description": "## Overview\nIt's right for you if...\nYou crave speed and want to cover long distances efficiently. The AgileEon 9X features a sleek hydroformed aluminum frame that houses a powerful motor, along with a large-capacity battery for extended rides. It comes equipped with a 10-speed drivetrain, front and rear lighting, fenders, and a rear rack.\n\nThe tech you get\nDesigned for those constantly on the move, this bike includes a state-of-the-art motor and a high-capacity battery, making it an excellent choice for lengthy commutes.\n\nThe final word\nWith the AgileEon 9X, you can push your boundaries and explore new horizons thanks to its powerful motor and long-lasting battery.\n\n## Features\n\nConnect Your Ride with RideMate App\nMake use of the RideMate app to transform your smartphone into an onboard computer. Simply attach it to the RideMate controller to dock and charge, then utilize the thumb pad on your handlebar to make calls, listen to music, receive turn-by-turn directions, and more. The bike also supports Bluetooth® wireless technology, enabling seamless connectivity with fitness and health apps for route syncing and ride data.\n\nGoodbye, car. Hello, Extended Range!\nEnhance your riding experience with the Extended Range option, which allows for the attachment of an additional high-capacity 500Wh battery to your bike's downtube. This doubles the distance and time between charges, enabling longer rides, extended commutes, and more significant adventures. The Extended Range feature is compatible with select AgileEon electric bike models.\n\nWhat is the range?\nTo determine how far you can ride on a single charge, you can utilize the range calculator provided by AgileEon. We have pre-filled the variables for this specific model and an average rider, but adjustments can be made for a more accurate estimation.\n\n## Specifications\nFrameset\nFrame: High-performance hydroformed alloy, Removable Integrated Battery, Extended Range-compatible, internal cable routing, Motor Armor, post-mount disc, 135x5 mm QR\nFork: AgileEon rigid alloy fork, 1-1/8'' steel steerer, 100x15mm thru-axle, post-mount disc brake\nMax compatible fork travel: 63mm\n\nWheels\nFront Hub: AgileEon sealed bearing, 32-hole 15mm alloy thru-axle\nFront Skewer: AgileEon Switch thru-axle, removable lever\nRear Hub: AgileEon alloy, sealed bearing, 6-bolt, 135x5mm QR\nRear Skewer: 148x5mm bolt-on\nRim: AgileEon MD35, tubeless compatible, 32-hole, 35mm width, Presta valve\nSpokes:\n- Size: M, L, XL: 14g stainless steel, black\nTire: AgileEon E6 Hard-Case Lite, reflective strip, 27.5x2.40''\nMax tire size: 27.5x2.40\"\n\nDrivetrain\nShifter: Shimano Deore M4100, 10-speed\nRear derailleur:\n- Size: M, L, XL: Shimano Deore M5120, long cage\nCrank:\n- Size: M: AgileEon alloy, 170mm length\n- Size: L, XL: AgileEon alloy, 175mm length\nChainring: AgileEon 46T narrow/wide alloy, with alloy guard\nCassette:\n- Size: M, L, XL: Shimano Deore M4100, 11-42, 10-speed\nChain:\n- Size: M, L, XL: KMC E10\nPedal:\n- Size: M, L, XL: AgileEon City pedals\nMax chainring size: 1x: 48T\n\nComponents\nSaddle: AgileEon Commuter Comp\nSeatpost: AgileEon Comp, 6061 alloy, 31.6mm, 8mm offset, 330mm length\nHandlebar:\n- Size: M: AgileEon alloy, 31.8mm, 15mm rise, 600mm width\n- Size: L, XL: AgileEon alloy, 31.8mm, 15mm rise, 660mm width\nGrips: AgileEon Satellite Elite, alloy lock-on\nStem:\n- Size: M: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 70mm length\n- Size: L: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 90mm length\n- Size: XL: AgileEon alloy, 31.8mm, Blendr compatible, 7-degree, 100mm length\nHeadset:\n- Size: M, L, XL: AgileEon IS-2 alloy, integrated, sealed cartridge bearing, 1-1/8'' top, 1.5'' bottom\nBrake: Shimano MT520 4-piston hydraulic disc, post-mount, 180mm rotor\nBrake rotor: Shimano RT56, 6-bolt, 180mm\nRotor size: Max brake rotor sizes: 180mm front & rear\n\nAccessories\nBattery: AgileEon PowerTube 625Wh\nCharger: AgileEon standard 4A, 100-240V\nMotor: AgileEon Performance Speed, 85 Nm, 28 mph / 45 kph\nLight:\n- Size: M, L, XL: AgileEon taillight, 50 lumens\n- Size: M, L, XL: AgileEon headlight, 500 lumens\nKickstand:\n- Size: M, L, XL: Rear mount, alloy\n- Size: M, L, XL: Adjustable length alloy kickstand\nCargo rack: AgileEon integrated rear rack, aluminum\nFender: AgileEon custom aluminum\n\nWeight\nWeight: M - 25.54 kg / 56.3 lbs\nWeight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 300 pounds (136 kg).\n\n## Sizing\n| Size |       Rider Height       |        Inseam        |\n|:----:|:------------------------:|:--------------------:|\n|   M  | 165 - 175 cm 5'5\" - 5'9\" | 77 - 83 cm 30\" - 33\" |\n|   L  | 175 - 186 cm 5'9\" - 6'1\" | 82 - 88 cm 32\" - 35\" |\n|  XL  | 186 - 197 cm 6'1\" - 6'6\" | 87 - 93 cm 34\" - 37\" |\n\n## Geometry\n| Frame size letter         |   M   |   L   |   XL  |\n|---------------------------|-------|-------|-------|\n| Wheel size                | 27.5\" | 27.5\" | 27.5\" |\n| A — Seat tube             | 44.6  | 49.1  | 53.4  |\n| B — Seat tube angle       | 73.0° | 73.0° | 73.0° |\n| C — Head tube length      | 16.5  | 19.5  | 23.0  |\n| D — Head angle            | 69.5° | 70.0° | 70.5° |\n| E — Effective top tube    | 59.5  | 60.7  | 62.2  |\n| F — Bottom bracket height | 29.5  | 29.5  | 29.5  |\n| G — Bottom bracket drop   | 6.0   | 6.0   | 6.0   |\n| H — Chainstay length      | 48.7  | 48.7  | 48.7  |\n| I — Offset                | 4.4   | 4.4   | 4.4   |\n| J — Trail                 | 8.6   | 8.1   | 7.9   |\n| K — Wheelbase             | 114.6 | 115.0 | 116.4 |\n| L — Standover             | 79.5  | 83.7  | 87.9  |\n| M — Frame reach           | 40.5  | 40.8  | 41.2  |\n| N — Frame stack           | 62.3  | 65.2  | 68.8  |",
    "price": 3499.99,
    "tags": [
      "bicycle",
      "road bike",
      "professional"
    ]
  },
  {
    "name": "Stealth R1X Pro",
    "shortDescription": "Stealth R1X Pro is a high-performance carbon road bike designed for riders who crave speed and exceptional handling. With its aerodynamic tube shaping, disc brakes, and lightweight carbon wheels, the Stealth R1X Pro offers unparalleled performance for competitive road cycling.",
    "description": "## Overview\nIt's right for you if...\nYou're a competitive cyclist looking for a road bike that offers superior performance in terms of speed, handling, and aerodynamics. You want a complete package that includes lightweight carbon wheels, without the need for future upgrades.\n\nThe tech you get\nThe Stealth R1X Pro features a lightweight and aerodynamic carbon frame, an advanced carbon fork, high-performance Shimano Ultegra 11-speed drivetrain, and powerful Ultegra disc brakes. The bike also comes equipped with cutting-edge Bontrager Aeolus Elite 35 carbon wheels.\n\nThe final word\nThe Stealth R1X Pro stands out with its combination of a fast and aerodynamic frame, high-end drivetrain, and top-of-the-line carbon wheels. Whether you're racing on local roads, participating in pro stage races, or engaging in hill climbing competitions, this bike is a formidable choice that delivers an exceptional riding experience.\n\n## Features\nSleek and aerodynamic design\nThe Stealth R1X Pro's aero tube shapes maximize speed and performance, making it faster on climbs and flats alike. The bike also features a streamlined Aeolus RSL bar/stem for improved front-end aerodynamics.\n\nDesigned for all riders\nThe Stealth R1X Pro is designed to provide an outstanding fit for riders of all genders, body types, riding styles, and abilities. It comes equipped with size-specific components to ensure a comfortable and efficient riding position for competitive riders.\n\n## Specifications\nFrameset\n- Frame: Ultralight carbon frame constructed with high-performance 500 Series ADV Carbon. It features Ride Tuned performance tube optimization, a tapered head tube, internal routing, DuoTrap S compatibility, flat mount disc brake mounts, and a 142x12mm thru axle.\n- Fork: Full carbon fork (Émonda SL) with a tapered carbon steerer, internal brake routing, flat mount disc brake mounts, and a 12x100mm thru axle.\n- Frame fit: H1.5 Race geometry.\n\nWheels\n- Front wheel: Bontrager Aeolus Elite 35 carbon wheel with a 35mm rim depth, ADV Carbon construction, Tubeless Ready compatibility, and a 100x12mm thru axle.\n- Rear wheel: Bontrager Aeolus Elite 35 carbon wheel with a 35mm rim depth, ADV Carbon construction, Tubeless Ready compatibility, Shimano 11/12-speed freehub, and a 142x12mm thru axle.\n- Front skewer: Bontrager Switch thru axle with a removable lever.\n- Rear skewer: Bontrager Switch thru axle with a removable lever.\n- Tire: Bontrager R2 Hard-Case Lite with an aramid bead, 60 tpi, and a size of 700x25c.\n- Maximum tire size: 28mm.\n\nDrivetrain\n- Shifter:\n  - Size 47, 50, 52: Shimano Ultegra R8025 with short-reach levers, 11-speed.\n  - Size 54, 56, 58, 60, 62: Shimano Ultegra R8020, 11-speed.\n- Front derailleur: Shimano Ultegra R8000, braze-on.\n- Rear derailleur: Shimano Ultegra R8000, short cage, with a maximum cog size of 30T.\n- Crank:\n  - Size 47: Shimano Ultegra R8000 with 52/36 chainrings and a 165mm length.\n  - Size 50, 52: Shimano Ultegra R8000 with 52/36 chainrings and a 170mm length.\n  - Size 54, 56, 58: Shimano Ultegra R8000 with 52/36 chainrings and a 172.5mm length.\n  - Size 60, 62: Shimano Ultegra R8000 with 52/36 chainrings and a 175mm length.\n- Bottom bracket: Praxis T47 threaded bottom bracket with internal bearings.\n- Cassette: Shimano Ultegra R8000, 11-30, 11-speed.\n- Chain: Shimano Ultegra HG701, 11-speed.\n- Maximum chainring size: 1x - 50T, 2x - 53/39.\n\nComponents\n- Saddle: Bontrager Aeolus Comp with steel rails and a width of 145mm.\n- Seatpost:\n  - Size 47, 50, 52, 54: Bontrager carbon seatmast cap with a 20mm offset and a short length.\n  - Size 56, 58, 60, 62: Bontrager carbon seatmast cap with a 20mm offset and a tall length.\n- Handlebar:\n  - Size 47, 50: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 38cm.\n  - Size 52: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 40cm.\n  - Size 54, 56, 58: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 42cm.\n  - Size 60, 62: Bontrager Elite VR-C alloy handlebar with a 31.8mm clamp, 100mm reach, 124mm drop, and a width of 44cm.\n- Handlebar tape: Bontrager Supertack Perf tape.\n- Stem:\n  - Size 47: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 70mm.\n  - Size 50: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 80mm.\n  - Size 52, 54: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 90mm.\n  - Size 56: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 100mm.\n  - Size 58, 60, 62: Bontrager Pro alloy stem with a 31.8mm clamp, Blendr compatibility, 7-degree rise, and a length of 110mm.\n- Brake: Shimano Ultegra hydraulic disc brakes with flat mount calipers.\n- Brake rotor: Shimano RT800 with centerlock mounting, 160mm diameter.\n\nWeight\n- Weight: 8.03 kg (17.71 lbs) for the 56cm frame.\n- Weight limit: The bike has a maximum total weight limit (combined weight of the bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\nPlease refer to the table below for the corresponding Stealth R1X Pro frame sizes, recommended rider height range, and inseam measurements:\n\n| Size |      Rider Height     |     Inseam     |\n|:----:|:---------------------:|:--------------:|\n|  47  |  152 - 158 cm (5'0\")  |  71 - 75 cm    |\n|  50  |  158 - 163 cm (5'2\")  |  74 - 77 cm    |\n|  52  |  163 - 168 cm (5'4\")  |  76 - 79 cm    |\n|  54  |  168 - 174 cm (5'6\")  |  78 - 82 cm    |\n|  56  | 174 - 180 cm (5'9\")  |  81 - 85 cm    |\n|  58  | 180 - 185 cm (5'11\") |  84 - 87 cm    |\n|  60  |  185 - 190 cm (6'1\")  |  86 - 90 cm    |\n|  62  |  190 - 195 cm (6'3\")  |  89 - 92 cm    |\n\n## Geometry\nThe table below provides the geometry measurements for each frame size of the Stealth R1X Pro:\n\n| Frame size number              | 47 cm | 50 cm | 52 cm | 54 cm | 56 cm | 58 cm | 60 cm | 62 cm |\n|-------------------------------|-------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size                    | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                 | 42.4  | 45.3  | 48.3  | 49.6  | 52.5  | 55.3  | 57.3  | 59.3  |\n| B — Seat tube angle           | 74.6° | 74.6° | 74.2° | 73.7° | 73.3° | 73.0° | 72.8° | 72.5° |\n| C — Head tube length          | 10.0  | 11.1  | 12.1  | 13.1  | 15.1  | 17.1  | 19.1  | 21.1  |\n| D — Head angle                | 72.1° | 72.1° | 72.8° | 73.0° | 73.5° | 73.8° | 73.9° | 73.9° |\n| E — Effective top tube        | 51.2  | 52.1  | 53.4  | 54.3  | 55.9  | 57.4  | 58.6  | 59.8  |\n| G — Bottom bracket drop       | 7.2   | 7.2   | 7.2   | 7.0   | 7.0   | 6.8   | 6.8   | 6.8   |\n| H — Chainstay length          | 41.0  | 41.0  | 41.0  | 41.0  | 41.0  | 41.1  | 41.1  | 41.2  |\n| I — Offset                    | 4.5   | 4.5   | 4.5   | 4.5   | 4.0   | 4.0   | 4.0   | 4.0   |\n| J — Trail                     | 6.8   | 6.2   | 5.8   | 5.6   | 5.8   | 5.7   | 5.6   | 5.6   |\n| K — Wheelbase                 | 97.2  | 97.4  | 97.7  | 98.1  | 98.3  | 99.2  | 100.1 | 101.0 |\n| L — Standover                 | 69.2  | 71.1  | 73.2  | 74.4  | 76.8  | 79.3  | 81.1  | 82.9  |\n| M — Frame reach               | 37.3  | 37.8  | 38.3  | 38.6  | 39.1  | 39.6  | 39.9  | 40.3  |\n| N — Frame stack               | 50.7  | 52.1  | 53.3  | 54.1  | 56.3  | 58.1  | 60.1  | 62.0  |\n| Saddle rail height min (short mast) | 55.5 | 58.5 | 61.5 | 64.0 | 67.0 | 69.0 | 71.0 | 73.0 |\n| Saddle rail height max (short mast) | 61.5 | 64.5 | 67.5 | 70.0 | 73.0 | 75.0 | 77.0 | 79.0 |\n| Saddle rail height min (tall mast)  | 59.0 | 62.0 | 65.0 | 67.5 | 70.5 | 72.5 | 74.5 | 76.5 |\n| Saddle rail height max (tall mast)  | 65.0 | 68.0 | 71.0 | 73.5 | 76.5 | 78.5 | 80.5 | 82.5 |",
    "price": 2999.99,
    "tags": [
      "bicycle",
      "mountain bike",
      "professional"
    ]
  },
  {
    "name": "Avant SLR 6 Disc Pro",
    "shortDescription": "Avant SLR 6 Disc Pro is a high-performance carbon road bike designed for riders who prioritize speed and handling. With its aero tube shaping, disc brakes, and lightweight carbon wheels, it offers the perfect balance of speed and control.",
    "description": "## Overview\nIt's right for you if...\nYou're a rider who values exceptional performance on fast group rides and races, and you want a complete package that includes lightweight carbon wheels. The Avant SLR 6 Disc Pro is designed to provide the speed and aerodynamics you need to excel on any road.\n\nThe tech you get\nThe Avant SLR 6 Disc Pro features a lightweight 500 Series ADV Carbon frame and fork, Bontrager Aeolus Elite 35 carbon wheels, a full Shimano Ultegra 11-speed drivetrain, and powerful Ultegra disc brakes.\n\nThe final word\nThe standout feature of this bike is the combination of its aero frame, high-performance drivetrain, and top-quality carbon wheels. Whether you're racing, tackling challenging climbs, or participating in professional stage races, the Avant SLR 6 Disc Pro is a worthy choice that will enhance your performance.\n\n## Features\nAll-new aero design\nThe Avant SLR 6 Disc Pro features innovative aero tube shapes that provide an advantage in all riding conditions, whether it's climbing or riding on flat roads. Additionally, it is equipped with a sleek new Aeolus RSL bar/stem that enhances front-end aero performance.\n\nAwesome bikes for everyone\nThe Avant SLR 6 Disc Pro is designed with the belief that every rider, regardless of gender, body type, riding style, or ability, deserves a great bike. It is equipped with size-specific components that ensure a perfect fit for competitive riders of all genders.\n\n## Specifications\nFrameset\n- Frame: Ultralight 500 Series ADV Carbon, Ride Tuned performance tube optimization, tapered head tube, internal routing, DuoTrap S compatible, flat mount disc, 142x12mm thru axle\n- Fork: Avant SL full carbon, tapered carbon steerer, internal brake routing, flat mount disc, 12x100mm thru axle\n- Frame fit: H1.5 Race\n\nWheels\n- Front wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, 100x12mm thru axle\n- Rear wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, Shimano 11/12-speed freehub, 142x12mm thru axle\n- Front skewer: Bontrager Switch thru axle, removable lever\n- Rear skewer: Bontrager Switch thru axle, removable lever\n- Tire: Bontrager R2 Hard-Case Lite, aramid bead, 60 tpi, 700x25c\n- Max tire size: 28mm\n\nDrivetrain\n- Shifter: \n    - Size 47, 50, 52: Shimano Ultegra R8025, short-reach lever, 11-speed\n    - Size 54, 56, 58, 60, 62: Shimano Ultegra R8020, 11-speed\n- Front derailleur: Shimano Ultegra R8000, braze-on\n- Rear derailleur: Shimano Ultegra R8000, short cage, 30T max cog\n- Crank: \n    - Size 47: Shimano Ultegra R8000, 52/36, 165mm length\n    - Size 50, 52: Shimano Ultegra R8000, 52/36, 170mm length\n    - Size 54, 56, 58: Shimano Ultegra R8000, 52/36, 172.5mm length\n    - Size 60, 62: Shimano Ultegra R8000, 52/36, 175mm length\n- Bottom bracket: Praxis, T47 threaded, internal bearing\n- Cassette: Shimano Ultegra R8000, 11-30, 11-speed\n- Chain: Shimano Ultegra HG701, 11-speed\n- Max chainring size: 1x: 50T, 2x: 53/39\n\nComponents\n- Saddle: Bontrager Aeolus Comp, steel rails, 145mm width\n- Seatpost: \n    - Size 47, 50, 52, 54: Bontrager carbon seatmast cap, 20mm offset, short length\n    - Size 56, 58, 60, 62: Bontrager carbon seatmast cap, 20mm offset, tall length\n- Handlebar: \n    - Size 47, 50: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 38cm width\n    - Size 52: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 40cm width\n    - Size 54, 56, 58: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 42cm width\n    - Size 60, 62: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 44cm width\n- Handlebar tape: Bontrager Supertack Perf tape\n- Stem: \n    - Size 47: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 70mm length\n    - Size 50: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 80mm length\n    - Size 52, 54: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 90mm length\n    - Size 56: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 100mm length\n    - Size 58, 60, 62: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 110mm length\n- Brake: Shimano Ultegra hydraulic disc, flat mount\n- Brake rotor: Shimano RT800, centerlock, 160mm\n\nWeight\n- Weight: 56 - 8.03 kg / 17.71 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  47  |  152 - 158 cm 5'0\" - 5'2\" | 71 - 75 cm 28\" - 30\" |\n|  50  |  158 - 163 cm 5'2\" - 5'4\" | 74 - 77 cm 29\" - 30\" |\n|  52  |  163 - 168 cm 5'4\" - 5'6\" | 76 - 79 cm 30\" - 31\" |\n|  54  |  168 - 174 cm 5'6\" - 5'9\" | 78 - 82 cm 31\" - 32\" |\n|  56  | 174 - 180 cm 5'9\" - 5'11\" | 81 - 85 cm 32\" - 33\" |\n|  58  | 180 - 185 cm 5'11\" - 6'1\" | 84 - 87 cm 33\" - 34\" |\n|  60  |  185 - 190 cm 6'1\" - 6'3\" | 86 - 90 cm 34\" - 35\" |\n|  62  |  190 - 195 cm 6'3\" - 6'5\" | 89 - 92 cm 35\" - 36\" |\n\n## Geometry\n| Frame size number                     | 47 cm | 50 cm | 52 cm | 54 cm | 56 cm | 58 cm | 60 cm | 62 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 42.4  | 45.3  | 48.3  | 49.6  | 52.5  | 55.3  | 57.3  | 59.3  |\n| B — Seat tube angle                   | 74.6° | 74.6° | 74.2° | 73.7° | 73.3° | 73.0° | 72.8° | 72.5° |\n| C — Head tube length                  | 10.0  | 11.1  | 12.1  | 13.1  | 15.1  | 17.1  | 19.1  | 21.1  |\n| D — Head angle                        | 72.1° | 72.1° | 72.8° | 73.0° | 73.5° | 73.8° | 73.9° | 73.9° |\n| E — Effective top tube                | 51.2  | 52.1  | 53.4  | 54.3  | 55.9  | 57.4  | 58.6  | 59.8  |\n| G — Bottom bracket drop               | 7.2   | 7.2   | 7.2   | 7.0   | 7.0   | 6.8   | 6.8   | 6.8   |\n| H — Chainstay length                  | 41.0  | 41.0  | 41.0  | 41.0  | 41.0  | 41.1  | 41.1  | 41.2  |\n| I — Offset                            | 4.5   | 4.5   | 4.5   | 4.5   | 4.0   | 4.0   | 4.0   | 4.0   |\n| J — Trail                             | 6.8   | 6.2   | 5.8   | 5.6   | 5.8   | 5.7   | 5.6   | 5.6   |\n| K — Wheelbase                         | 97.2  | 97.4  | 97.7  | 98.1  | 98.3  | 99.2  | 100.1 | 101.0 |\n| L — Standover                         | 69.2  | 71.1  | 73.2  | 74.4  | 76.8  | 79.3  | 81.1  | 82.9  |\n| M — Frame reach                       | 37.3  | 37.8  | 38.3  | 38.6  | 39.1  | 39.6  | 39.9  | 40.3  |\n| N — Frame stack                       | 50.7  | 52.1  | 53.3  | 54.1  | 56.3  | 58.1  | 60.1  | 62.0  |\n| Saddle rail height min (w/short mast) | 55.5  | 58.5  | 61.5  | 64.0  | 67.0  | 69.0  | 71.0  | 73.0  |\n| Saddle rail height max (w/short mast) | 61.5  | 64.5  | 67.5  | 70.0  | 73.0  | 75.0  | 77.0  | 79.0  |\n| Saddle rail height min (w/tall mast)  | 59.0  | 62.0  | 65.0  | 67.5  | 70.5  | 72.5  | 74.5  | 76.5  |\n| Saddle rail height max (w/tall mast)  | 65.0  | 68.0  | 71.0  | 73.5  | 76.5  | 78.5  | 80.5  | 82.5  |",
    "price": 999.99,
    "tags": [
      "bicycle",
      "city bike",
      "professional"
    ]
  }
]

---

### Spring Ai Commons/Src/Test/Resources/Events.Json (spring-ai-commons/src/test/resources/events.json)

[
  {
    "sessions": [
      {
        "description": "Session one"
      },
      {
        "description": "Session two"
      },
      {
        "description": "Session three"
      }
    ]
  }
]

---

### Spring Ai Commons/Src/Test/Resources/Person.Json (spring-ai-commons/src/test/resources/person.json)

{
  "name": "Avant SLR 6 Disc Pro",
  "shortDescription": "Avant SLR 6 Disc Pro is a high-performance carbon road bike designed for riders who prioritize speed and handling. With its aero tube shaping, disc brakes, and lightweight carbon wheels, it offers the perfect balance of speed and control.",
  "description": "## Overview\nIt's right for you if...\nYou're a rider who values exceptional performance on fast group rides and races, and you want a complete package that includes lightweight carbon wheels. The Avant SLR 6 Disc Pro is designed to provide the speed and aerodynamics you need to excel on any road.\n\nThe tech you get\nThe Avant SLR 6 Disc Pro features a lightweight 500 Series ADV Carbon frame and fork, Bontrager Aeolus Elite 35 carbon wheels, a full Shimano Ultegra 11-speed drivetrain, and powerful Ultegra disc brakes.\n\nThe final word\nThe standout feature of this bike is the combination of its aero frame, high-performance drivetrain, and top-quality carbon wheels. Whether you're racing, tackling challenging climbs, or participating in professional stage races, the Avant SLR 6 Disc Pro is a worthy choice that will enhance your performance.\n\n## Features\nAll-new aero design\nThe Avant SLR 6 Disc Pro features innovative aero tube shapes that provide an advantage in all riding conditions, whether it's climbing or riding on flat roads. Additionally, it is equipped with a sleek new Aeolus RSL bar/stem that enhances front-end aero performance.\n\nAwesome bikes for everyone\nThe Avant SLR 6 Disc Pro is designed with the belief that every rider, regardless of gender, body type, riding style, or ability, deserves a great bike. It is equipped with size-specific components that ensure a perfect fit for competitive riders of all genders.\n\n## Specifications\nFrameset\n- Frame: Ultralight 500 Series ADV Carbon, Ride Tuned performance tube optimization, tapered head tube, internal routing, DuoTrap S compatible, flat mount disc, 142x12mm thru axle\n- Fork: Avant SL full carbon, tapered carbon steerer, internal brake routing, flat mount disc, 12x100mm thru axle\n- Frame fit: H1.5 Race\n\nWheels\n- Front wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, 100x12mm thru axle\n- Rear wheel: Bontrager Aeolus Elite 35, ADV Carbon, Tubeless Ready, 35mm rim depth, Shimano 11/12-speed freehub, 142x12mm thru axle\n- Front skewer: Bontrager Switch thru axle, removable lever\n- Rear skewer: Bontrager Switch thru axle, removable lever\n- Tire: Bontrager R2 Hard-Case Lite, aramid bead, 60 tpi, 700x25c\n- Max tire size: 28mm\n\nDrivetrain\n- Shifter: \n    - Size 47, 50, 52: Shimano Ultegra R8025, short-reach lever, 11-speed\n    - Size 54, 56, 58, 60, 62: Shimano Ultegra R8020, 11-speed\n- Front derailleur: Shimano Ultegra R8000, braze-on\n- Rear derailleur: Shimano Ultegra R8000, short cage, 30T max cog\n- Crank: \n    - Size 47: Shimano Ultegra R8000, 52/36, 165mm length\n    - Size 50, 52: Shimano Ultegra R8000, 52/36, 170mm length\n    - Size 54, 56, 58: Shimano Ultegra R8000, 52/36, 172.5mm length\n    - Size 60, 62: Shimano Ultegra R8000, 52/36, 175mm length\n- Bottom bracket: Praxis, T47 threaded, internal bearing\n- Cassette: Shimano Ultegra R8000, 11-30, 11-speed\n- Chain: Shimano Ultegra HG701, 11-speed\n- Max chainring size: 1x: 50T, 2x: 53/39\n\nComponents\n- Saddle: Bontrager Aeolus Comp, steel rails, 145mm width\n- Seatpost: \n    - Size 47, 50, 52, 54: Bontrager carbon seatmast cap, 20mm offset, short length\n    - Size 56, 58, 60, 62: Bontrager carbon seatmast cap, 20mm offset, tall length\n- Handlebar: \n    - Size 47, 50: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 38cm width\n    - Size 52: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 40cm width\n    - Size 54, 56, 58: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 42cm width\n    - Size 60, 62: Bontrager Elite VR-C, alloy, 31.8mm, 100mm reach, 124mm drop, 44cm width\n- Handlebar tape: Bontrager Supertack Perf tape\n- Stem: \n    - Size 47: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 70mm length\n    - Size 50: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 80mm length\n    - Size 52, 54: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 90mm length\n    - Size 56: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 100mm length\n    - Size 58, 60, 62: Bontrager Pro, 31.8mm, Blendr compatible, 7-degree, 110mm length\n- Brake: Shimano Ultegra hydraulic disc, flat mount\n- Brake rotor: Shimano RT800, centerlock, 160mm\n\nWeight\n- Weight: 56 - 8.03 kg / 17.71 lbs\n- Weight limit: This bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 275 pounds (125 kg).\n\n## Sizing\n| Size |        Rider Height       |        Inseam        |\n|:----:|:-------------------------:|:--------------------:|\n|  47  |  152 - 158 cm 5'0\" - 5'2\" | 71 - 75 cm 28\" - 30\" |\n|  50  |  158 - 163 cm 5'2\" - 5'4\" | 74 - 77 cm 29\" - 30\" |\n|  52  |  163 - 168 cm 5'4\" - 5'6\" | 76 - 79 cm 30\" - 31\" |\n|  54  |  168 - 174 cm 5'6\" - 5'9\" | 78 - 82 cm 31\" - 32\" |\n|  56  | 174 - 180 cm 5'9\" - 5'11\" | 81 - 85 cm 32\" - 33\" |\n|  58  | 180 - 185 cm 5'11\" - 6'1\" | 84 - 87 cm 33\" - 34\" |\n|  60  |  185 - 190 cm 6'1\" - 6'3\" | 86 - 90 cm 34\" - 35\" |\n|  62  |  190 - 195 cm 6'3\" - 6'5\" | 89 - 92 cm 35\" - 36\" |\n\n## Geometry\n| Frame size number                     | 47 cm | 50 cm | 52 cm | 54 cm | 56 cm | 58 cm | 60 cm | 62 cm |\n|---------------------------------------|-------|-------|-------|-------|-------|-------|-------|-------|\n| Wheel size                            | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  | 700c  |\n| A — Seat tube                         | 42.4  | 45.3  | 48.3  | 49.6  | 52.5  | 55.3  | 57.3  | 59.3  |\n| B — Seat tube angle                   | 74.6° | 74.6° | 74.2° | 73.7° | 73.3° | 73.0° | 72.8° | 72.5° |\n| C — Head tube length                  | 10.0  | 11.1  | 12.1  | 13.1  | 15.1  | 17.1  | 19.1  | 21.1  |\n| D — Head angle                        | 72.1° | 72.1° | 72.8° | 73.0° | 73.5° | 73.8° | 73.9° | 73.9° |\n| E — Effective top tube                | 51.2  | 52.1  | 53.4  | 54.3  | 55.9  | 57.4  | 58.6  | 59.8  |\n| G — Bottom bracket drop               | 7.2   | 7.2   | 7.2   | 7.0   | 7.0   | 6.8   | 6.8   | 6.8   |\n| H — Chainstay length                  | 41.0  | 41.0  | 41.0  | 41.0  | 41.0  | 41.1  | 41.1  | 41.2  |\n| I — Offset                            | 4.5   | 4.5   | 4.5   | 4.5   | 4.0   | 4.0   | 4.0   | 4.0   |\n| J — Trail                             | 6.8   | 6.2   | 5.8   | 5.6   | 5.8   | 5.7   | 5.6   | 5.6   |\n| K — Wheelbase                         | 97.2  | 97.4  | 97.7  | 98.1  | 98.3  | 99.2  | 100.1 | 101.0 |\n| L — Standover                         | 69.2  | 71.1  | 73.2  | 74.4  | 76.8  | 79.3  | 81.1  | 82.9  |\n| M — Frame reach                       | 37.3  | 37.8  | 38.3  | 38.6  | 39.1  | 39.6  | 39.9  | 40.3  |\n| N — Frame stack                       | 50.7  | 52.1  | 53.3  | 54.1  | 56.3  | 58.1  | 60.1  | 62.0  |\n| Saddle rail height min (w/short mast) | 55.5  | 58.5  | 61.5  | 64.0  | 67.0  | 69.0  | 71.0  | 73.0  |\n| Saddle rail height max (w/short mast) | 61.5  | 64.5  | 67.5  | 70.0  | 73.0  | 75.0  | 77.0  | 79.0  |\n| Saddle rail height min (w/tall mast)  | 59.0  | 62.0  | 65.0  | 67.5  | 70.5  | 72.5  | 74.5  | 76.5  |\n| Saddle rail height max (w/tall mast)  | 65.0  | 68.0  | 71.0  | 73.5  | 76.5  | 78.5  | 80.5  | 82.5  |",
  "price": 999.99,
  "tags": [
    "bicycle",
    "city bike",
    "professional"
  ],
  "store": {
    "name": "Bike Shop",
    "location": {
      "city": "San Francisco",
      "state": "CA",
      "address": {
        "street": "123 Market St",
        "zipcode": "94103"
      }
    },
    "products": [
      {
        "name": "Avant SLR 6 Disc Pro",
        "price": 999.99,
        "tags": [
          "bicycle",
          "city bike",
          "professional"
        ],
        "details": {
          "weight": "7.5kg",
          "color": "red"
        }
      },
      {
        "name": "Mountain Master 3000",
        "price": 1299.99,
        "tags": [
          "bicycle",
          "mountain bike",
          "professional"
        ],
        "details": {
          "weight": "9kg",
          "color": "blue"
        }
      }
    ]
  },
  "employees": [
    {
      "name": "John Doe",
      "role": "Manager"
    },
    {
      "name": "Jane Smith",
      "role": "Sales"
    }
  ]
}

---

### Spring Ai Commons/Src/Test/Resources/Text Source (spring-ai-commons/src/test/resources/text_source.txt)

Spring                 Framework                               Documentation


                                                                                                                        Version    6.0.0

            Chapter                1.    Spring              Framework                         Overview


            Spring makes it easy to create Java enterprise applications. It provides everything you need to
            embrace    the  Java   language    in  an  enterprise    environment,      with   support   for  Groovy    and   Kotlin   as
            alternative languages on the JVM, and with the flexibility to create many kinds of architectures
            depending     on  an  application’s    needs.  As  of  Spring   Framework      5.1, Spring   requires    JDK  8+  (Java  SE
            8+) and provides out-of-the-box support for JDK 11 LTS. Java SE 8 update 60 is suggested as the
            minimum      patch  release   for Java  8, but  it is  generally  recommended       to  use a  recent  patch   release.

            Spring  supports    a wide   range   of application    scenarios.   In  a large  enterprise,   applications    often  exist
            for a  long  time   and   have   to run   on  a  JDK  and   application    server   whose    upgrade     cycle  is beyond
            developer    control.   Others   may    run  as  a single   jar with   the  server   embedded,      possibly   in  a cloud
            environment.      Yet others   may    be standalone     applications    (such   as  batch   or integration    workloads)
            that do  not  need   a server.


            Spring  is open   source.   It  has  a large  and active  community      that  provides   continuous     feedback    based
            on a  diverse   range  of  real-world   use  cases.  This  has  helped    Spring  to  successfully   evolve   over  a  very
            long  time.

            1.1.    What          We      Mean          by    "Spring"


            The  term   "Spring"   means    different   things  in  different   contexts.  It can  be  used   to refer  to the  Spring
            Framework      project   itself,  which  is where    it  all  started.  Over time,  other  Spring   projects   have   been
            built on  top  of  the Spring    Framework.      Most   often,  when    people   say  "Spring",   they  mean    the  entire
            family  of  projects.  This  reference    documentation       focuses   on  the foundation:     the  Spring   Framework
            itself.


            The  Spring   Framework      is divided   into  modules.    Applications     can  choose   which    modules    they  need.
            At the heart are the modules of the core container, including a configuration model and a
            dependency injection mechanism. Beyond that, the Spring Framework provides foundational
            support    for   different    application     architectures,     including    messaging,      transactional     data   and
            persistence, and web. It also includes the Servlet-based Spring MVC web framework and, in
            parallel, the  Spring   WebFlux     reactive   web   framework.


            A note about modules: Spring’s framework jars allow for deployment to JDK 9’s module path
            ("Jigsaw"). For use in Jigsaw-enabled applications, the Spring Framework 5 jars come with
            "Automatic-Module-Name" manifest entries which define stable language-level module names
            ("spring.core",   "spring.context",     etc.) independent     from    jar artifact  names    (the  jars follow   the  same
            naming    pattern   with   "-" instead   of  ".",  e.g.  "spring-core"  and   "spring-context").    Of  course,   Spring’s
            framework     jars  keep  working    fine  on  the  classpath   on  both  JDK  8  and  9+.

            1.2.    History            of   Spring          and       the      Spring          Framework


            Spring came into being in 2003 as a response to the complexity of the early J2EE specifications.
            While   some    consider   Java   EE  and   its modern-day      successor    Jakarta   EE  to  be  in  competition     with
            Spring, they are in fact complementary. The Spring programming model does not embrace the
            Jakarta    EE   platform      specification;    rather,    it  integrates     with    carefully    selected    individual

            specifications   from   the  traditional   EE  umbrella:


              • Servlet  API   (JSR 340)

              • WebSocket     API  (JSR  356)

              • Concurrency      Utilities (JSR  236)

              • JSON   Binding    API  (JSR 367)

              • Bean   Validation   (JSR  303)

              • JPA  (JSR  338)

              • JMS   (JSR 914)

              • as well  as  JTA/JCA   setups  for  transaction    coordination,    if necessary.


            The  Spring   Framework      also  supports    the Dependency       Injection   (JSR 330)  and   Common      Annotations
            (JSR 250) specifications, which application developers may choose to use instead of the Spring-
            specific  mechanisms      provided     by the  Spring   Framework.       Originally,  those   were   based   on  common
            javax  packages.

            As  of Spring   Framework       6.0, Spring   has  been   upgraded     to  the Jakarta   EE   9 level  (e.g. Servlet   5.0+,
            JPA  3.0+), based    on  the  jakarta   namespace      instead   of the  traditional   javax   packages.    With   EE  9  as
            the  minimum      and   EE  10  supported     already,   Spring   is prepared     to provide    out-of-the-box     support
            for the further evolution of the Jakarta EE APIs. Spring Framework 6.0 is fully compatible with
            Tomcat   10.1,  Jetty 11  and  Undertow     2.3  as web   servers,   and  also  with  Hibernate    ORM    6.1.


            Over   time,  the role  of  Java/Jakarta    EE  in application    development      has  evolved.    In the  early  days   of
            J2EE  and   Spring,  applications    were   created   to  be deployed     to an  application    server.  Today,   with  the
            help  of Spring   Boot,   applications    are  created   in a  devops-   and   cloud-friendly     way,  with   the  Servlet
            container   embedded      and   trivial  to change.   As  of  Spring   Framework      5, a  WebFlux     application    does
            not  even   use  the  Servlet   API  directly   and   can  run   on  servers   (such   as  Netty)  that  are  not   Servlet
            containers.


            Spring  continues    to  innovate   and   to evolve.  Beyond     the Spring   Framework,      there  are  other   projects,
            such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch, among others. It’s
            important to remember that each project has its own source code repository, issue tracker, and
            release  cadence.    See  spring.io/projects    for the  complete    list of Spring   projects.

            1.3.    Design           Philosophy


            When you learn about a framework, it’s important to know not only what it does but what
            principles   it  follows. Here  are  the  guiding   principles   of the  Spring   Framework:


              • Provide choice at every level. Spring lets you defer design decisions as late as possible. For
                example, you can switch persistence providers through configuration without changing your
                code.  The   same   is true  for  many   other   infrastructure     concerns    and  integration    with  third-party
                APIs.

              • Accommodate diverse perspectives. Spring embraces flexibility and is not opinionated about
                how things should be done. It supports a wide range of application needs with different
                perspectives.

              • Maintain strong backward compatibility. Spring’s evolution has been carefully managed to
                force  few   breaking    changes    between    versions.   Spring    supports   a  carefully   chosen   range   of  JDK
                versions and third-party libraries to facilitate maintenance of applications and libraries that
                depend    on  Spring.

              • Care   about  API   design.  The  Spring   team   puts   a lot of thought   and   time  into  making    APIs  that  are
                intuitive  and   that  hold  up  across  many    versions   and   many    years.

              • Set high standards for code quality. The Spring Framework puts a strong emphasis on
                meaningful,     current,   and   accurate    javadoc.   It is one   of very   few  projects   that  can   claim   clean
                code   structure   with  no  circular   dependencies     between     packages.

            1.4.    Feedback               and       Contributions


            For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click
            here  for  a list of the  suggested    tags  to use  on  Stack   Overflow.    If  you’re fairly  certain   that there   is a
            problem    in the  Spring   Framework      or would    like to suggest   a feature,   please  use  the  GitHub    Issues.

            If you have a solution in mind or a suggested fix, you can submit a pull request on Github.
            However,    please   keep   in mind    that, for  all but  the  most   trivial issues,  we  expect   a  ticket to  be  filed
            in the issue  tracker,   where   discussions    take  place  and   leave  a record   for  future  reference.


            For more    details  see the  guidelines    at the CONTRIBUTING,         top-level  project  page.

            1.5.    Getting           Started


            If  you are  just getting   started   with  Spring,   you  may    want   to begin   using   the  Spring   Framework      by
            creating a Spring Boot-based application. Spring Boot provides a quick (and opinionated) way to
            create a production-ready Spring-based application. It is based on the Spring Framework, favors
            convention    over   configuration,    and  is designed    to get  you  up  and  running    as  quickly  as  possible.


            You  can  use  start.spring.io    to generate    a basic  project   or follow   one  of  the  "Getting   Started"  guides,
            such as Getting Started Building a RESTful Web Service. As well as being easier to digest, these
            guides   are  very   task  focused,   and   most   of them    are  based   on   Spring   Boot.  They   also   cover   other
            projects from the Spring portfolio that you might want to consider when solving a particular
            problem.

            Chapter                2.    Core           Technologies


            This  part  of the  reference    documentation       covers   all  the  technologies   that  are  absolutely   integral   to
            the Spring   Framework.


            Foremost    amongst    these   is  the  Spring Framework’s      Inversion    of Control   (IoC)  container.   A  thorough
            treatment    of the  Spring   Framework’s      IoC  container    is closely  followed    by  comprehensive       coverage
            of Spring’s   Aspect-Oriented      Programming        (AOP)   technologies.    The   Spring   Framework       has  its own
            AOP framework, which is conceptually easy to understand and which successfully addresses the
            80%   sweet  spot  of AOP   requirements      in Java   enterprise   programming.


            Coverage of Spring’s integration with AspectJ (currently the richest — in terms of features — and
            certainly  most   mature    AOP   implementation       in the  Java  enterprise   space)   is also provided.


            AOT processing can be used to optimize your application ahead-of-time. It is typically used for
            native  image   deployment      using  GraalVM.

            2.1.    The       IoC      Container


            This  chapter   covers   Spring’s  Inversion    of Control   (IoC)  container.


            2.1.1.   Introduction          to  the   Spring      IoC   Container        and    Beans

            This chapter covers the Spring Framework implementation of the Inversion of Control (IoC)
            principle. IoC is also known as dependency injection (DI). It is a process whereby objects define
            their dependencies      (that  is, the other   objects   they  work   with)   only  through    constructor    arguments,
            arguments to a factory method, or properties that are set on the object instance after it is
            constructed or returned from a factory method. The container then injects those dependencies
            when   it creates   the  bean.  This   process   is fundamentally      the  inverse   (hence   the  name,    Inversion    of
            Control) of the bean itself controlling the instantiation or location of its dependencies by using
            direct  construction    of classes  or  a mechanism      such   as the  Service  Locator    pattern.


            The  org.springframework.beans         and   org.springframework.context         packages     are  the  basis  for  Spring
            Framework’s       IoC   container.     The   BeanFactory      interface    provides     an   advanced      configuration
            mechanism capable of managing any type of object. ApplicationContext is a sub-interface of
            BeanFactory.   It adds:


              • Easier   integration   with  Spring’s   AOP   features

              • Message    resource    handling    (for use  in internationalization)

              • Event   publication

              • Application-layer       specific    contexts    such     as  the    WebApplicationContext         for   use   in   web
                applications.


            In short, the BeanFactory provides the configuration framework and basic functionality, and the
            ApplicationContext       adds    more     enterprise-specific      functionality.     The    ApplicationContext        is  a
            complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of
            Spring’s    IoC   container.     For    more     information      on    using    the   BeanFactory      instead    of   the

            ApplicationContext,      see  the  section  covering    the BeanFactory    API.


            In Spring, the objects that form the backbone of your application and that are managed by the
            Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and
            managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your
            application.   Beans,   and   the dependencies      among     them,   are  reflected   in the  configuration    metadata
            used  by  a container.


            2.1.2.   Container        Overview

            The  org.springframework.context.ApplicationContext                interface   represents    the  Spring   IoC  container
            and  is responsible     for instantiating,    configuring,    and   assembling     the  beans.   The  container    gets  its
            instructions on what objects to instantiate, configure, and assemble by reading configuration
            metadata.    The  configuration     metadata     is  represented   in  XML,   Java  annotations,    or  Java  code.  It lets
            you express the objects that compose your application and the rich interdependencies between
            those  objects.


            Several implementations of the ApplicationContext interface are supplied with Spring. In stand-
            alone applications, it is common to create an instance of ClassPathXmlApplicationContext or
            FileSystemXmlApplicationContext.           While     XML     has   been     the   traditional    format     for   defining
            configuration metadata, you can instruct the container to use Java annotations or code as the
            metadata    format   by  providing    a small   amount    of XML    configuration    to  declaratively   enable    support
            for these  additional    metadata    formats.


            In most application scenarios, explicit user code is not required to instantiate one or more
            instances   of a  Spring   IoC  container.    For  example,    in a  web   application    scenario,   a simple   eight   (or
            so) lines  of boilerplate    web   descriptor    XML    in the  web.xml    file of the  application    typically   suffices
            (see Convenient     ApplicationContext       Instantiation    for Web    Applications).    If you  use  the  Spring   Tools
            for Eclipse   (an  Eclipse-powered       development      environment),      you   can  easily  create   this  boilerplate
            configuration    with   a few  mouse    clicks  or keystrokes.


            The  following    diagram    shows    a high-level    view   of how   Spring    works.   Your   application    classes  are
            combined with configuration metadata so that, after the ApplicationContext is created and
            initialized,  you  have   a fully configured    and   executable    system   or  application.

            Figure  1.  The  Spring IoC container


            Configuration      Metadata

            As the preceding diagram shows, the Spring IoC container consumes a form of configuration
            metadata. This configuration metadata represents how you, as an application developer, tell the
            Spring  container    to instantiate,   configure,   and   assemble    the  objects  in your   application.


            Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is
            what   most  of  this chapter   uses  to convey    key  concepts    and  features   of the  Spring   IoC container.


                              XML-based     metadata     is not  the  only  allowed    form   of configuration     metadata.     The
                              Spring IoC container itself is totally decoupled from the format in which this
                             configuration metadata is actually written. These days, many developers choose
                              Java-based    configuration    for  their  Spring  applications.


            For information     about   using   other  forms   of metadata     with  the  Spring   container,   see:


              • Annotation-based         configuration:       Spring     2.5   introduced      support      for   annotation-based
                configuration     metadata.

              • Java-based configuration: Starting with Spring 3.0, many features provided by the Spring
                JavaConfig project became part of the core Spring Framework. Thus, you can define beans
                external to your application classes by using Java rather than XML files. To use these new
                features,   see the  @Configuration,     @Bean,  @Import,  and   @DependsOn   annotations.

            Spring   configuration     consists  of  at least  one   and  typically   more    than  one   bean   definition   that  the
            container must manage. XML-based configuration metadata configures these beans as <bean/>
            elements inside a top-level <beans/> element. Java configuration typically uses @Bean-annotated
            methods    within   a @Configuration     class.

            These   bean   definitions    correspond     to the  actual   objects   that  make   up   your   application.   Typically,
            you define service layer objects, data access objects (DAOs), presentation objects such as Struts
            Action instances, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so
            forth. Typically,   one   does  not  configure    fine-grained     domain    objects   in the  container,    because    it  is

            usually   the responsibility    of  DAOs   and   business    logic  to create  and   load  domain     objects.  However,
            you  can   use  Spring’s   integration    with  AspectJ    to configure    objects   that  have   been   created   outside
            the control   of an  IoC  container.   See  Using   AspectJ   to dependency-inject      domain     objects  with  Spring.


            The  following   example     shows   the  basic  structure   of XML-based      configuration     metadata:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="..."    class="...">      ①   ②
                         
                    </bean>


                    <bean   id="..."    class="...">
                         
                    </bean>


                    


              </beans>


            ① The    id attribute   is a string  that identifies   the individual    bean   definition.

            ② The    class  attribute   defines   the type  of the  bean   and  uses   the fully  qualified   classname.

            The  value   of the  id attribute   refers   to collaborating    objects.  The   XML    for referring   to  collaborating
            objects  is not shown    in  this example.    See  Dependencies      for more    information.


            Instantiating    a  Container

            The  location   path   or paths   supplied    to an  ApplicationContext       constructor    are  resource    strings  that
            let  the  container  load  configuration     metadata    from   a variety   of external   resources,    such  as  the local
            file  system, the  Java  CLASSPATH,   and   so on.


            Java


              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");



            Kotlin


              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")

                              After  you  learn   about   Spring’s   IoC  container,    you   may   want   to  know   more    about
                              Spring’s   Resource     abstraction     (as  described     in  Resources),     which     provides     a
                             convenient mechanism for reading an InputStream from locations defined in a
                              URI syntax. In particular, Resource paths are used to construct applications
                              contexts,  as  described    in Application    Contexts   and   Resource    Paths.


            The  following   example     shows   the  service   layer  objects  (services.xml)     configuration     file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    


                    <bean   id="petStore"
              class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
                         <property     name="accountDao"        ref="accountDao"/>
                         <property     name="itemDao"       ref="itemDao"/>
                         
                    </bean>


                    


              </beans>



            The  following   example     shows   the  data  access   objects  daos.xml   file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="accountDao"
                         class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
                         
                    </bean>


                    <bean   id="itemDao"
              class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
                         
                    </bean>


                    


              </beans>

            In the  preceding    example,     the  service  layer   consists  of  the  PetStoreServiceImpl       class and   two   data
            access objects of the types JpaAccountDao and JpaItemDao (based on the JPA Object-Relational
            Mapping    standard).    The  property    name  element    refers  to the  name   of  the JavaBean     property,   and  the
            ref element refers to the name of another bean definition. This linkage between id and ref
            elements expresses the dependency between collaborating objects. For details of configuring an
            object’s  dependencies,     see  Dependencies.



            Composing    XML-based    Configuration   Metadata

            It can be useful to have bean definitions span multiple XML files. Often, each individual XML
            configuration    file represents    a logical  layer  or module     in your  architecture.


            You can use the application context constructor to load bean definitions from all these XML
            fragments.    This  constructor    takes  multiple   Resource   locations,   as was   shown    in the  previous    section.
            Alternatively,   use  one   or more    occurrences     of the  <import/>    element    to load   bean   definitions   from
            another   file or files. The  following    example    shows    how   to do  so:



              <beans>
                    <import    resource="services.xml"/>
                    <import    resource="resources/messageSource.xml"/>
                    <import    resource="/resources/themeSource.xml"/>


                    <bean   id="bean1"     class="..."/>
                    <bean   id="bean2"     class="..."/>
              </beans>



            In the preceding example, external bean definitions are loaded from three files: services.xml,
            messageSource.xml,      and  themeSource.xml.      All location   paths   are   relative  to  the  definition   file doing
            the importing,    so  services.xml    must    be in  the same    directory   or  classpath   location   as  the file doing
            the importing,     while  messageSource.xml       and  themeSource.xml      must   be  in  a resources    location   below
            the  location   of the  importing     file.  As  you can  see,  a leading    slash  is ignored.   However,     given   that
            these  paths   are  relative,  it is better  form   not  to  use  the  slash  at all. The  contents    of the  files being
            imported,    including   the  top  level  <beans/>   element,    must   be  valid  XML    bean   definitions,   according
            to the Spring   Schema.

                              It  is  possible,  but  not  recommended,     to reference    files in parent   directories   using   a
                              relative "../" path. Doing so creates a dependency on a file that is outside the
                              current    application.     In   particular,    this   reference     is  not   recommended          for
                              classpath: URLs (for example, classpath:../services.xml), where the runtime
                              resolution process chooses the “nearest” classpath root and then looks into its
                              parent directory. Classpath configuration changes may lead to the choice of a
                              different,  incorrect   directory.
                
                              You  can  always    use  fully qualified    resource   locations   instead   of  relative  paths:   for
                              example,        file:C:/config/services.xml             or     classpath:/config/services.xml.
                              However, be aware that you are coupling your application’s configuration to
                              specific  absolute   locations.   It  is  generally  preferable  to keep   an indirection    for such
                              absolute locations — for example, through "${…}" placeholders that are resolved
                              against  JVM   system   properties    at runtime.


            The  namespace      itself provides    the  import   directive   feature.  Further    configuration     features   beyond
            plain bean definitions are available in a selection of XML namespaces provided by Spring — for
            example,    the context   and   util  namespaces.



            The Groovy   Bean   Definition  DSL

            As a further example for externalized configuration metadata, bean definitions can also be
            expressed    in Spring’s   Groovy    Bean   Definition    DSL,  as known     from   the  Grails  framework.     Typically,
            such  configuration     live in a ".groovy"    file  with the structure   shown    in  the following    example:



              beans    {
                    dataSource(BasicDataSource)           {
                         driverClassName       =  "org.hsqldb.jdbcDriver"
                         url   =  "jdbc:hsqldb:mem:grailsDB"
                         username     = "sa"
                         password     = ""
                         settings     = [mynew:"setting"]
                    }
                    sessionFactory(SessionFactory)            {
                         dataSource     =  dataSource
                    }
                    myService(MyService)         {
                         nestedBean     =  {  AnotherBean     bean   ->
                               dataSource     =  dataSource
                         }
                    }
              }



            This  configuration     style  is largely  equivalent     to XML    bean   definitions    and  even   supports    Spring’s
            XML   configuration     namespaces.      It also  allows   for importing     XML    bean   definition   files through    an
            importBeans    directive.

            Using   the  Container

            The  ApplicationContext      is the  interface   for an  advanced     factory  capable    of maintaining     a registry   of
            different beans and their dependencies. By using the method T getBean(String name, Class<T>
            requiredType),    you  can  retrieve   instances   of  your  beans.

            The  ApplicationContext       lets you   read   bean   definitions   and   access   them,   as  the  following    example
            shows:


            Java


              //  create    and   configure    beans
              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");


              //  retrieve     configured     instance
              PetStoreService       service    =  context.getBean("petStore",            PetStoreService.class);


              //  use   configured     instance
              List<String>      userList     = service.getUsernameList();



            Kotlin


              import    org.springframework.beans.factory.getBean


              //  create    and   configure    beans
              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")


              //  retrieve     configured     instance
              val   service    =  context.getBean<PetStoreService>("petStore")


              //  use   configured     instance
              var   userList    =  service.getUsernameList()



            With    Groovy     configuration,      bootstrapping       looks    very    similar.   It  has    a   different    context
            implementation class which is Groovy-aware (but also understands XML bean definitions). The
            following   example    shows    Groovy    configuration:


            Java


              ApplicationContext        context    =  new   GenericGroovyApplicationContext("services.groovy",
              "daos.groovy");



            Kotlin


              val   context    =  GenericGroovyApplicationContext("services.groovy",                    "daos.groovy")



            The  most   flexible  variant   is GenericApplicationContext         in  combination     with   reader   delegates — for
            example,    with  XmlBeanDefinitionReader        for XML    files,  as  the  following example    shows:

            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml")
              context.refresh()



            You  can  also  use  the GroovyBeanDefinitionReader         for Groovy    files, as the  following   example     shows:


            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy")
              context.refresh()



            You can mix and match such reader delegates on the same ApplicationContext, reading bean
            definitions   from   diverse  configuration     sources.


            You  can  then  use  getBean   to retrieve   instances    of your  beans.   The  ApplicationContext       interface   has  a
            few  other   methods    for  retrieving   beans,   but,  ideally, your   application    code   should   never   use  them.
            Indeed,   your  application    code   should   have   no  calls to  the getBean()    method    at  all  and thus  have   no
            dependency      on Spring   APIs   at all.  For  example,  Spring’s   integration    with  web   frameworks      provides
            dependency     injection   for  various   web   framework     components      such   as controllers    and  JSF-managed
            beans, letting you declare a dependency on a specific bean through metadata (such as an
            autowiring    annotation).


            2.1.3.   Bean     Overview

            A Spring   IoC  container    manages    one   or more    beans.  These   beans   are  created   with   the configuration
            metadata    that  you  supply   to the  container    (for example,    in the  form   of XML   <bean/>   definitions).


            Within   the  container    itself,  these bean   definitions   are  represented     as BeanDefinition     objects,   which
            contain   (among    other  information)     the  following   metadata:

              • A package-qualified class name: typically, the actual implementation class of the bean being

                defined.

              • Bean behavioral configuration elements, which state how the bean should behave in the
                container    (scope,  lifecycle  callbacks,   and  so  forth).

              • References     to other  beans   that  are  needed    for the  bean   to do  its work.  These   references    are  also
                called  collaborators    or  dependencies.

              • Other   configuration     settings   to set  in the  newly    created   object — for    example,    the  size  limit  of
                the  pool  or the  number     of connections     to use  in a bean   that  manages    a  connection    pool.


            This metadata translates to a set of properties that make up each bean definition. The following
            table describes    these  properties:


            Table 1. The  bean  definition

            Property                                                       Explained     in…

            Class                                                          Instantiating   Beans

            Name                                                           Naming    Beans

            Scope                                                          Bean   Scopes

            Constructor     arguments                                      Dependency      Injection

            Properties                                                     Dependency      Injection

            Autowiring     mode                                            Autowiring     Collaborators

            Lazy   initialization   mode                                   Lazy-initialized    Beans

            Initialization   method                                        Initialization   Callbacks

            Destruction     method                                         Destruction    Callbacks


            In addition to bean definitions that contain information on how to create a specific bean, the
            ApplicationContext      implementations       also  permit   the  registration   of existing   objects  that  are  created
            outside the container (by users). This is done by accessing the ApplicationContext’s BeanFactory
            through      the     getBeanFactory()        method,       which      returns      the    DefaultListableBeanFactory
            implementation.          DefaultListableBeanFactory            supports       this     registration       through       the
            registerSingleton(..)        and    registerBeanDefinition(..)          methods.     However,      typical   applications
            work   solely  with  beans   defined   through    regular   bean   definition   metadata.


                              Bean   metadata    and   manually    supplied    singleton   instances   need   to be  registered    as
                              early  as possible,   in order   for  the container    to properly    reason    about   them   during
                              autowiring    and   other  introspection     steps.  While   overriding    existing   metadata    and
                             existing  singleton    instances    is supported    to  some    degree,   the  registration   of  new
                              beans at runtime (concurrently with live access to the factory) is not officially
                              supported    and   may   lead  to  concurrent    access   exceptions,    inconsistent    state  in the
                              bean  container,    or both.



            Naming     Beans

            Every   bean   has  one  or  more   identifiers.  These   identifiers   must   be  unique    within   the container    that
            hosts  the  bean.   A bean   usually   has   only  one   identifier.  However,     if it  requires  more   than   one,  the

            extra  ones  can  be  considered     aliases.


            In XML-based      configuration    metadata,    you   use  the  id attribute,  the  name  attribute,  or  both  to specify
            the  bean   identifiers.  The   id  attribute   lets you   specify  exactly   one   id. Conventionally,     these   names
            are  alphanumeric      ('myBean',    'someService',    etc.), but  they  can  contain    special  characters    as  well. If
            you  want    to introduce    other   aliases  for  the  bean,   you  can   also  specify  them    in the  name   attribute,
            separated    by  a comma     (,), semicolon     (;), or white   space.   As  a historical   note,  in  versions   prior   to
            Spring   3.1,  the  id  attribute  was defined   as  an xsd:ID   type,  which   constrained     possible   characters.   As
            of 3.1, it is defined as an xsd:string type. Note that bean id uniqueness is still enforced by the
            container,   though   no  longer   by  XML   parsers.


            You  are  not  required   to supply    a name  or an  id for  a bean.   If  you do not  supply   a  name  or id explicitly,
            the container    generates    a unique    name    for that  bean.  However,     if you  want   to refer  to  that bean   by
            name, through the use of the ref element or a Service Locator style lookup, you must provide a
            name. Motivations for not supplying a name are related to using inner beans and autowiring
            collaborators.


                                                    Bean     Naming        Conventions

               The   convention     is  to  use  the  standard Java  convention     for  instance   field names    when    naming
               beans. That is, bean names start with a lowercase letter and are camel-cased from there.
               Examples     of such   names    include   accountManager,    accountService,     userDao,   loginController,     and
               so  forth.


               Naming     beans   consistently    makes    your   configuration     easier  to read   and   understand.     Also,  if
               you   use  Spring  AOP,   it  helps a lot when   applying    advice   to a set of beans    related  by  name.




                              With component scanning in the classpath, Spring generates bean names for
                              unnamed     components,      following    the rules  described    earlier:  essentially,   taking  the
                              simple   class  name    and  turning    its  initial  character  to lower-case.    However,     in the
                             (unusual)    special  case   when    there  is more    than   one   character    and  both   the  first
                              and  second   characters    are  upper   case,  the  original  casing   gets preserved.    These   are
                              the same    rules  as  defined   by  java.beans.Introspector.decapitalize            (which    Spring
                              uses  here).



            Aliasing a Bean   outside  the Bean  Definition

            In a bean definition itself, you can supply more than one name for the bean, by using a
            combination     of up  to  one  name    specified   by  the id  attribute  and   any  number     of other   names    in the
            name attribute. These names can be equivalent aliases to the same bean and are useful for some
            situations, such as letting each component in an application refer to a common dependency by
            using  a bean   name    that is specific  to that  component      itself.

            Specifying all aliases where the bean is actually defined is not always adequate, however. It is
            sometimes     desirable   to  introduce    an  alias  for a  bean   that  is defined   elsewhere.     This  is commonly
            the case in large systems where configuration is split amongst each subsystem, with each
            subsystem     having   its own   set  of object   definitions.   In XML-based      configuration     metadata,    you   can
            use the  <alias/>   element    to accomplish     this. The  following    example    shows    how   to do  so:

              <alias    name="fromName"       alias="toName"/>



            In this case, a bean (in the same container) named fromName may also, after the use of this alias
            definition,  be  referred   to as  toName.


            For example,     the configuration     metadata    for  subsystem     A may   refer  to a  DataSource     by the  name    of
            subsystemA-dataSource.       The  configuration     metadata     for  subsystem     B  may   refer  to a  DataSource     by
            the name of subsystemB-dataSource. When composing the main application that uses both these
            subsystems,    the  main   application    refers  to the  DataSource     by  the name    of myApp-dataSource.     To  have
            all three names refer to the same object, you can add the following alias definitions to the
            configuration    metadata:



              <alias    name="myApp-dataSource"          alias="subsystemA-dataSource"/>
              <alias    name="myApp-dataSource"          alias="subsystemB-dataSource"/>



            Now   each   component      and  the  main   application    can   refer  to the  dataSource    through    a  name   that  is
            unique   and   guaranteed      not  to clash   with  any   other   definition   (effectively   creating   a  namespace),
            yet they  refer  to the  same   bean.


                                                           Java-configuration

               If you   use  Javaconfiguration,      the  @Bean  annotation     can   be used   to  provide   aliases.  See   Using
               the  @Bean  Annotation     for details.




            Instantiating    Beans

            A bean   definition   is essentially   a recipe   for creating   one   or more   objects.   The  container    looks  at the
            recipe for a named bean when asked and uses the configuration metadata encapsulated by that
            bean  definition   to  create  (or acquire)   an  actual   object.


            If  you use  XML-based      configuration     metadata,    you  specify   the  type  (or  class) of  object  that  is to be
            instantiated   in  the class  attribute   of the  <bean/>   element.    This  class  attribute   (which,   internally,  is a
            Class   property      on   a   BeanDefinition      instance)     is  usually    mandatory.       (For   exceptions,     see
            Instantiation    by  Using   an  Instance   Factory    Method    and   Bean   Definition    Inheritance.)    You   can  use
            the Class  property    in one   of two  ways:


              • Typically, to specify the bean class to be constructed in the case where the container itself
                directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java
                code   with  the  new operator.

              • To specify the actual class containing the static factory method that is invoked to create the
                object,  in the  less common      case  where    the  container    invokes   a static   factory   method    on  a class
                to create   the  bean.   The  object   type  returned    from    the invocation     of the  static   factory   method
                may   be  the same    class or  another   class  entirely.

                                                          Nested      class    names

               If you   want   to configure    a  bean   definition   for  a nested   class,  you  may    use  either  the  binary
               name    or the  source   name    of the  nested   class.


               For example, if you have a class called SomeThing in the com.example package, and this
               SomeThing    class  has  a static   nested   class  called  OtherThing,    they  can   be  separated    by  a dollar
               sign ($) or a dot (.). So the value of the class attribute in a bean definition would be
               com.example.SomeThing$OtherThing           or com.example.SomeThing.OtherThing.





            Instantiation  with  a Constructor

            When you create a bean by the constructor approach, all normal classes are usable by and
            compatible    with   Spring.  That   is,  the  class  being developed    does   not  need   to implement     any   specific
            interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice.
            However,     depending     on  what    type  of  IoC  you  use   for that  specific   bean,   you  may    need   a default
            (empty)   constructor.


            The  Spring   IoC  container    can  manage     virtually   any  class  you  want   it to manage.     It  is  not  limited  to
            managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-
            argument) constructor and appropriate setters and getters modeled after the properties in the
            container.   You   can  also  have   more   exotic  non-bean-style      classes  in  your  container.    If,  for  example,
            you need to use a legacy connection pool that absolutely does not adhere to the JavaBean
            specification,   Spring   can  manage    it as well.


            With  XML-based      configuration     metadata    you  can   specify  your   bean   class as follows:



              <bean    id="exampleBean"       class="examples.ExampleBean"/>


              <bean    name="anotherExample"         class="examples.ExampleBeanTwo"/>



            For details about the mechanism for supplying arguments to the constructor (if required) and
            setting  object  instance   properties    after the  object  is constructed,    see  Injecting  Dependencies.



            Instantiation  with  a Static Factory  Method

            When    defining   a bean   that  you  create  with   a static factory   method,    use  the class   attribute  to specify
            the class  that  contains   the  static   factory   method    and   an  attribute   named    factory-method     to specify
            the name of the factory method itself. You should be able to call this method (with optional
            arguments,     as described    later)  and   return   a live  object,  which    subsequently     is treated   as  if it had
            been  created    through    a constructor.    One   use  for such   a bean   definition   is to call static   factories   in
            legacy  code.


            The  following    bean   definition   specifies   that  the  bean   will  be  created   by  calling   a factory   method.
            The definition does not specify the type (class) of the returned object, but rather the class
            containing the factory method. In this example, the createInstance() method must be a static
            method.   The   following   example     shows   how   to specify   a factory   method:

              <bean    id="clientService"
                    class="examples.ClientService"
                    factory-method="createInstance"/>



            The  following   example     shows   a class  that  would   work    with  the  preceding    bean   definition:


            Java


              public    class   ClientService      {
                    private    static   ClientService       clientService      =  new  ClientService();
                    private    ClientService()       {}


                    public   static    ClientService      createInstance()        {
                         return    clientService;
                    }
              }



            Kotlin


              class    ClientService      private    constructor()      {
                    companion     object   {
                         private    val   clientService      =  ClientService()
                         @JvmStatic
                         fun   createInstance()       =  clientService
                    }
              }



            For details about the mechanism for supplying (optional) arguments to the factory method and
            setting  object   instance   properties    after  the  object   is returned    from   the  factory,   see  Dependencies
            and  Configuration     in Detail.



            Instantiation  by Using  an  Instance  Factory  Method

            Similar to instantiation through a static factory method, instantiation with an instance factory
            method    invokes    a non-static   method     of an  existing   bean   from   the  container    to create   a new   bean.
            To  use  this mechanism,      leave   the  class   attribute  empty    and,   in the  factory-bean     attribute,  specify
            the name of a bean in the current (or parent or ancestor) container that contains the instance
            method    that  is  to  be  invoked to  create  the  object.  Set the  name    of the  factory   method    itself with  the
            factory-method     attribute.  The  following    example    shows    how   to configure    such  a bean:

              
              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              
              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>



            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                    }
                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }
              }



            One  factory   class can   also hold   more   than  one   factory  method,    as the  following    example    shows:



              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>


              <bean    id="accountService"
                    factory-bean="serviceLocator"
                    factory-method="createAccountServiceInstance"/>

            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    private    static   AccountService       accountService       = new   AccountServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }


                    public   AccountService       createAccountServiceInstance()             {
                         return    accountService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                         private    val   accountService      =  AccountServiceImpl()
                    }


                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }


                    fun  createAccountServiceInstance():             AccountService       {
                         return    accountService
                    }
              }



            This approach shows that the factory bean itself can be managed and configured through
            dependency     injection   (DI). See  Dependencies      and   Configuration     in Detail.


                              In Spring   documentation,       "factory   bean"   refers  to a  bean   that is configured     in the
                              Spring container and that creates objects through an instance or static factory
                             method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-
                              specific  FactoryBean    implementation       class.



            Determining    a Bean’s Runtime    Type

            The runtime type of a specific bean is non-trivial to determine. A specified class in the bean
            metadata    definition   is just  an  initial class  reference,    potentially   combined      with  a  declared   factory
            method    or being   a  FactoryBean    class which    may   lead  to  a different   runtime    type  of the  bean,   or not

            being set at all in case of an instance-level factory method (which is resolved via the specified
            factory-bean name instead). Additionally, AOP proxying may wrap a bean instance with an
            interface-based     proxy   with   limited  exposure     of the  target   bean’s  actual   type  (just  its implemented
            interfaces).

            The recommended way to find out about the actual runtime type of a particular bean is a
            BeanFactory.getType      call  for the  specified   bean   name.   This   takes  all of the  above   cases   into account
            and  returns   the  type   of object   that a  BeanFactory.getBean       call is going   to return   for  the  same   bean
            name.

            2.1.4.   Dependencies

            A typical  enterprise    application    does   not  consist  of a  single  object  (or  bean   in the  Spring   parlance).
            Even   the  simplest   application    has   a few   objects   that  work   together    to present    what   the  end-user
            sees  as a  coherent    application.    This  next  section   explains    how   you   go  from   defining   a  number     of
            bean  definitions    that stand   alone  to  a fully realized   application    where   objects   collaborate    to achieve
            a goal.


            Dependency       Injection

            Dependency      injection   (DI) is a process   whereby     objects  define   their  dependencies      (that is, the  other
            objects  with  which    they  work)   only  through    constructor    arguments,     arguments     to a factory   method,
            or properties    that  are  set  on  the  object  instance    after  it  is  constructed  or  returned    from   a factory
            method. The container then injects those dependencies when it creates the bean. This process is
            fundamentally      the  inverse   (hence   the  name,   Inversion    of  Control)   of the  bean   itself controlling   the
            instantiation   or  location  of  its  dependencies    on  its own   by  using  direct  construction    of  classes  or the
            Service  Locator    pattern.


            Code   is cleaner   with  the  DI  principle,   and   decoupling    is more    effective  when    objects   are  provided
            with their dependencies. The object does not look up its dependencies and does not know the
            location   or class  of  the  dependencies.      As  a result,  your   classes   become    easier   to test, particularly
            when the dependencies are on interfaces or abstract base classes, which allow for stub or mock
            implementations       to be used   in unit  tests.


            DI  exists   in   two    major    variants:    Constructor-based        dependency       injection    and    Setter-based
            dependency     injection.



            Constructor-based    Dependency     Injection

            Constructor-based DI is accomplished by the container invoking a constructor with a number of
            arguments,      each   representing      a  dependency.       Calling   a   static   factory    method     with    specific
            arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a
            constructor    and  to  a static   factory  method     similarly.  The  following    example    shows    a class  that  can
            only  be dependency-injected        with  constructor     injection:

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  a MovieFinder
                    private    final   MovieFinder      movieFinder;


                    //  a  constructor     so  that   the   Spring   container     can   inject   a  MovieFinder
                    public   SimpleMovieLister(MovieFinder             movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              //  a  constructor      so  that   the  Spring    container     can  inject    a MovieFinder
              class    SimpleMovieLister(private          val   movieFinder:      MovieFinder)      {
                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Notice that there is nothing special about this class. It is a POJO that has no dependencies on
            container   specific  interfaces,   base   classes, or  annotations.


            Constructor     Argument      Resolution

            Constructor argument resolution matching occurs by using the argument’s type. If no potential
            ambiguity exists in the constructor arguments of a bean definition, the order in which the
            constructor    arguments     are  defined    in a bean   definition    is the order   in  which   those   arguments     are
            supplied   to the  appropriate     constructor    when   the  bean   is being   instantiated.   Consider    the following
            class:


            Java


              package    x.y;


              public    class   ThingOne     {


                    public   ThingOne(ThingTwo        thingTwo,     ThingThree     thingThree)      {
                         //  ...
                    }
              }

            Kotlin


              package    x.y


              class    ThingOne(thingTwo:        ThingTwo,    thingThree:      ThingThree)



            Assuming that the ThingTwo and ThingThree classes are not related by inheritance, no potential
            ambiguity    exists.  Thus,  the  following    configuration     works    fine, and   you  do  not  need   to  specify  the
            constructor    argument     indexes   or types   explicitly  in the  <constructor-arg/>      element.



              <beans>
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        ref="beanTwo"/>
                         <constructor-arg        ref="beanThree"/>
                    </bean>


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>


                    <bean   id="beanThree"       class="x.y.ThingThree"/>
              </beans>



            When    another   bean   is referenced,    the  type  is known,    and  matching     can  occur   (as was   the case   with
            the preceding example). When a simple type is used, such as <value>true</value>, Spring cannot
            determine    the  type  of  the  value,  and  so  cannot   match    by  type  without    help.  Consider    the following
            class:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    final   int   years;


                    //  The  Answer    to  Life,   the   Universe,     and  Everything
                    private    final   String    ultimateAnswer;


                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }

            Kotlin


              package    examples


              class    ExampleBean(
                    private    val  years:    Int,   //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    val  ultimateAnswer:       String    //  The   Answer   to  Life,    the  Universe,     and
              Everything
              )



            Constructor   argument    type  matching
            In the  preceding    scenario,    the  container    can  use  type  matching     with   simple   types  if you   explicitly
            specify  the  type  of  the  constructor    argument     by  using   the  type  attribute,  as  the  following    example
            shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       type="int"     value="7500000"/>
                    <constructor-arg       type="java.lang.String"          value="42"/>
              </bean>



            Constructor   argument    index
            You can use the index attribute to specify explicitly the index of constructor arguments, as the
            following   example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       index="0"     value="7500000"/>
                    <constructor-arg       index="1"     value="42"/>
              </bean>



            In addition to resolving the ambiguity of multiple simple values, specifying an index resolves
            ambiguity    where    a constructor    has  two  arguments     of  the same    type.

                             The  index   is  0-based.


            Constructor   argument    name
            You can also use the constructor parameter name for value disambiguation, as the following
            example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       name="years"      value="7500000"/>
                    <constructor-arg       name="ultimateAnswer"         value="42"/>
              </bean>



            Keep   in mind    that, to  make   this  work   out  of  the  box,  your   code  must    be  compiled    with   the  debug
            flag enabled    so that  Spring   can  look   up  the parameter     name    from   the  constructor.    If you  cannot    or

            do not  want   to  compile   your   code   with  the  debug   flag, you   can  use  the  @ConstructorProperties         JDK
            annotation to explicitly name your constructor arguments. The sample class would then have to
            look  as follows:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Fields    omitted


                    @ConstructorProperties({"years",             "ultimateAnswer"})
                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }



            Kotlin


              package    examples


              class    ExampleBean
              @ConstructorProperties("years",             "ultimateAnswer")
              constructor(val       years:    Int,   val  ultimateAnswer:       String)




            Setter-based  Dependency     Injection

            Setter-based DI is accomplished by the container calling setter methods on your beans after
            invoking a no-argument constructor or a no-argument static factory method to instantiate your
            bean.

            The following example shows a class that can only be dependency-injected by using pure setter
            injection.  This  class  is  conventional   Java.  It is  a  POJO that has  no  dependencies      on  container    specific
            interfaces,  base   classes,  or annotations.

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  the  MovieFinder
                    private    MovieFinder     movieFinder;


                    //  a  setter   method    so  that   the  Spring    container     can  inject    a  MovieFinder
                    public   void   setMovieFinder(MovieFinder           movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              class    SimpleMovieLister       {


                    //  a  late-initialized       property    so   that  the   Spring    container    can   inject   a
              MovieFinder
                    lateinit    var   movieFinder:      MovieFinder


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            The  ApplicationContext      supports    constructor-based       and  setter-based    DI  for the  beans   it manages.    It
            also supports setter-based DI after some dependencies have already been injected through the
            constructor    approach.    You   configure    the  dependencies      in the  form   of  a BeanDefinition,     which    you
            use  in conjunction     with  PropertyEditor     instances    to convert   properties    from   one  format   to  another.
            However,    most   Spring   users   do  not  work   with   these  classes  directly   (that is, programmatically)       but
            rather  with   XML   bean  definitions,   annotated    components      (that  is,  classes annotated    with  @Component,
            @Controller,   and   so forth),  or @Bean   methods    in  Java-based    @Configuration     classes.  These   sources   are
            then converted internally into instances of BeanDefinition and used to load an entire Spring IoC
            container   instance.

                                           Constructor-based              or  setter-based          DI?

               Since   you   can  mix   constructor-based       and  setter-based     DI, it is a  good   rule  of thumb     to use
               constructors     for  mandatory      dependencies      and  setter   methods    or  configuration     methods     for
               optional    dependencies.     Note   that  use  of  the  @Autowired      annotation     on  a setter   method    can
               be  used   to make   the  property    be  a required    dependency;     however,     constructor    injection   with
               programmatic       validation   of arguments      is  preferable.

               The    Spring    team    generally     advocates     constructor     injection,    as  it  lets  you    implement
               application components as immutable objects and ensures that required dependencies are
               not null. Furthermore, constructor-injected components are always returned to the client
               (calling) code in a fully initialized state. As a side note, a large number of constructor
               arguments     is a bad   code  smell,  implying    that  the class  likely  has  too many    responsibilities    and
               should   be  refactored    to better  address    proper   separation    of concerns.


               Setter  injection   should   primarily    only  be  used   for optional   dependencies      that  can  be  assigned
               reasonable default values within the class. Otherwise, not-null checks must be performed
               everywhere the code uses the dependency. One benefit of setter injection is that setter
               methods make objects of that class amenable to reconfiguration or re-injection later.
               Management       through    JMX   MBeans     is  therefore  a compelling    use  case  for  setter  injection.


               Use   the  DI  style that  makes     the  most   sense   for a  particular   class.  Sometimes,     when    dealing
               with   third-party   classes   for which   you   do  not  have  the  source,   the  choice  is made    for you.  For
               example,    if a third-party    class  does  not  expose   any   setter  methods,    then  constructor     injection
               may   be  the  only  available   form   of DI.





            Dependency    Resolution   Process

            The  container    performs    bean   dependency      resolution   as  follows:


              • The   ApplicationContext      is created   and   initialized  with  configuration     metadata     that  describes   all
                the  beans.  Configuration     metadata     can  be  specified   by XML,   Java   code,  or annotations.

              • For  each  bean,   its dependencies      are expressed     in the  form  of  properties,   constructor    arguments,
                or arguments to the static-factory method (if you use that instead of a normal constructor).
                These   dependencies      are  provided    to the bean,   when    the bean   is actually   created.

              • Each   property    or constructor    argument     is an  actual   definition   of the  value  to  set,  or  a reference
                to another    bean   in the  container.

              • Each   property    or constructor     argument     that  is  a  value  is  converted  from   its  specified format    to
                the  actual  type  of  that property    or  constructor    argument.     By default,   Spring   can  convert   a value
                supplied   in  string  format   to all built-in  types,  such  as int,  long, String,   boolean,  and   so forth.

            The  Spring   container    validates   the configuration     of each   bean   as the  container    is  created. However,
            the bean properties themselves are not set until the bean is actually created. Beans that are
            singleton-scoped and set to be pre-instantiated (the default) are created when the container is
            created. Scopes are defined in Bean Scopes. Otherwise, the bean is created only when it is
            requested. Creation of a bean potentially causes a graph of beans to be created, as the bean’s
            dependencies      and  its dependencies'      dependencies      (and  so  on)  are  created   and   assigned.    Note  that

            resolution   mismatches      among     those  dependencies      may    show   up  late — that    is,  on  first  creation of
            the affected   bean.


                                                       Circular       dependencies

               If you use predominantly constructor injection, it is possible to create an unresolvable
               circular   dependency      scenario.


               For  example:    Class  A  requires   an  instance   of class  B through    constructor    injection,   and  class  B
               requires an instance of class A through constructor injection. If you configure beans for
               classes   A  and  B  to be  injected   into  each   other,  the  Spring   IoC  container    detects   this  circular
               reference    at runtime,    and  throws    a BeanCurrentlyInCreationException.


               One   possible    solution   is to edit  the  source   code   of  some   classes   to be   configured    by  setters
               rather than constructors. Alternatively, avoid constructor injection and use setter injection
               only.   In   other    words,    although     it  is  not    recommended,        you    can    configure     circular
               dependencies      with  setter  injection.


               Unlike   the  typical  case  (with   no  circular  dependencies),      a circular   dependency      between    bean
               A and bean B forces one of the beans to be injected into the other prior to being fully
               initialized   itself  (a  classic  chicken-and-egg   scenario).



            You can generally trust Spring to do the right thing. It detects configuration problems, such as
            references to non-existent beans and circular dependencies, at container load-time. Spring sets
            properties    and  resolves    dependencies      as late  as  possible,   when    the  bean   is actually   created.   This
            means    that a  Spring   container    that  has  loaded   correctly   can  later  generate    an  exception    when    you
            request an object if there is a problem creating that object or one of its dependencies — for
            example,    the bean   throws    an  exception    as a  result  of a missing   or  invalid   property.   This  potentially
            delayed visibility of some configuration issues is why ApplicationContext implementations by
            default pre-instantiate singleton beans. At the cost of some upfront time and memory to create
            these   beans    before    they    are   actually   needed,     you    discover    configuration      issues   when     the
            ApplicationContext      is created,  not  later. You   can  still  override  this default   behavior    so that  singleton
            beans   initialize lazily, rather   than  being   eagerly   pre-instantiated.


            If  no circular  dependencies      exist,  when    one  or  more   collaborating     beans   are  being   injected   into  a
            dependent bean, each collaborating bean is totally configured prior to being injected into the
            dependent     bean.  This   means    that, if bean   A  has  a dependency      on  bean   B, the  Spring   IoC  container
            completely    configures    bean    B prior   to invoking    the  setter  method     on  bean   A. In  other   words,   the
            bean is instantiated (if it is not a pre-instantiated singleton), its dependencies are set, and the
            relevant lifecycle methods (such as a configured init method or the InitializingBean callback
            method)    are  invoked.



            Examples   of Dependency     Injection

            The  following    example    uses  XML-based      configuration     metadata     for setter-based    DI. A  small   part  of
            a Spring   XML   configuration     file specifies  some   bean   definitions   as  follows:

              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <property     name="beanOne">
                         <ref   bean="anotherExampleBean"/>
                    </property>


                    
                    <property     name="beanTwo"      ref="yetAnotherBean"/>
                    <property     name="integerProperty"         value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   void   setBeanOne(AnotherBean          beanOne)    {
                         this.beanOne      =  beanOne;
                    }


                    public   void   setBeanTwo(YetAnotherBean           beanTwo)    {
                         this.beanTwo      =  beanTwo;
                    }


                    public   void   setIntegerProperty(int          i)  {
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean     {
                    lateinit    var   beanOne:    AnotherBean
                    lateinit    var   beanTwo:    YetAnotherBean
                    var  i:  Int   =  0
              }



            In the  preceding    example,    setters  are  declared    to match   against   the  properties    specified  in  the XML

            file.  The  following  example    uses  constructor-based       DI:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <constructor-arg>
                         <ref   bean="anotherExampleBean"/>
                    </constructor-arg>


                    
                    <constructor-arg       ref="yetAnotherBean"/>


                    <constructor-arg       type="int"     value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   ExampleBean(
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {
                         this.beanOne      =  anotherBean;
                         this.beanTwo      =  yetAnotherBean;
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean(
                         private    val   beanOne:    AnotherBean,
                         private    val   beanTwo:    YetAnotherBean,
                         private    val   i:  Int)



            The constructor arguments specified in the bean definition are used as arguments to the
            constructor    of the  ExampleBean.


            Now   consider    a variant   of this  example,    where,   instead   of using   a constructor,    Spring   is told  to call
            a static  factory   method    to return   an  instance   of the  object:

              <bean    id="exampleBean"       class="examples.ExampleBean"            factory-method="createInstance">
                    <constructor-arg       ref="anotherExampleBean"/>
                    <constructor-arg       ref="yetAnotherBean"/>
                    <constructor-arg       value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    //  a  private    constructor
                    private    ExampleBean(...)       {
                         ...
                    }


                    //  a  static   factory    method;    the   arguments     to  this   method   can   be
                    //  considered     the   dependencies     of   the  bean   that   is  returned,
                    //  regardless     of  how   those   arguments     are  actually     used.
                    public   static    ExampleBean      createInstance      (
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {


                         ExampleBean      eb  =  new  ExampleBean      (...);
                         //  some   other    operations...
                         return    eb;
                    }
              }



            Kotlin


              class    ExampleBean     private    constructor()      {
                    companion     object   {
                         //  a  static    factory    method;    the  arguments     to  this   method    can  be
                         //  considered      the  dependencies      of  the   bean  that   is  returned,
                         //  regardless      of  how  those   arguments     are   actually    used.
                         @JvmStatic
                         fun   createInstance(anotherBean:           AnotherBean,      yetAnotherBean:       YetAnotherBean,
              i:  Int):    ExampleBean     {
                               val  eb  =  ExampleBean      (...)
                               //  some   other   operations...
                               return   eb
                         }
                    }
              }

            Arguments     to  the  static   factory  method     are  supplied    by  <constructor-arg/>      elements,    exactly   the
            same   as if a constructor    had   actually   been  used.   The  type  of  the class  being   returned    by  the factory
            method    does   not  have   to be  of  the same    type  as  the  class  that  contains   the  static   factory   method
            (although, in this example, it is). An instance (non-static) factory method can be used in an
            essentially   identical   fashion   (aside  from    the  use  of the  factory-bean     attribute   instead   of  the  class
            attribute),  so we   do not  discuss   those  details  here.


            Dependencies       and  Configuration       in Detail

            As mentioned      in the previous    section,  you   can  define  bean   properties    and  constructor    arguments      as
            references    to other  managed      beans   (collaborators)    or  as values   defined    inline. Spring’s   XML-based
            configuration     metadata    supports    sub-element      types  within   its <property/>     and   <constructor-arg/>
            elements    for this purpose.



            Straight Values  (Primitives,  Strings,  and  so on)

            The  value   attribute   of the  <property/>     element    specifies   a property    or  constructor     argument     as  a
            human-readable       string  representation.      Spring’s   conversion    service   is used   to convert    these  values
            from   a String  to  the actual   type  of the  property    or argument.     The  following    example    shows    various
            values  being   set:



              <bean    id="myDataSource"       class="org.apache.commons.dbcp.BasicDataSource"                   destroy-
              method="close">
                    
                    <property     name="driverClassName"         value="com.mysql.jdbc.Driver"/>
                    <property     name="url"     value="jdbc:mysql://localhost:3306/mydb"/>
                    <property     name="username"       value="root"/>
                    <property     name="password"       value="misterkaoli"/>
              </bean>



            The  following   example     uses  the  p-namespace      for even   more   succinct   XML   configuration:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                    https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="myDataSource"        class="org.apache.commons.dbcp.BasicDataSource"
                         destroy-method="close"
                         p:driverClassName="com.mysql.jdbc.Driver"
                         p:url="jdbc:mysql://localhost:3306/mydb"
                         p:username="root"
                         p:password="misterkaoli"/>


              </beans>



            The  preceding    XML    is more   succinct.   However,     typos  are  discovered     at runtime    rather   than  design

            time, unless you use an IDE (such as IntelliJ IDEA or the Spring Tools for Eclipse) that supports
            automatic property completion when you create bean definitions. Such IDE assistance is highly
            recommended.


            You  can  also  configure   a  java.util.Properties      instance,   as  follows:



              <bean    id="mappings"
                    class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">


                    
                    <property     name="properties">
                         <value>
                               jdbc.driver.className=com.mysql.jdbc.Driver
                               jdbc.url=jdbc:mysql://localhost:3306/mydb
                         </value>
                    </property>
              </bean>



            The Spring container converts the text inside the <value/> element into a java.util.Properties
            instance   by  using  the  JavaBeans     PropertyEditor     mechanism.      This  is a  nice  shortcut,   and  is one  of  a
            few  places   where    the  Spring   team   do  favor   the  use  of the  nested    <value/>   element    over   the  value
            attribute  style.


            The  idref  element

            The  idref   element    is simply   an  error-proof    way   to  pass  the  id (a  string  value   -  not a reference)    of
            another bean in the container to a <constructor-arg/> or <property/> element. The following
            example    shows   how    to use  it:



              <bean    id="theTargetBean"        class="..."/>


              <bean    id="theClientBean"        class="...">
                    <property     name="targetName">
                         <idref    bean="theTargetBean"/>
                    </property>
              </bean>



            The  preceding    bean   definition   snippet   is exactly  equivalent    (at runtime)    to the  following   snippet:



              <bean    id="theTargetBean"        class="..."     />


              <bean    id="client"     class="...">
                    <property     name="targetName"       value="theTargetBean"/>
              </bean>



            The  first form   is preferable    to the  second,   because    using  the  idref   tag lets the  container    validate   at
            deployment time that the referenced, named bean actually exists. In the second variation, no

            validation   is performed      on  the  value   that is passed    to the  targetName    property    of  the  client  bean.
            Typos are only discovered (with most likely fatal results) when the client bean is actually
            instantiated.   If the  client  bean   is a  prototype    bean,  this  typo  and   the  resulting   exception    may   only
            be discovered     long  after the  container    is  deployed.


                              The  local   attribute   on  the  idref   element    is no  longer   supported     in the  4.0  beans
                              XSD, since it does not provide value over a regular bean reference any more.
                             Change    your  existing   idref   local   references    to idref   bean  when    upgrading     to the
                              4.0 schema.


            A common      place   (at least  in  versions   earlier   than   Spring   2.0)  where    the  <idref/>   element    brings
            value is in the configuration of AOP interceptors in a ProxyFactoryBean bean definition. Using
            <idref/> elements when you specify the interceptor names prevents you from misspelling an
            interceptor   ID.



            References   to Other  Beans  (Collaborators)

            The  ref  element    is the  final element    inside   a <constructor-arg/>      or  <property/>    definition   element.
            Here, you set the value of the specified property of a bean to be a reference to another bean (a
            collaborator)    managed     by  the  container.    The  referenced     bean   is a  dependency      of the  bean   whose
            property    is to be  set, and   it is initialized   on  demand     as  needed    before   the  property    is set. (If the
            collaborator    is a singleton    bean,  it may   already    be  initialized  by  the  container.)    All references    are
            ultimately   a reference    to another    object.  Scoping   and   validation   depend    on  whether    you   specify  the
            ID or  name   of the  other   object  through    the bean  or  parent  attribute.


            Specifying   the  target  bean   through    the  bean  attribute   of the  <ref/>  tag  is the most   general    form  and
            allows  creation    of a reference    to any   bean   in the  same   container    or parent    container,   regardless    of
            whether it is in the same XML file. The value of the bean attribute may be the same as the id
            attribute   of the  target  bean   or  be  the  same   as  one   of the  values   in the  name   attribute   of the  target
            bean.  The  following    example    shows    how   to use  a ref  element:



              <ref   bean="someBean"/>



            Specifying    the  target  bean   through    the  parent   attribute   creates   a  reference    to a  bean   that  is in  a
            parent container of the current container. The value of the parent attribute may be the same as
            either  the id  attribute  of  the target  bean   or  one  of the  values   in the  name  attribute  of  the target  bean.
            The target bean must be in a parent container of the current one. You should use this bean
            reference variant mainly when you have a hierarchy of containers and you want to wrap an
            existing  bean   in  a parent   container    with   a proxy    that  has  the  same   name    as  the  parent   bean.   The
            following   pair  of listings  shows   how   to use  the  parent   attribute:



              
              <bean    id="accountService"        class="com.something.SimpleAccountService">
                    
              </bean>

              
              <bean    id="accountService"        
                    class="org.springframework.aop.framework.ProxyFactoryBean">
                    <property     name="target">
                         <ref   parent="accountService"/>           
                    </property>
                    
              </bean>




                              The  local  attribute   on  the  ref element    is no  longer   supported    in the  4.0 beans    XSD,
                             since it does not provide value over a regular bean reference any more. Change
                              your  existing   ref  local  references    to ref  bean  when    upgrading     to the 4.0  schema.



            Inner Beans

            A <bean/>   element    inside   the  <property/>    or  <constructor-arg/>      elements    defines   an  inner   bean,   as
            the following    example    shows:



              <bean    id="outer"     class="...">
                    
                    <property     name="target">
                         <bean    class="com.example.Person">           
                               <property     name="name"     value="Fiona      Apple"/>
                               <property     name="age"     value="25"/>
                         </bean>
                    </property>
              </bean>



            An  inner  bean   definition   does   not  require   a defined   ID  or name.    If specified,  the  container    does  not
            use such a value as an identifier. The container also ignores the scope flag on creation, because
            inner  beans   are  always   anonymous       and  are  always    created   with  the  outer  bean.   It  is  not  possible  to
            access inner beans independently or to inject them into collaborating beans other than into the
            enclosing   bean.


            As a  corner   case,  it  is  possible  to  receive  destruction  callbacks    from   a custom    scope — for    example,
            for a request-scoped      inner   bean   contained    within   a singleton    bean.  The   creation   of  the inner   bean
            instance is tied to its containing bean, but destruction callbacks let it participate in the request
            scope’s  lifecycle.  This  is  not  a common    scenario.   Inner   beans   typically  simply   share   their  containing
            bean’s  scope.



            Collections

            The <list/>, <set/>, <map/>, and <props/> elements set the properties and arguments of the Java
            Collection    types  List,  Set,  Map, and   Properties,    respectively.   The   following    example     shows   how    to
            use them:

              <bean    id="moreComplexObject"         class="example.ComplexObject">
                    
                    <property     name="adminEmails">
                         <props>
                               <prop   key="administrator">administrator@example.org</prop>
                               <prop   key="support">support@example.org</prop>
                               <prop   key="development">development@example.org</prop>
                         </props>
                    </property>
                    
                    <property     name="someList">
                         <list>
                               <value>a    list   element    followed    by   a reference</value>
                               <ref   bean="myDataSource"        />
                         </list>
                    </property>
                    
                    <property     name="someMap">
                         <map>
                               <entry   key="an    entry"    value="just      some  string"/>
                               <entry   key="a    ref"   value-ref="myDataSource"/>
                         </map>
                    </property>
                    
                    <property     name="someSet">
                         <set>
                               <value>just     some   string</value>
                               <ref   bean="myDataSource"        />
                         </set>
                    </property>
              </bean>



            The  value  of  a map   key  or  value,  or a set  value,  can  also  be any  of  the following    elements:



              bean   |  ref  |  idref   |  list   |  set  |  map   | props    | value    | null



            Collection    Merging

            The Spring container also supports merging collections. An application developer can define a
            parent   <list/>,  <map/>,  <set/>   or  <props/>   element    and  have   child  <list/>,  <map/>,   <set/>  or  <props/>
            elements inherit and override values from the parent collection. That is, the child collection’s
            values   are  the  result  of merging     the  elements    of the  parent    and  child   collections,   with  the  child’s
            collection  elements    overriding    values   specified   in the  parent   collection.


            This section on merging discusses the parent-child bean mechanism. Readers unfamiliar with
            parent   and  child  bean   definitions   may   wish   to read  the  relevant   section   before  continuing.


            The  following   example     demonstrates     collection   merging:

              <beans>
                    <bean   id="parent"      abstract="true"       class="example.ComplexObject">
                         <property     name="adminEmails">
                               <props>
                                    <prop    key="administrator">administrator@example.com</prop>
                                    <prop    key="support">support@example.com</prop>
                               </props>
                         </property>
                    </bean>
                    <bean   id="child"     parent="parent">
                         <property     name="adminEmails">
                               
                               <props   merge="true">
                                    <prop    key="sales">sales@example.com</prop>
                                    <prop    key="support">support@example.co.uk</prop>
                               </props>
                         </property>
                    </bean>
              <beans>



            Notice  the  use  of the  merge=true    attribute  on  the  <props/>   element    of the  adminEmails    property    of the
            child bean definition. When the child bean is resolved and instantiated by the container, the
            resulting   instance   has  an  adminEmails     Properties    collection   that  contains   the  result  of  merging    the
            child’s  adminEmails    collection   with   the  parent’s   adminEmails    collection.   The   following    listing shows
            the result:



              administrator=administrator@example.com
              sales=sales@example.com
              support=support@example.co.uk



            The  child  Properties    collection’s   value   set inherits   all property    elements    from   the  parent   <props/>,
            and  the  child’s value   for the  support   value  overrides    the  value  in  the parent   collection.


            This  merging    behavior     applies   similarly   to the  <list/>,   <map/>,   and  <set/>   collection   types.   In the
            specific  case  of the  <list/>   element,    the  semantics    associated    with   the List   collection   type  (that  is,
            the notion    of an  ordered   collection   of  values)  is maintained.     The   parent’s   values   precede    all of the
            child list’s values. In the case of the Map, Set, and Properties collection types, no ordering exists.
            Hence,   no  ordering    semantics    are  in effect  for  the collection   types   that  underlie   the  associated    Map,
            Set, and  Properties    implementation       types  that  the container    uses  internally.


            Limitations     of Collection    Merging

            You  cannot   merge    different   collection  types   (such  as  a Map and   a List).  If  you do  attempt   to do  so, an
            appropriate    Exception    is  thrown.  The  merge   attribute  must   be  specified   on  the lower,   inherited,   child
            definition.  Specifying    the  merge  attribute   on a  parent   collection  definition    is  redundant   and   does  not
            result in  the desired   merging.

            Strongly-typed      collection

            Thanks to Java’s support for generic types, you can use strongly typed collections. That is, it is
            possible   to declare   a Collection    type  such   that  it  can  only contain   (for example)     String   elements.   If
            you use Spring to dependency-inject a strongly-typed Collection into a bean, you can take
            advantage of Spring’s type-conversion support such that the elements of your strongly-typed
            Collection    instances   are  converted     to the  appropriate     type  prior  to  being   added   to  the Collection.
            The  following   Java   class and   bean  definition   show    how   to do  so:


            Java


              public    class   SomeClass     {


                    private    Map<String,     Float>    accounts;


                    public   void   setAccounts(Map<String,          Float>    accounts)     {
                         this.accounts       = accounts;
                    }
              }



            Kotlin


              class    SomeClass    {
                    lateinit    var   accounts:    Map<String,      Float>
              }




              <beans>
                    <bean   id="something"       class="x.y.SomeClass">
                         <property     name="accounts">
                               <map>
                                    <entry    key="one"     value="9.99"/>
                                    <entry    key="two"     value="2.75"/>
                                    <entry    key="six"     value="3.99"/>
                               </map>
                         </property>
                    </bean>
              </beans>



            When     the   accounts    property     of  the   something     bean    is  prepared     for   injection,   the   generics
            information about the element type of the strongly-typed Map<String, Float> is available by
            reflection.  Thus,   Spring’s   type  conversion     infrastructure     recognizes    the  various    value  elements     as
            being  of  type  Float,  and   the  string  values   (9.99,  2.75,  and  3.99)   are  converted    into  an  actual   Float
            type.



            Null and  Empty   String Values

            Spring   treats  empty    arguments     for  properties    and   the  like  as empty    Strings.   The   following    XML-
            based   configuration    metadata     snippet   sets the  email  property    to the empty    String   value  ("").

              <bean    class="ExampleBean">
                    <property     name="email"     value=""/>
              </bean>



            The  preceding    example    is equivalent    to the  following    Java  code:


            Java


              exampleBean.setEmail("");



            Kotlin


              exampleBean.email        =  ""



            The  <null/>   element    handles   null  values.  The   following   listing  shows   an  example:



              <bean    class="ExampleBean">
                    <property     name="email">
                         <null/>
                    </property>
              </bean>



            The  preceding    configuration     is  equivalent   to the following    Java  code:


            Java


              exampleBean.setEmail(null);



            Kotlin


              exampleBean.email        =  null




            XML  Shortcut   with  the p-namespace

            The  p-namespace      lets you   use  the bean  element’s    attributes   (instead   of nested   <property/>    elements)
            to describe   your   property   values   collaborating    beans,   or both.


            Spring supports extensible configuration formats with namespaces, which are based on an XML
            Schema    definition.   The   beans  configuration     format    discussed    in this  chapter   is defined    in an  XML
            Schema    document.     However,     the  p-namespace       is not  defined   in  an  XSD   file and  exists  only   in the
            core  of Spring.


            The following example shows two XML snippets (the first uses standard XML format and the
            second   uses  the  p-namespace)      that resolve   to the  same   result:

              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="classic"       class="com.example.ExampleBean">
                         <property     name="email"      value="someone@somewhere.com"/>
                    </bean>


                    <bean   name="p-namespace"        class="com.example.ExampleBean"
                         p:email="someone@somewhere.com"/>
              </beans>



            The  example     shows    an  attribute   in the  p-namespace       called  email  in  the  bean   definition.   This  tells
            Spring   to include   a property    declaration.    As  previously    mentioned,     the p-namespace       does  not  have
            a schema    definition,   so you  can  set  the name    of the  attribute   to the property    name.


            This  next  example    includes   two   more   bean   definitions   that  both  have   a reference    to another   bean:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="john-classic"         class="com.example.Person">
                         <property     name="name"      value="John     Doe"/>
                         <property     name="spouse"      ref="jane"/>
                    </bean>


                    <bean   name="john-modern"
                         class="com.example.Person"
                         p:name="John      Doe"
                         p:spouse-ref="jane"/>


                    <bean   name="jane"      class="com.example.Person">
                         <property     name="name"      value="Jane     Doe"/>
                    </bean>
              </beans>



            This example includes not only a property value using the p-namespace but also uses a special
            format    to   declare    property     references.     Whereas       the   first  bean    definition     uses   <property
            name="spouse" ref="jane"/> to create a reference from bean john to bean jane, the second bean
            definition   uses  p:spouse-ref="jane"       as an  attribute   to do  the exact   same   thing.  In this  case,  spouse  is
            the property name, whereas the -ref part indicates that this is not a straight value but rather a
            reference   to another    bean.

                              The  p-namespace       is  not  as  flexible  as  the  standard  XML    format.   For  example,    the
                              format   for  declaring    property    references    clashes   with   properties   that  end   in  Ref,
                             whereas    the  standard    XML   format    does  not.  We   recommend       that  you  choose   your
                              approach     carefully    and    communicate        this  to   your   team    members       to  avoid
                              producing    XML    documents     that  use  all  three approaches     at the  same   time.



            XML  Shortcut   with  the c-namespace

            Similar to the XML Shortcut with the p-namespace, the c-namespace, introduced in Spring 3.1,
            allows  inlined   attributes   for configuring     the constructor    arguments      rather  then   nested   constructor-
            arg elements.


            The  following    example    uses   the  c: namespace      to do  the  same    thing  as the  from   Constructor-based
            Dependency      Injection:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:c="http://www.springframework.org/schema/c"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>
                    <bean   id="beanThree"       class="x.y.ThingThree"/>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        name="thingTwo"       ref="beanTwo"/>
                         <constructor-arg        name="thingThree"       ref="beanThree"/>
                         <constructor-arg        name="email"      value="something@somewhere.com"/>
                    </bean>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne"         c:thingTwo-ref="beanTwo"
                         c:thingThree-ref="beanThree"            c:email="something@somewhere.com"/>


              </beans>



            The  c: namespace      uses   the same    conventions     as the  p: one   (a trailing  -ref  for  bean   references)    for
            setting  the  constructor    arguments     by  their  names.   Similarly,   it needs   to be  declared   in  the  XML   file
            even  though    it  is  not  defined  in  an  XSD  schema  (it  exists  inside  the  Spring core).

            For the  rare  cases   where   the  constructor    argument     names    are  not  available   (usually   if  the  bytecode
            was   compiled    without    debugging     information),     you   can  use  fallback   to  the  argument     indexes,    as
            follows:

              
              <bean    id="beanOne"     class="x.y.ThingOne"         c:_0-ref="beanTwo"        c:_1-ref="beanThree"
                    c:_2="something@somewhere.com"/>




                              Due  to  the XML    grammar,     the  index   notation    requires   the  presence    of the  leading
                              _, as XML attribute names cannot start with a number (even though some IDEs
                             allow it). A corresponding index notation is also available for <constructor-arg>
                              elements but not commonly used since the plain order of declaration is usually
                              sufficient  there.


            In practice, the constructor resolution mechanism is quite efficient in matching arguments, so
            unless  you   really need   to, we  recommend       using   the name    notation   throughout     your   configuration.



            Compound     Property  Names

            You can use compound or nested property names when you set bean properties, as long as all
            components      of the  path   except   the  final property    name    are  not   null. Consider    the  following    bean
            definition:



              <bean    id="something"      class="things.ThingOne">
                    <property     name="fred.bob.sammy"         value="123"     />
              </bean>



            The  something    bean   has  a fred  property,    which   has  a  bob property,    which   has  a  sammy  property,   and
            that final  sammy  property    is being  set  to a value   of 123. In  order  for  this to work,   the  fred  property    of
            something   and   the  bob property    of  fred  must   not  be  null  after  the bean   is constructed.    Otherwise,     a
            NullPointerException      is thrown.


            Using   depends-on

            If  a  bean is  a  dependency    of another    bean,  that  usually   means    that  one  bean   is set as  a property    of
            another. Typically you accomplish this with the <ref/> element in XML-based configuration
            metadata.    However,     sometimes     dependencies      between    beans   are  less  direct. An   example    is when    a
            static initializer in a class needs to be triggered, such as for database driver registration. The
            depends-on    attribute   can  explicitly  force   one  or  more   beans    to be  initialized  before   the  bean   using
            this element is initialized. The following example uses the depends-on attribute to express a
            dependency     on  a single   bean:



              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager"/>
              <bean    id="manager"     class="ManagerBean"         />



            To express    a dependency      on  multiple   beans,   supply   a list  of  bean  names  as  the value   of the  depends-
            on attribute   (commas,    whitespace,     and  semicolons     are valid  delimiters):

              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager,accountDao">
                    <property     name="manager"      ref="manager"      />
              </bean>


              <bean    id="manager"     class="ManagerBean"         />
              <bean    id="accountDao"       class="x.y.jdbc.JdbcAccountDao"             />




                              The  depends-on    attribute  can   specify  both   an initialization-time     dependency      and,  in
                              the case of singleton beans only, a corresponding destruction-time dependency.
                             Dependent beans that define a depends-on relationship with a given bean are
                              destroyed    first,  prior  to  the  given  bean itself being   destroyed.   Thus,   depends-on    can
                              also control   shutdown     order.



            Lazy-initialized     Beans

            By  default,  ApplicationContext      implementations       eagerly   create   and  configure    all singleton   beans    as
            part  of the  initialization  process.   Generally,    this pre-instantiation     is desirable,   because   errors   in the
            configuration or surrounding environment are discovered immediately, as opposed to hours or
            even days later. When this behavior is not desirable, you can prevent pre-instantiation of a
            singleton   bean   by  marking    the  bean   definition   as being   lazy-initialized.   A  lazy-initialized   bean   tells
            the IoC  container    to create  a bean   instance   when    it is  first  requested, rather   than  at startup.


            In XML, this behavior is controlled by the lazy-init attribute on the <bean/> element, as the
            following   example    shows:



              <bean    id="lazy"    class="com.something.ExpensiveToCreateBean"                  lazy-init="true"/>
              <bean    name="not.lazy"       class="com.something.AnotherBean"/>



            When the preceding configuration is consumed by an ApplicationContext, the lazy bean is not
            eagerly   pre-instantiated     when    the  ApplicationContext      starts,  whereas    the  not.lazy    bean   is eagerly
            pre-instantiated.


            However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-
            initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must
            satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean
            elsewhere    that  is  not  lazy-initialized.

            You can also control lazy-initialization at the container level by using the default-lazy-init
            attribute  on  the  <beans/>   element,   as  the following    example    shows:



              <beans    default-lazy-init="true">
                    
              </beans>

            Autowiring     Collaborators

            The  Spring   container    can   autowire    relationships     between    collaborating     beans.   You  can   let Spring
            resolve   collaborators    (other   beans)   automatically     for  your   bean   by  inspecting    the  contents    of the
            ApplicationContext.      Autowiring    has  the  following    advantages:

              • Autowiring can significantly reduce the need to specify properties or constructor arguments.
                (Other mechanisms such as a bean template discussed elsewhere in this chapter are also
                valuable    in this regard.)

              • Autowiring     can  update    a configuration    as  your  objects   evolve.  For  example,    if you  need   to add   a
                dependency      to  a class,  that dependency       can  be  satisfied  automatically     without    you   needing    to
                modify the configuration. Thus autowiring can be especially useful during development,
                without    negating    the option   of  switching    to explicit  wiring    when    the code   base   becomes     more
                stable.


            When using XML-based configuration metadata (see Dependency Injection), you can specify the
            autowire mode for a bean definition with the autowire attribute of the <bean/> element. The
            autowiring functionality has four modes. You specify autowiring per bean and can thus choose
            which   ones  to  autowire.   The   following   table  describes   the  four  autowiring     modes:


            Table 2. Autowiring    modes

            Mode                     Explanation
            no                       (Default)   No  autowiring.    Bean   references    must   be  defined   by  ref elements.
                                     Changing     the default   setting  is not  recommended       for  larger  deployments,
                                     because    specifying   collaborators     explicitly  gives  greater   control  and   clarity. To
                                     some    extent,  it  documents    the structure   of  a system.
            byName                   Autowiring     by  property    name.   Spring   looks  for a  bean  with   the same    name   as
                                     the  property    that needs   to be  autowired.    For  example,    if a bean   definition   is
                                     set to  autowire    by name    and  it contains   a master   property    (that is, it  has  a
                                     setMaster(..)     method),    Spring   looks  for a  bean  definition   named     master  and
                                     uses  it to set the  property.
            byType                   Lets  a property    be  autowired    if exactly  one   bean  of  the property    type  exists  in
                                     the  container.   If more   than   one  exists, a  fatal exception    is  thrown,  which
                                     indicates   that  you  may   not  use  byType   autowiring    for that  bean.   If  there are no
                                     matching     beans,  nothing    happens    (the  property   is not  set).
            constructor              Analogous     to byType   but  applies  to constructor    arguments.     If there  is not
                                     exactly   one  bean   of the  constructor    argument     type  in the  container,   a fatal
                                     error   is  raised.


            With byType or constructor autowiring mode, you can wire arrays and typed collections. In such
            cases,  all autowire    candidates     within   the  container    that  match    the  expected    type  are  provided     to
            satisfy  the  dependency.     You   can  autowire     strongly-typed     Map  instances   if the  expected    key   type  is
            String. An autowired Map instance’s values consist of all bean instances that match the expected
            type, and   the Map  instance’s   keys  contain   the  corresponding      bean   names.

            Limitations  and  Disadvantages    of Autowiring

            Autowiring works best when it is used consistently across a project. If autowiring is not used in
            general,  it might   be confusing    to developers     to use  it  to  wire  only  one  or  two  bean definitions.


            Consider   the  limitations   and   disadvantages     of autowiring:

              • Explicit  dependencies      in  property   and  constructor-arg      settings  always    override   autowiring.     You
                cannot    autowire    simple   properties    such  as  primitives,   Strings,   and   Classes   (and  arrays   of such
                simple   properties).   This  limitation   is by-design.

              • Autowiring     is less  exact  than   explicit  wiring.   Although,    as  noted   in  the  earlier  table,  Spring   is
                careful to avoid guessing in case of ambiguity that might have unexpected results. The
                relationships    between    your   Spring-managed       objects   are  no longer   documented      explicitly.

              • Wiring information may not be available to tools that may generate documentation from a
                Spring   container.

              • Multiple bean definitions within the container may match the type specified by the setter
                method    or  constructor    argument     to be  autowired.    For  arrays,  collections,   or Map  instances,   this is
                not  necessarily    a problem.    However,     for dependencies      that  expect   a single  value,  this  ambiguity
                is not  arbitrarily  resolved.   If no  unique   bean   definition   is available,   an  exception   is thrown.


            In the  latter scenario,   you  have   several   options:

              • Abandon     autowiring     in favor  of explicit  wiring.

              • Avoid   autowiring     for  a bean   definition    by  setting  its autowire-candidate       attributes   to false,   as
                described    in the  next  section.

              • Designate    a single  bean   definition   as the  primary    candidate    by  setting  the  primary  attribute   of its
                <bean/>   element    to true.

              • Implement the more fine-grained control available with annotation-based configuration, as
                described    in Annotation-based       Container    Configuration.



            Excluding   a  Bean from  Autowiring

            On a per-bean basis, you can exclude a bean from autowiring. In Spring’s XML format, set the
            autowire-candidate      attribute   of the  <bean/>  element    to false.  The   container    makes   that  specific  bean
            definition   unavailable     to the  autowiring     infrastructure     (including   annotation     style  configurations
            such  as @Autowired).


                              The  autowire-candidate       attribute   is designed    to only  affect  type-based     autowiring.
                              It does not affect explicit references by name, which get resolved even if the
                             specified bean is not marked as an autowire candidate. As a consequence,
                              autowiring    by  name    nevertheless    injects  a bean   if  the  name  matches.


            You can also limit autowire candidates based on pattern-matching against bean names. The top-
            level <beans/> element accepts one or more patterns within its default-autowire-candidates
            attribute. For example, to limit autowire candidate status to any bean whose name ends with
            Repository,   provide    a value   of *Repository.    To  provide    multiple   patterns,   define   them   in  a comma-
            separated    list.  An  explicit  value of true  or  false  for  a bean   definition’s   autowire-candidate      attribute

            always   takes  precedence.     For  such  beans,   the pattern   matching     rules  do  not apply.


            These techniques are useful for beans that you never want to be injected into other beans by
            autowiring. It does not mean that an excluded bean cannot itself be configured by using
            autowiring.    Rather,   the bean   itself is not a  candidate    for autowiring    other   beans.


            Method    Injection

            In most   application    scenarios,    most   beans   in the  container    are   singletons.   When    a  singleton   bean
            needs   to collaborate    with  another    singleton   bean   or a  non-singleton     bean   needs   to collaborate    with
            another non-singleton bean, you typically handle the dependency by defining one bean as a
            property    of the  other.  A  problem     arises  when    the  bean   lifecycles   are  different.  Suppose     singleton
            bean   A  needs   to use   non-singleton     (prototype)    bean   B, perhaps     on  each   method    invocation     on  A.
            The  container    creates   the singleton    bean   A only  once,   and  thus   only  gets  one  opportunity     to set the
            properties.   The   container    cannot   provide    bean   A  with  a  new   instance   of  bean   B every   time   one  is
            needed.

            A solution   is to  forego   some   inversion    of control.   You  can   make   bean   A  aware    of the  container    by
            implementing the ApplicationContextAware interface, and by making a getBean("B") call to the
            container ask for (a typically new) bean B instance every time bean A needs it. The following
            example    shows   this  approach:

            Java


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple;


              //  Spring-API      imports
              import    org.springframework.beans.BeansException;
              import    org.springframework.context.ApplicationContext;
              import    org.springframework.context.ApplicationContextAware;


              public    class   CommandManager       implements     ApplicationContextAware          {


                    private    ApplicationContext        applicationContext;


                    public   Object    process(Map      commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    protected     Command    createCommand()       {
                         //  notice    the   Spring   API   dependency!
                         return    this.applicationContext.getBean("command",                 Command.class);
                    }


                    public   void   setApplicationContext(
                               ApplicationContext        applicationContext)        throws    BeansException       {
                         this.applicationContext          =  applicationContext;
                    }
              }

            Kotlin


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple


              //  Spring-API      imports
              import    org.springframework.context.ApplicationContext
              import    org.springframework.context.ApplicationContextAware


              class    CommandManager      :  ApplicationContextAware          {


                    private    lateinit    var   applicationContext:        ApplicationContext


                    fun  process(commandState:          Map<*,   *>):   Any   {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  notice    the  Spring    API  dependency!
                    protected     fun  createCommand()       =
                               applicationContext.getBean("command",               Command::class.java)


                    override    fun   setApplicationContext(applicationContext:                ApplicationContext)         {
                         this.applicationContext          =  applicationContext
                    }
              }



            The preceding is not desirable, because the business code is aware of and coupled to the Spring
            Framework.      Method    Injection,   a somewhat      advanced     feature   of  the  Spring   IoC  container,   lets  you
            handle   this use  case  cleanly.



               You   can  read  more   about   the  motivation    for  Method    Injection   in this blog  entry.





            Lookup   Method   Injection

            Lookup    method    injection   is the  ability of  the  container   to  override   methods     on  container-managed
            beans   and  return   the  lookup    result  for another    named     bean   in the  container.    The  lookup    typically
            involves a prototype bean, as in the scenario described in the preceding section. The Spring
            Framework      implements     this  method    injection   by  using  bytecode    generation    from   the  CGLIB    library
            to dynamically     generate   a  subclass   that overrides    the  method.

                                • For  this  dynamic    subclassing    to  work,   the  class that  the  Spring   bean   container
                                  subclasses    cannot   be  final,  and   the  method    to  be  overridden     cannot   be  final,
                                  either.

                                • Unit-testing    a class  that  has   an  abstract   method     requires    you  to  subclass   the
                                  class  yourself   and  to supply   a stub  implementation       of the  abstract   method.
                               • Concrete    methods     are  also necessary     for component      scanning,    which    requires
                                  concrete   classes   to pick  up.

                                • A further key limitation is that lookup methods do not work with factory
                                  methods and in particular not with @Bean methods in configuration classes,
                                  since,  in  that  case, the  container    is not  in  charge   of  creating   the  instance   and
                                  therefore   cannot    create  a runtime-generated        subclass   on  the fly.


            In the case of the CommandManager class in the previous code snippet, the Spring container
            dynamically     overrides    the implementation       of the  createCommand()      method.    The  CommandManager     class
            does  not  have   any  Spring   dependencies,     as the  reworked     example    shows:


            Java


              package    fiona.apple;


              //  no   more  Spring    imports!


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              package    fiona.apple


              //  no   more  Spring    imports!


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    fun  createCommand():        Command
              }



            In the client class that contains the method to be injected (the CommandManager in this case), the
            method    to be  injected  requires    a signature   of the  following    form:



              <public|protected>        [abstract]      <return-type>      theMethodName(no-arguments);



            If  the  method   is abstract,   the  dynamically-generated         subclass   implements      the  method.    Otherwise,
            the dynamically-generated subclass overrides the concrete method defined in the original class.
            Consider   the  following    example:



              
              <bean    id="myCommand"      class="fiona.apple.AsyncCommand"              scope="prototype">
                    
              </bean>


              
              <bean    id="commandManager"        class="fiona.apple.CommandManager">
                    <lookup-method      name="createCommand"         bean="myCommand"/>
              </bean>



            The bean identified as commandManager calls its own createCommand() method whenever it needs a
            new   instance   of the  myCommand   bean.   You  must   be  careful  to deploy   the  myCommand    bean   as a prototype
            if that is actually what is needed. If it is a singleton, the same instance of the myCommand bean is
            returned   each   time.


            Alternatively, within the annotation-based component model, you can declare a lookup method
            through   the  @Lookup   annotation,    as the  following   example     shows:

            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup("myCommand")
                    protected     abstract    Command    createCommand();
              }



            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup("myCommand")
                    protected     abstract    fun  createCommand():        Command
              }



            Or, more    idiomatically,   you   can  rely on  the  target  bean   getting   resolved   against   the  declared   return
            type  of the lookup    method:


            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup
                    protected     abstract    fun  createCommand():        Command
              }



            Note that you should typically declare such annotated lookup methods with a concrete stub
            implementation,      in order   for them    to be  compatible    with   Spring’s  component      scanning    rules  where
            abstract classes get ignored by default. This limitation does not apply to explicitly registered or
            explicitly  imported    bean   classes.


                              Another way of accessing differently scoped target beans is an ObjectFactory/
                              Provider   injection  point.  See  Scoped    Beans   as Dependencies.
                 
                              You       may        also      find       the       ServiceLocatorFactoryBean             (in      the
                              org.springframework.beans.factory.config             package)    to be useful.



            Arbitrary  Method   Replacement

            A less useful form of method injection than lookup method injection is the ability to replace
            arbitrary   methods     in a  managed     bean    with  another    method     implementation.       You  can   safely  skip
            the rest  of this section   until you   actually  need   this functionality.


            With XML-based configuration metadata, you can use the replaced-method element to replace an
            existing  method     implementation       with   another,   for  a  deployed    bean.   Consider    the  following    class,
            which   has  a method    called  computeValue     that  we  want   to override:


            Java


              public    class   MyValueCalculator        {


                    public   String    computeValue(String         input)   {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }

            Kotlin


              class    MyValueCalculator       {


                    fun  computeValue(input:         String):    String    {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }



            A class that implements the org.springframework.beans.factory.support.MethodReplacer interface
            provides   the  new   method    definition,   as the  following   example     shows:


            Java


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              public    class   ReplacementComputeValue          implements     MethodReplacer       {


                    public   Object    reimplement(Object        o,  Method    m,  Object[]    args)    throws   Throwable     {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         String    input   =  (String)    args[0];
                         ...
                         return    ...;
                    }
              }



            Kotlin


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              class    ReplacementComputeValue          : MethodReplacer       {


                    override    fun   reimplement(obj:       Any,   method:    Method,    args:   Array<out     Any>):    Any  {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         val   input   =  args[0]    as  String;
                         ...
                         return    ...;
                    }
              }



            The  bean   definition    to deploy   the  original   class  and   specify   the  method    override    would    resemble
            the following    example:

              <bean    id="myValueCalculator"         class="x.y.z.MyValueCalculator">
                    
                    <replaced-method       name="computeValue"         replacer="replacementComputeValue">
                         <arg-type>String</arg-type>
                    </replaced-method>
              </bean>


              <bean    id="replacementComputeValue"           class="a.b.c.ReplacementComputeValue"/>



            You  can   use  one   or more    <arg-type/>    elements     within   the  <replaced-method/>       element    to indicate
            the method signature of the method being overridden. The signature for the arguments is
            necessary only if the method is overloaded and multiple variants exist within the class. For
            convenience,     the  type  string  for  an  argument     may   be  a  substring   of  the  fully qualified   type   name.
            For example,    the  following    all  match  java.lang.String:



              java.lang.String
              String
              Str



            Because   the  number     of arguments     is often  enough     to distinguish   between     each  possible   choice,   this
            shortcut can save a lot of typing, by letting you type only the shortest string that matches an
            argument     type.

            2.1.5.   Bean     Scopes

            When    you   create   a bean   definition,   you   create   a recipe   for  creating   actual   instances    of the  class
            defined   by  that  bean   definition.   The  idea  that  a bean   definition    is a recipe   is  important,   because   it
            means   that,  as with   a class, you  can  create   many    object  instances   from   a single  recipe.


            You  can  control   not  only  the  various   dependencies      and   configuration     values   that are  to  be plugged
            into an object that is created from a particular bean definition but also control the scope of the
            objects  created   from    a particular   bean   definition.   This   approach    is powerful     and  flexible,  because
            you  can  choose    the scope   of  the objects   you  create   through    configuration    instead   of  having   to bake
            in the  scope   of  an  object  at  the  Java  class  level.  Beans   can   be  defined   to  be  deployed    in  one  of  a
            number     of scopes.   The  Spring    Framework      supports    six scopes,   four   of which    are  available   only  if
            you  use  a web-aware      ApplicationContext.      You  can  also  create  a custom    scope.

            The  following   table  describes    the supported     scopes:


            Table 3. Bean   scopes

            Scope                    Description

            singleton                (Default)   Scopes   a single  bean   definition   to a single  object   instance   for each
                                     Spring   IoC  container.

            prototype                Scopes   a  single  bean  definition   to  any  number     of object  instances.

            Scope                    Description

            request                  Scopes   a  single  bean  definition   to  the lifecycle  of a single   HTTP   request.   That
                                     is, each  HTTP    request   has  its  own  instance   of a bean   created   off the  back  of  a
                                     single  bean   definition.   Only  valid  in  the context   of a web-aware      Spring
                                     ApplicationContext.

            session                  Scopes   a  single  bean  definition   to  the lifecycle  of an  HTTP    Session.  Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            application              Scopes   a  single  bean  definition   to  the lifecycle  of a ServletContext.     Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            websocket                Scopes   a  single  bean  definition   to  the lifecycle  of a WebSocket.    Only  valid  in the
                                     context   of a  web-aware     Spring   ApplicationContext.



                              As  of Spring   3.0,  a thread    scope   is available   but  is  not  registered   by   default.  For
                             more   information,     see  the  documentation       for  SimpleThreadScope.      For  instructions
                              on how    to register  this or  any  other  custom    scope,  see  Using   a Custom    Scope.



            The  Singleton    Scope

            Only  one   shared   instance    of a singleton    bean   is  managed,   and   all requests   for  beans   with   an  ID  or
            IDs that  match    that  bean   definition   result  in  that one   specific  bean   instance    being  returned    by  the
            Spring  container.


            To put  it another    way,  when    you  define   a bean   definition   and   it  is  scoped as a singleton,   the  Spring
            IoC container    creates   exactly   one  instance    of the  object  defined   by  that  bean   definition.   This  single
            instance   is stored   in a  cache   of such   singleton    beans,   and  all subsequent      requests   and   references
            for that  named    bean   return   the  cached    object.  The  following    image   shows    how   the  singleton   scope
            works:








































            Spring’s   concept   of  a singleton    bean   differs  from    the  singleton   pattern   as  defined    in the  Gang    of
            Four  (GoF)   patterns    book.  The   GoF   singleton   hard-codes     the  scope   of  an  object  such   that  one  and

            only  one  instance   of  a particular   class  is created   per  ClassLoader.     The  scope   of the  Spring   singleton
            is  best  described  as being   per-container     and   per-bean.   This  means    that,  if  you  define one  bean   for  a
            particular   class in  a single  Spring   container,   the  Spring   container    creates  one   and  only  one   instance
            of the  class  defined   by  that  bean   definition.   The   singleton   scope   is the  default   scope   in Spring.   To
            define  a bean   as  a singleton   in XML,   you   can  define  a bean   as  shown    in the  following   example:



              <bean    id="accountService"        class="com.something.DefaultAccountService"/>


              
              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="singleton"/>




            The  Prototype     Scope

            The non-singleton prototype scope of bean deployment results in the creation of a new bean
            instance every time a request for that specific bean is made. That is, the bean is injected into
            another    bean   or  you  request    it through    a getBean()    method     call on  the  container.    As  a  rule,  you
            should   use  the prototype    scope   for all stateful  beans   and   the singleton   scope   for  stateless  beans.


            The  following   diagram     illustrates  the Spring   prototype    scope:








































            (A data   access  object   (DAO)   is not  typically   configured    as  a prototype,    because    a  typical  DAO    does
            not hold   any  conversational     state. It was   easier  for us  to reuse  the  core  of the  singleton   diagram.)

            The  following   example     defines   a bean   as a prototype    in XML:



              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="prototype"/>



            In contrast   to the  other   scopes,  Spring   does   not  manage     the complete     lifecycle  of a prototype    bean.

            The  container    instantiates,   configures,    and  otherwise     assembles    a  prototype    object  and   hands   it to
            the client,  with   no  further   record   of that  prototype    instance.   Thus,   although    initialization   lifecycle
            callback   methods    are  called  on  all objects   regardless    of scope,  in  the case  of  prototypes,    configured
            destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped
            objects  and   release  expensive     resources    that  the  prototype    beans   hold.  To  get the  Spring   container
            to release  resources    held  by  prototype-scoped      beans,   try  using  a custom    bean   post-processor,     which
            holds  a reference    to beans   that  need   to be cleaned    up.


            In some   respects,   the  Spring   container’s   role  in  regard   to a prototype-scoped       bean  is a  replacement
            for the  Java  new  operator.    All lifecycle  management        past  that  point  must    be  handled    by  the  client.
            (For details  on  the  lifecycle  of a bean   in the  Spring   container,   see  Lifecycle   Callbacks.)


            Singleton    Beans   with   Prototype-bean       Dependencies

            When you use singleton-scoped beans with dependencies on prototype beans, be aware that
            dependencies     are  resolved    at instantiation    time.  Thus,   if  you dependency-inject      a  prototype-scoped
            bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-
            injected  into  the  singleton   bean.   The  prototype    instance    is  the  sole  instance that  is ever  supplied    to
            the singleton-scoped      bean.


            However,    suppose    you   want   the  singleton-scoped      bean   to acquire   a  new   instance   of the  prototype-
            scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into
            your   singleton     bean,    because    that   injection    occurs    only    once,   when     the   Spring    container
            instantiates the singleton bean and resolves and injects its dependencies. If you need a new
            instance   of a prototype    bean   at runtime    more   than   once,  see Method     Injection.


            Request,    Session,   Application,     and   WebSocket      Scopes

            The  request,   session,   application,    and   websocket   scopes   are   available   only  if you   use  a web-aware
            Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you use these
            scopes    with   regular     Spring    IoC   containers,     such   as   the   ClassPathXmlApplicationContext,           an
            IllegalStateException       that complains     about   an  unknown     bean   scope   is thrown.



            Initial  Web Configuration

            To support the scoping of beans at the request, session, application, and websocket levels (web-
            scoped beans), some minor initial configuration is required before you define your beans. (This
            initial setup  is not  required   for  the standard    scopes:   singleton   and   prototype.)


            How   you  accomplish     this  initial setup  depends    on  your   particular   Servlet  environment.


            If  you access  scoped    beans   within   Spring   Web    MVC,   in effect,  within   a request   that  is processed    by
            the  Spring   DispatcherServlet,      no  special   setup   is necessary.   DispatcherServlet       already   exposes    all
            relevant   state.


            If  you use  a  Servlet   web   container,    with  requests    processed    outside   of  Spring’s   DispatcherServlet
            (for     example,        when        using      JSF      or      Struts),     you       need       to     register      the
            org.springframework.web.context.request.RequestContextListener ServletRequestListener. This can
            be done    programmatically       by  using   the WebApplicationInitializer         interface.   Alternatively,    add  the
            following   declaration    to your   web   application’s   web.xml   file:

              <web-app>
                    ...
                    <listener>
                         <listener-class>
                               org.springframework.web.context.request.RequestContextListener
                         </listener-class>
                    </listener>
                    ...
              </web-app>



            Alternatively,     if   there    are    issues     with    your     listener     setup,    consider      using    Spring’s
            RequestContextFilter.        The    filter   mapping       depends      on   the    surrounding       web     application
            configuration,    so you   have   to change    it  as  appropriate.  The  following    listing shows    the  filter part  of
            a web   application:



              <web-app>
                    ...
                    <filter>
                         <filter-name>requestContextFilter</filter-name>
                         <filter-class>org.springframework.web.filter.RequestContextFilter</filter-
              class>
                    </filter>
                    <filter-mapping>
                         <filter-name>requestContextFilter</filter-name>
                         <url-pattern>/*</url-pattern>
                    </filter-mapping>
                    ...
              </web-app>



            DispatcherServlet,     RequestContextListener,        and   RequestContextFilter       all do  exactly   the  same   thing,
            namely    bind  the  HTTP    request   object  to  the  Thread  that  is servicing   that  request.   This  makes    beans
            that are  request-   and  session-scoped      available   further  down    the  call chain.



            Request  scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="loginAction"       class="com.something.LoginAction"              scope="request"/>



            The  Spring   container    creates   a new   instance   of  the LoginAction     bean   by using   the  loginAction    bean
            definition for each and every HTTP request. That is, the loginAction bean is scoped at the HTTP
            request   level. You  can   change   the  internal   state of  the instance    that is created   as  much   as  you  want,
            because other instances created from the same loginAction bean definition do not see these
            changes in state. They are particular to an individual request. When the request completes
            processing,   the  bean   that is scoped   to  the request   is discarded.


            When    using  annotation-driven       components      or Java  configuration,     the  @RequestScope    annotation     can

            be used   to assign  a  component     to the  request   scope.  The   following   example     shows   how   to do  so:


            Java


              @RequestScope
              @Component
              public    class   LoginAction      {
                    //  ...
              }



            Kotlin


              @RequestScope
              @Component
              class    LoginAction     {
                    //  ...
              }




            Session  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>



            The   Spring     container     creates    a  new     instance    of   the   UserPreferences       bean    by   using    the
            userPreferences bean definition for the lifetime of a single HTTP Session. In other words, the
            userPreferences     bean   is effectively   scoped   at the  HTTP    Session   level. As  with   request-scoped     beans,
            you  can  change    the  internal  state  of the  instance   that  is created   as much    as you   want,   knowing    that
            other  HTTP    Session   instances    that  are  also  using  instances    created   from   the  same    userPreferences
            bean  definition    do not  see  these  changes    in state,  because   they   are particular    to an  individual   HTTP
            Session.  When     the  HTTP   Session   is eventually    discarded,    the  bean   that  is scoped   to  that  particular
            HTTP   Session   is also discarded.


            When using annotation-driven components or Java configuration, you can use the @SessionScope
            annotation    to assign   a component      to the session   scope.


            Java


              @SessionScope
              @Component
              public    class   UserPreferences       {
                    //  ...
              }

            Kotlin


              @SessionScope
              @Component
              class    UserPreferences       {
                    //  ...
              }




            Application  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="appPreferences"        class="com.something.AppPreferences"               scope="application"/>



            The  Spring   container    creates  a  new   instance   of the  AppPreferences     bean   by  using  the  appPreferences
            bean  definition   once   for the  entire  web   application.    That  is, the appPreferences     bean   is scoped   at the
            ServletContext     level  and  stored   as a  regular   ServletContext     attribute.  This  is somewhat      similar   to a
            Spring  singleton    bean  but  differs  in two   important    ways:   It is  a singleton  per ServletContext,     not  per
            Spring   ApplicationContext      (for  which   there   may   be  several   in any   given  web   application),    and   it  is
            actually  exposed    and   therefore   visible  as a ServletContext     attribute.


            When      using     annotation-driven        components         or   Java     configuration,      you     can    use    the
            @ApplicationScope annotation to assign a component to the application scope. The following
            example    shows   how    to do so:


            Java


              @ApplicationScope
              @Component
              public    class   AppPreferences       {
                    //  ...
              }



            Kotlin


              @ApplicationScope
              @Component
              class    AppPreferences      {
                    //  ...
              }




            WebSocket    Scope

            WebSocket     scope   is associated   with   the  lifecycle  of a WebSocket      session  and   applies   to STOMP     over
            WebSocket     applications,   see  WebSocket     scope   for  more   details.

            Scoped  Beans   as Dependencies

            The  Spring   IoC  container     manages     not  only  the  instantiation    of  your   objects  (beans),   but  also  the
            wiring   up  of collaborators     (or dependencies).      If  you want   to inject  (for  example)    an  HTTP    request-
            scoped   bean   into  another    bean   of a  longer-lived    scope,  you   may   choose    to inject  an  AOP   proxy    in
            place  of  the  scoped   bean.   That   is,  you need   to  inject  a proxy    object  that  exposes    the  same   public
            interface as the scoped object but that can also retrieve the real target object from the relevant
            scope  (such   as an  HTTP   request)   and   delegate   method    calls  onto  the  real object.


                              You  may   also  use  <aop:scoped-proxy/>       between    beans   that  are  scoped   as  singleton,
                              with  the  reference    then   going   through    an  intermediate     proxy    that  is serializable
                              and  therefore   able  to  re-obtain   the target  singleton    bean  on  deserialization.


                              When declaring <aop:scoped-proxy/> against a bean of scope prototype, every
                              method    call on  the  shared    proxy   leads   to the  creation   of a  new   target  instance    to
                              which   the  call is  then being  forwarded.

                              Also, scoped    proxies   are  not  the only   way   to access  beans    from   shorter   scopes  in  a
                              lifecycle-safe fashion. You may also declare your injection point (that is, the
                             constructor    or setter  argument     or  autowired    field)  as ObjectFactory<MyTargetBean>,
                              allowing   for  a  getObject()    call to  retrieve   the  current   instance    on  demand     every
                              time  it  is  needed — without    holding    on to  the instance   or  storing  it separately.


                              As an extended variant, you may declare ObjectProvider<MyTargetBean> which
                              delivers    several     additional     access     variants,    including      getIfAvailable      and
                              getIfUnique.


                              The    JSR-330     variant     of   this    is   called    Provider     and     is   used    with     a
                              Provider<MyTargetBean> declaration and a corresponding get() call for every
                              retrieval  attempt.   See  here  for  more   details  on  JSR-330   overall.


            The  configuration     in  the following    example     is only  one   line, but  it is important    to  understand     the
            “why”   as well  as  the “how”    behind   it:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    
                    <bean   id="userPreferences"         class="com.something.UserPreferences"               scope="session">
                         
                         <aop:scoped-proxy/>         ①
                    </bean>


                    
                    <bean   id="userService"       class="com.something.SimpleUserService">
                         
                         <property     name="userPreferences"          ref="userPreferences"/>
                    </bean>
              </beans>


            ① The    line that  defines   the proxy.

            To create   such  a proxy,   you  insert  a child  <aop:scoped-proxy/>       element    into  a scoped   bean   definition
            (see Choosing the Type of Proxy to Create and XML Schema-based configuration). Why do
            definitions   of beans   scoped   at  the request,   session   and  custom-scope      levels  require   the  <aop:scoped-
            proxy/> element? Consider the following singleton bean definition and contrast it with what you
            need to define for the aforementioned scopes (note that the following userPreferences bean
            definition   as it  stands is incomplete):



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            In the  preceding    example,    the  singleton   bean   (userManager)    is injected   with  a  reference   to  the HTTP
            Session-scoped bean (userPreferences). The salient point here is that the userManager bean is a
            singleton:   it  is  instantiated exactly   once   per  container,   and   its dependencies      (in this case   only  one,
            the userPreferences bean) are also injected only once. This means that the userManager bean
            operates   only  on  the  exact  same   userPreferences      object  (that  is,  the  one  with which   it was  originally
            injected).

            This  is not  the  behavior    you   want   when    injecting   a  shorter-lived    scoped    bean   into  a longer-lived
            scoped   bean   (for  example,    injecting   an   HTTP   Session-scoped      collaborating     bean   as  a dependency
            into singleton    bean).  Rather,   you   need   a single  userManager     object,  and,  for  the lifetime   of an  HTTP
            Session,  you   need   a userPreferences      object  that  is specific  to the  HTTP    Session.   Thus,  the  container

            creates  an  object   that  exposes   the  exact   same   public   interface   as  the  UserPreferences     class  (ideally
            an  object  that  is a UserPreferences      instance),   which    can  fetch  the  real  UserPreferences      object  from
            the scoping mechanism (HTTP request, Session, and so forth). The container injects this proxy
            object  into the  userManager    bean,   which   is unaware     that  this UserPreferences     reference    is a proxy.   In
            this  example,     when     a   UserManager     instance     invokes    a   method     on   the   dependency-injected
            UserPreferences     object,  it is actually   invoking    a  method     on  the  proxy.   The  proxy    then  fetches   the
            real UserPreferences object from (in this case) the HTTP Session and delegates the method
            invocation    onto  the  retrieved   real UserPreferences      object.

            Thus, you need the following (correct and complete) configuration when injecting request- and
            session-scoped     beans   into collaborating     objects,  as the  following   example    shows:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session">
                    <aop:scoped-proxy/>
              </bean>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>




            Choosing    the  Type   of  Proxy   to  Create

            By default, when the Spring container creates a proxy for a bean that is marked up with the
            <aop:scoped-proxy/>      element,    a CGLIB-based     class  proxy   is created.


                              CGLIB   proxies   intercept    only  public   method    calls! Do   not  call non-public    methods
                             on such   a proxy.   They  are  not  delegated    to the  actual  scoped   target  object.


            Alternatively, you can configure the Spring container to create standard JDK interface-based
            proxies   for such   scoped   beans,   by  specifying   false   for the  value   of the  proxy-target-class      attribute
            of the  <aop:scoped-proxy/>      element.    Using   JDK  interface-based      proxies   means    that  you  do  not  need
            additional   libraries   in your   application    classpath    to affect  such   proxying.    However,     it also  means
            that the  class  of  the  scoped   bean   must    implement     at  least one   interface   and   that  all collaborators
            into which    the  scoped    bean   is injected   must   reference    the  bean   through    one  of  its interfaces.   The
            following   example    shows    a proxy   based   on  an  interface:



              
              <bean    id="userPreferences"        class="com.stuff.DefaultUserPreferences"                 scope="session">
                    <aop:scoped-proxy        proxy-target-class="false"/>
              </bean>


              <bean    id="userManager"       class="com.stuff.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            For   more    detailed    information      about    choosing     class-based     or  interface-based      proxying,     see
            Proxying    Mechanisms.

            Custom    Scopes

            The bean scoping mechanism is extensible. You can define your own scopes or even redefine
            existing  scopes,   although    the  latter is considered     bad  practice   and   you  cannot    override   the  built-in
            singleton   and   prototype   scopes.



            Creating  a Custom   Scope

            To   integrate    your    custom     scopes    into   the   Spring    container,     you    need    to   implement      the
            org.springframework.beans.factory.config.Scope               interface,  which    is  described  in  this section.  For  an
            idea  of how    to implement     your   own    scopes,  see  the  Scope   implementations       that  are  supplied    with
            the Spring Framework itself and the Scope javadoc, which explains the methods you need to
            implement     in more   detail.


            The  Scope   interface   has  four  methods     to  get objects   from   the  scope,   remove    them    from   the  scope,
            and  let them   be  destroyed.


            The session scope implementation, for example, returns the session-scoped bean (if it does not
            exist, the  method    returns   a new   instance   of  the bean,   after  having   bound    it  to  the  session  for  future
            reference).   The  following    method    returns   the  object  from   the underlying     scope:


            Java


              Object    get(String     name,   ObjectFactory<?>        objectFactory)



            Kotlin


              fun   get(name:     String,    objectFactory:      ObjectFactory<*>):        Any



            The session scope implementation, for example, removes the session-scoped bean from the
            underlying    session.   The   object  should    be  returned,    but  you  can   return   null  if the  object   with  the
            specified  name    is not  found.  The   following   method     removes    the  object  from   the underlying     scope:


            Java


              Object    remove(String      name)



            Kotlin


              fun   remove(name:      String):    Any



            The following method registers a callback that the scope should invoke when it is destroyed or
            when   the  specified   object  in the  scope   is  destroyed:


            Java


              void   registerDestructionCallback(String              name,    Runnable    destructionCallback)

            Kotlin


              fun   registerDestructionCallback(name:              String,    destructionCallback:        Runnable)



            See the  javadoc   or  a Spring   scope   implementation      for  more   information     on  destruction    callbacks.

            The  following   method     obtains   the conversation     identifier   for the  underlying    scope:


            Java


              String    getConversationId()



            Kotlin


              fun   getConversationId():         String



            This  identifier  is different   for  each   scope.  For  a  session   scoped   implementation,       this identifier   can
            be the  session   identifier.



            Using a Custom    Scope

            After  you  write   and   test one  or  more   custom    Scope   implementations,       you  need   to make    the  Spring
            container   aware    of your   new   scopes.   The  following    method    is the  central   method    to register   a new
            Scope  with  the  Spring   container:


            Java


              void   registerScope(String         scopeName,     Scope   scope);



            Kotlin


              fun   registerScope(scopeName:          String,    scope:    Scope)



            This  method     is declared   on   the  ConfigurableBeanFactory        interface,   which    is available   through    the
            BeanFactory property on most of the concrete ApplicationContext implementations that ship with
            Spring.


            The  first argument      to the  registerScope(..)       method    is the  unique    name    associated    with   a  scope.
            Examples of such names in the Spring container itself are singleton and prototype. The second
            argument      to   the   registerScope(..)        method      is   an   actual    instance     of   the   custom      Scope
            implementation      that  you  wish   to register  and   use.

            Suppose that you write your custom Scope implementation, and then register it as shown in the
            next  example.

                              The  next  example     uses  SimpleThreadScope,      which   is included    with  Spring   but  is not
                             registered by default. The instructions would be the same for your own custom
                              Scope  implementations.


            Java


              Scope    threadScope     =  new  SimpleThreadScope();
              beanFactory.registerScope("thread",               threadScope);



            Kotlin


              val   threadScope     =  SimpleThreadScope()
              beanFactory.registerScope("thread",               threadScope)



            You can then create bean definitions that adhere to the scoping rules of your custom Scope, as
            follows:



              <bean    id="..."    class="..."     scope="thread">



            With  a  custom   Scope   implementation,      you  are  not  limited   to programmatic      registration    of the  scope.
            You  can  also  do  the  Scope  registration   declaratively,    by  using  the  CustomScopeConfigurer       class,  as the
            following   example    shows:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    <bean   class="org.springframework.beans.factory.config.CustomScopeConfigurer">
                         <property     name="scopes">
                               <map>
                                    <entry    key="thread">
                                          <bean
              class="org.springframework.context.support.SimpleThreadScope"/>
                                    </entry>
                               </map>
                         </property>
                    </bean>


                    <bean   id="thing2"      class="x.y.Thing2"        scope="thread">
                         <property     name="name"      value="Rick"/>
                         <aop:scoped-proxy/>
                    </bean>


                    <bean   id="thing1"      class="x.y.Thing1">
                         <property     name="thing2"      ref="thing2"/>
                    </bean>


              </beans>




                              When    you  place   <aop:scoped-proxy/>       within   a <bean>   declaration    for a  FactoryBean
                             implementation,      it is the factory   bean   itself that  is scoped,   not  the  object  returned
                              from  getObject().


            2.1.6.   Customizing          the   Nature       of  a Bean

            The  Spring   Framework       provides    a number     of  interfaces   you   can  use  to  customize    the  nature   of  a
            bean.  This  section   groups   them   as follows:

              • Lifecycle   Callbacks

              • ApplicationContextAware        and  BeanNameAware

              • Other   Aware  Interfaces


            Lifecycle   Callbacks

            To  interact  with   the  container’s    management       of  the bean    lifecycle,  you  can   implement     the  Spring
            InitializingBean and DisposableBean interfaces. The container calls afterPropertiesSet() for the

            former   and   destroy()    for the  latter  to let the  bean   perform     certain  actions   upon    initialization  and
            destruction    of your  beans.


                              The  JSR-250   @PostConstruct      and  @PreDestroy     annotations     are  generally   considered
                              best practice   for receiving    lifecycle  callbacks   in a modern     Spring   application.   Using
                              these annotations means that your beans are not coupled to Spring-specific
                             interfaces.  For  details,  see Using   @PostConstruct     and   @PreDestroy.


                              If you do not want to use the JSR-250 annotations but you still want to remove
                              coupling,   consider   init-method    and   destroy-method     bean   definition   metadata.


            Internally,  the  Spring   Framework       uses  BeanPostProcessor       implementations       to process   any   callback
            interfaces it can find and call the appropriate methods. If you need custom features or other
            lifecycle  behavior    Spring  does   not  by default   offer, you   can  implement     a BeanPostProcessor      yourself.
            For more    information,    see  Container    Extension    Points.


            In addition to the initialization and destruction callbacks, Spring-managed objects may also
            implement     the  Lifecycle   interface   so  that those   objects  can  participate    in the  startup  and   shutdown
            process,  as  driven   by the  container’s    own   lifecycle.


            The  lifecycle  callback   interfaces   are  described    in this section.



            Initialization Callbacks

            The     org.springframework.beans.factory.InitializingBean                   interface     lets    a    bean      perform
            initialization    work    after   the   container     has   set   all  necessary     properties     on   the   bean.    The
            InitializingBean     interface   specifies   a single  method:



              void   afterPropertiesSet()         throws    Exception;



            We  recommend       that  you  do  not  use  the InitializingBean      interface,   because   it unnecessarily     couples
            the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a
            POJO   initialization  method.    In  the  case  of XML-based      configuration    metadata,    you   can  use  the  init-
            method attribute to specify the name of the method that has a void no-argument signature. With
            Java  configuration,    you   can  use  the  initMethod    attribute   of @Bean.  See  Receiving    Lifecycle   Callbacks.
            Consider   the  following    example:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            init-method="init"/>



            Java


              public    class   ExampleBean      {


                    public   void   init()    {
                         //  do   some  initialization       work
                    }
              }

            Kotlin


              class    ExampleBean     {


                    fun  init()    {
                         //  do   some  initialization       work
                    }
              }



            The  preceding    example     has  almost   exactly  the  same   effect  as the  following    example    (which   consists
            of two  listings):



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     InitializingBean        {


                    @Override
                    public   void   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            Kotlin


              class    AnotherExampleBean        : InitializingBean        {


                    override    fun   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            However,    the  first of the  two  preceding    examples     does  not  couple   the  code  to Spring.



            Destruction   Callbacks

            Implementing the org.springframework.beans.factory.DisposableBean interface lets a bean get a
            callback   when    the  container    that  contains   it is destroyed.    The   DisposableBean     interface   specifies   a
            single  method:



              void   destroy()     throws    Exception;



            We  recommend       that  you   do  not  use  the DisposableBean      callback   interface,  because    it unnecessarily
            couples   the  code  to Spring.   Alternatively,    we  suggest   using   the @PreDestroy     annotation    or  specifying
            a generic   method     that  is supported     by  bean   definitions.   With   XML-based      configuration     metadata,
            you  can   use  the  destroy-method     attribute   on  the  <bean/>.   With   Java  configuration,     you   can  use  the

            destroyMethod      attribute    of  @Bean.   See    Receiving     Lifecycle    Callbacks.    Consider     the   following
            definition:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            destroy-method="cleanup"/>



            Java


              public    class   ExampleBean      {


                    public   void   cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    ExampleBean     {


                    fun  cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            The  preceding    definition   has  almost   exactly   the same    effect as  the following    definition:



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     DisposableBean       {


                    @Override
                    public   void   destroy()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    AnotherExampleBean        : DisposableBean       {


                    override    fun   destroy()    {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }

            However,    the  first of the  two  preceding    definitions   does   not  couple   the code   to Spring.


                              You  can  assign   the destroy-method     attribute   of a <bean>   element    a special  (inferred)
                              value, which instructs Spring to automatically detect a public close or shutdown
                              method       on     the    specific     bean      class.     (Any     class     that    implements
                              java.lang.AutoCloseable or java.io.Closeable would therefore match.) You can
                             also  set this  special  (inferred)    value   on  the  default-destroy-method        attribute   of  a
                              <beans> element to apply this behavior to an entire set of beans (see Default
                              Initialization  and   Destroy   Methods).    Note   that this  is  the  default behavior   with   Java
                              configuration.



            Default  Initialization and  Destroy  Methods

            When you write initialization and destroy method callbacks that do not use the Spring-specific
            InitializingBean      and  DisposableBean      callback   interfaces,   you   typically   write  methods     with   names
            such as init(), initialize(), dispose(), and so on. Ideally, the names of such lifecycle callback
            methods    are  standardized      across  a  project  so  that  all developers    use   the same    method    names    and
            ensure   consistency.


            You can configure the Spring container to “look” for named initialization and destroy callback
            method names on every bean. This means that you, as an application developer, can write your
            application    classes  and   use  an  initialization   callback   called  init(),   without   having    to configure    an
            init-method="init"      attribute   with  each   bean   definition.   The  Spring    IoC container    calls  that  method
            when   the  bean   is created   (and  in accordance     with   the standard    lifecycle  callback   contract   described
            previously).   This  feature   also enforces    a consistent   naming     convention    for  initialization   and  destroy
            method    callbacks.

            Suppose that your initialization callback methods are named init() and your destroy callback
            methods    are  named    destroy().   Your   class then   resembles    the  class  in the following    example:


            Java


              public    class   DefaultBlogService        implements     BlogService      {


                    private    BlogDao    blogDao;


                    public   void   setBlogDao(BlogDao        blogDao)     {
                         this.blogDao      =  blogDao;
                    }


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    public   void   init()    {
                         if  (this.blogDao       ==  null)   {
                               throw   new   IllegalStateException("The           [blogDao]    property     must   be  set.");
                         }
                    }
              }

            Kotlin


              class    DefaultBlogService        : BlogService      {


                    private    var  blogDao:     BlogDao?    =  null


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    fun  init()    {
                         if  (blogDao     ==  null)   {
                               throw   IllegalStateException("The           [blogDao]     property    must   be  set.")
                         }
                    }
              }



            You  could  then   use  that class  in a bean   resembling     the  following:



              <beans    default-init-method="init">


                    <bean   id="blogService"       class="com.something.DefaultBlogService">
                         <property     name="blogDao"       ref="blogDao"      />
                    </bean>


              </beans>



            The  presence    of the  default-init-method      attribute   on  the  top-level  <beans/>    element   attribute   causes
            the  Spring   IoC  container    to recognize     a method     called  init  on  the  bean    class  as the  initialization
            method    callback.   When    a  bean   is  created  and  assembled,     if the bean    class has   such  a  method,    it  is
            invoked   at the  appropriate     time.


            You can configure destroy method callbacks similarly (in XML, that is) by using the default-
            destroy-method     attribute  on  the  top-level  <beans/>    element.


            Where    existing   bean   classes   already   have   callback    methods    that  are   named    at  variance    with  the
            convention,    you   can  override   the  default   by  specifying   (in  XML,   that  is) the method     name    by using
            the init-method    and   destroy-method     attributes   of the  <bean/>  itself.


            The  Spring   container    guarantees    that  a configured    initialization   callback   is called  immediately     after
            a bean   is supplied   with   all dependencies.     Thus,   the  initialization  callback    is  called on  the raw   bean
            reference,   which   means    that  AOP   interceptors    and   so forth  are  not  yet  applied   to the  bean.  A  target
            bean  is fully  created   first and  then  an  AOP   proxy   (for  example)    with  its interceptor    chain   is  applied.
            If  the  target bean   and  the  proxy    are  defined   separately,   your   code   can  even   interact   with  the  raw
            target  bean,   bypassing    the  proxy.   Hence,   it would    be  inconsistent    to  apply   the  interceptors    to the
            init method, because doing so would couple the lifecycle of the target bean to its proxy or
            interceptors and leave strange semantics when your code interacts directly with the raw target
            bean.

---

### Spring Ai Docs/Src/Main/Antora/Antora Playbook.Yml (spring-ai-docs/src/main/antora/antora-playbook.yml)

# PACKAGES antora@3.2.0-alpha.6 @antora/atlas-extension:1.0.0-alpha.1 @antora/collector-extension@1.0.0-alpha.3 @springio/antora-extensions@1.1.0-alpha.2 @asciidoctor/tabs@1.0.0-alpha.12 @opendevise/antora-release-line-extension@1.0.0-alpha.2
#
# The purpose of this Antora playbook is to build the docs in the current branch.
antora:
  extensions:
    - '@antora/collector-extension'
    # - require: '@springio/antora-extensions/root-component-extension'
    - require: '@springio/antora-extensions'
      root_component_name: 'ai'
site:
  title: Spring AI Reference
  url: https://docs.spring.io/spring-ai/reference
  robots: allow
git:
  ensure_git_suffix: false  
content:
  sources:
    - url: ./../../../..
      branches: HEAD
      start_path: spring-ai-docs/src/main/antora
      worktrees: true
asciidoc:
  attributes:
    page-related-doc-categories: ai,java,ml
    page-pagination: ''
    hide-uri-scheme: '@'
    tabs-sync-option: '@'
    chomp: 'all'
    stem: 'asciimath'
  extensions:
    - '@asciidoctor/tabs'
    - '@springio/asciidoctor-extensions'
    - '@springio/asciidoctor-extensions/javadoc-extension'
    - '@springio/asciidoctor-extensions/include-code-extension'
    - '@djencks/asciidoctor-mathjax'
  sourcemap: true
urls:
  latest_version_segment_strategy: redirect:to
  latest_version_segment: ''
  redirect_facility: httpd
runtime:
  log:
    failure_level: warn
    format: pretty
ui:
  bundle:
    url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.17/ui-bundle.zip
    snapshot: true

---

### Spring Ai Docs/Src/Main/Antora/Antora.Yml (spring-ai-docs/src/main/antora/antora.yml)

name: ai
version: true
title: Spring AI
nav:
  - modules/ROOT/nav.adoc
ext:
  collector:
    - run:
        command: mvnw process-resources
        local: true
      scan:
        dir: spring-ai-docs/target/classes/antora-resources

---

### Spring Ai Docs/Src/Main/Antora/Resources/Antora Resources/Antora.Yml (spring-ai-docs/src/main/antora/resources/antora-resources/antora.yml)

version: ${antora-component.version}
prerelease: ${antora-component.prerelease}

---

### Spring Ai Docs/Src/Main/Asciidoc/Mcp (spring-ai-docs/src/main/asciidoc/mcp.md)

# Model Context Protocol (MCP) Server

The Spring AI MCP module provides integration with the Model Context Protocol, allowing you to expose your AI tools and resources through a standardized protocol. This module is particularly useful when you want to make your Spring AI tools and resources available to MCP-compatible clients.

## Dependencies

To use the MCP server functionality, add the following dependency to your project:

```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server</artifactId>
    <version>${spring-ai.version}</version>
</dependency>
```

## Configuration Properties

The MCP server can be configured using the following properties under the `spring.ai.mcp.server` prefix:

| Property | Default | Description |
|----------|---------|-------------|
| `enabled` | `false` | Enable/disable the MCP server |
| `name` | `"mcp-server"` | Name of the MCP server |
| `version` | `"1.0.0"` | Version of the MCP server |
| `type` | `SYNC` | Server type (`SYNC` or `ASYNC`) |
| `resource-change-notification` | `true` | Enable/disable resource change notifications |
| `tool-change-notification` | `true` | Enable/disable tool change notifications |
| `prompt-change-notification` | `true` | Enable/disable prompt change notifications |
| `transport` | `STDIO` | Transport type (`STDIO`, `WEBMVC`, or `WEBFLUX`) |
| `sse-message-endpoint` | `"/mcp/message"` | Server-Sent Events (SSE) message endpoint for web transports |

## Server Types

The MCP server supports two operation modes:

### 1. Synchronous Mode (Default)

The synchronous mode is the default option, suitable for most use cases where tools and resources are accessed sequentially:

```yaml
spring:
  ai:
    mcp:
      server:
        type: SYNC
```

### 2. Asynchronous Mode

The asynchronous mode is designed for reactive applications and scenarios requiring non-blocking operations:

```yaml
spring:
  ai:
    mcp:
      server:
        type: ASYNC
```

## Transport Options

The MCP server supports three transport types:

### 1. STDIO Transport (Default)

The Standard Input/Output transport is the default option, suitable for command-line tools and local development:

```yaml
spring:
  ai:
    mcp:
      server:
        transport: STDIO
```

### 2. WebMvc Transport

The WebMvc transport uses Spring MVC's Server-Sent Events (SSE) for communication:

```yaml
spring:
  ai:
    mcp:
      server:
        transport: WEBMVC
        sse-message-endpoint: /mcp/message  # Optional, defaults to /mcp/message
```

Required dependencies:
```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>mcp-spring-webmvc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
```

### 3. WebFlux Transport

The WebFlux transport uses Spring WebFlux's Server-Sent Events for reactive communication:

```yaml
spring:
  ai:
    mcp:
      server:
        transport: WEBFLUX
        sse-message-endpoint: /mcp/message  # Optional, defaults to /mcp/message
```

Required dependencies:
```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>mcp-spring-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
```

## Core Features

The MCP server provides several core features:

### Tools

- Extensible tool registration system supporting both sync and async execution
- Automatic tool discovery and registration through Spring's component scanning
- Change notification support for tool updates

### Resources

- Static and dynamic resource management
- Optional change notifications for resource updates
- Support for both sync and async resource access

### Prompts

- Configurable prompt templates
- Change notification support for template updates
- Integration with Spring AI's prompt system

## Usage Example

Here's an example of configuring the MCP server with WebMvc transport and custom settings:

```yaml
spring:
  ai:
    mcp:
      server:
        enabled: true
        name: "My AI Tools Server"
        version: "1.0.0"
        type: SYNC
        transport: WEBMVC
        sse-message-endpoint: /ai/mcp/events
        resource-change-notification: true
        tool-change-notification: true
        prompt-change-notification: false
```

## Auto-configuration

The MCP server auto-configuration is provided through:

1. `McpServerAutoConfiguration`: Core server configuration supporting both sync and async modes
2. `McpWebMvcServerAutoConfiguration`: WebMvc transport configuration (activated when WebMvc dependencies are present)
3. `McpWebFluxServerAutoConfiguration`: WebFlux transport configuration (activated when WebFlux dependencies are present)

The auto-configuration will automatically set up the appropriate server type and transport based on your configuration and available dependencies.

## Implementing Tools and Resources

To expose your Spring AI tools and resources through the MCP server:

1. Implement the `ToolCallback` interface for your AI tools:
```java
@Component
public class MyAiTool implements ToolCallback {
    // Implementation
}
```

2. The auto-configuration will automatically discover and register your tools with the MCP server, converting them to either sync or async implementations based on your server type configuration.

## Monitoring

The MCP server provides notifications for changes in:
- Tools (when tools are added or removed)
- Resources (when resources are updated)
- Prompts (when prompt templates change)

You can enable/disable these notifications using the configuration properties. The notification system works with both sync and async server types, providing consistent change tracking regardless of the chosen operation mode.

---

### Spring Ai Integration Tests/Src/Test/Resources/Application.Yml (spring-ai-integration-tests/src/test/resources/application.yml)

spring:
  main:
    web-application-type: none
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o-mini
      embedding:
        options:
          model: text-embedding-ada-002
    retry:
      max-attempts: 3
    vectorstore:
      pgvector:
        initialize-schema: true

---

### Spring Ai Integration Tests/Src/Test/Resources/Documents/Knowledge Base (spring-ai-integration-tests/src/test/resources/documents/knowledge-base.md)

# Anacletus and Birba's Quest for the Loch of the Stars

## Chapter 1: The Map and the Adventure

Once upon a time, in a cozy little cottage nestled at the edge of the Scottish Highlands, lived an owl named Anacletus and a curious cat named Birba. Anacletus was wise and careful, always reading maps and planning things thoroughly, while Birba was lively and adventurous, always ready to chase after the next interesting thing. Despite their differences, they were the best of friends and loved going on little adventures together.

## Chapter 2: The Journey Begins

One sunny morning, Anacletus showed Birba an old, crinkled map he’d found in the attic. “Look, Birba,” he said, pointing with his feathery wing. “This map leads to the legendary Loch of the Stars. They say it shines brighter than any other lake at night.” Birba’s eyes sparkled with excitement. “Oh, we have to go there!” she meowed. So, they packed a small bag with snacks, a compass, and a flashlight, and off they went, eager to find the legendary loch.

## Chapter 3: The Highland Adventure

Their journey began with a climb up the rolling hills covered in purple heather. Anacletus flapped his wings, soaring ahead to scout for any obstacles, while Birba trotted along below, her nose sniffing the air for interesting scents. Soon, they came across a bubbling brook. Anacletus carefully flew over it, but Birba hesitated. “Just a little jump!” Anacletus called out. With a deep breath, Birba leaped and landed safely on the other side. She purred proudly, and they continued on their way.

## Chapter 4: The Highland Cows and the Hidden Path

As they ventured deeper into the Highlands, they stumbled upon a herd of curious Highland cows with long, shaggy hair. The cows mooed softly, and one of them named Fergus approached. “Where are you two headed?” Fergus asked. “We’re searching for the Loch of the Stars!” Anacletus replied. Fergus nodded knowingly and pointed his nose north. “Follow the path by the big stones, and it will lead you closer to the loch,” he said. Thanking Fergus, they set off again, Birba occasionally stopping to bat at the fluttering butterflies along the way.

## Chapter 5: The Mysterious Forest and the Deer Family

The day wore on, and they soon found themselves in a mysterious forest. Tall, ancient pine trees surrounded them, casting long shadows. “Stay close, Birba,” Anacletus whispered, his wise eyes scanning for any sign of danger. But Birba had already darted after a flicker of light, thinking it was a firefly. Anacletus sighed and followed her until they came to a hidden glade where a family of deer grazed quietly. The smallest fawn looked up and gave them a curious nod before they moved along.

## Chapter 6: The Loch of the Stars

After a while, the sun began to set, painting the sky in shades of pink and gold. Anacletus decided it was a good time to rest. They found a cozy hollow at the base of a tree, where they shared the snacks they’d packed. Birba munched on her fish treats while Anacletus nibbled on a biscuit. “Do you think we’ll find the Loch of the Stars?” Birba asked, her eyes twinkling. “I think so,” Anacletus replied with a wise smile. “We’re getting closer.”

## Chapter 7: The Shimmering Loch

As night fell, they finally reached the top of a hill where they could see a shimmering light in the distance. “Look, Birba!” Anacletus hooted excitedly. There, nestled among the hills, was the Loch of the Stars, gleaming like a sky full of stars. The two friends hurried down to the water’s edge, marveling at how the loch sparkled under the moonlight, casting a gentle glow all around.

## Chapter 8: The Magic of the Loch

Birba dipped a curious paw into the water, causing ripples that sent stars dancing across the surface. “It’s beautiful!” she gasped. Anacletus nodded, his heart filled with awe. They spent the night by the loch, watching the shimmering stars reflected in the water, feeling as though they were surrounded by magic.

## Chapter 9: The Journey Home

When dawn broke, the shimmering loch returned to its quiet, glassy calm. With a satisfied yawn, Birba stretched and said, “That was the best adventure yet.” Anacletus agreed, feeling a warmth in his feathers as they turned back toward home, carrying memories of the Loch of the Stars in their hearts.

## Chapter 10: The End of the Adventure

And as they made their way back to their cozy cottage, they already started dreaming of their next big adventure—because Anacletus and Birba knew that the Scottish Highlands held endless wonders for those who dared to explore.

---

### Spring Ai Model/Src/Test/Resources/Text Source (spring-ai-model/src/test/resources/text_source.txt)

Spring                 Framework                               Documentation


                                                                                                                        Version    6.0.0

            Chapter                1.    Spring              Framework                         Overview


            Spring makes it easy to create Java enterprise applications. It provides everything you need to
            embrace    the  Java   language    in  an  enterprise    environment,      with   support   for  Groovy    and   Kotlin   as
            alternative languages on the JVM, and with the flexibility to create many kinds of architectures
            depending     on  an  application’s    needs.  As  of  Spring   Framework      5.1, Spring   requires    JDK  8+  (Java  SE
            8+) and provides out-of-the-box support for JDK 11 LTS. Java SE 8 update 60 is suggested as the
            minimum      patch  release   for Java  8, but  it is  generally  recommended       to  use a  recent  patch   release.

            Spring  supports    a wide   range   of application    scenarios.   In  a large  enterprise,   applications    often  exist
            for a  long  time   and   have   to run   on  a  JDK  and   application    server   whose    upgrade     cycle  is beyond
            developer    control.   Others   may    run  as  a single   jar with   the  server   embedded,      possibly   in  a cloud
            environment.      Yet others   may    be standalone     applications    (such   as  batch   or integration    workloads)
            that do  not  need   a server.


            Spring  is open   source.   It  has  a large  and active  community      that  provides   continuous     feedback    based
            on a  diverse   range  of  real-world   use  cases.  This  has  helped    Spring  to  successfully   evolve   over  a  very
            long  time.

            1.1.    What          We      Mean          by    "Spring"


            The  term   "Spring"   means    different   things  in  different   contexts.  It can  be  used   to refer  to the  Spring
            Framework      project   itself,  which  is where    it  all  started.  Over time,  other  Spring   projects   have   been
            built on  top  of  the Spring    Framework.      Most   often,  when    people   say  "Spring",   they  mean    the  entire
            family  of  projects.  This  reference    documentation       focuses   on  the foundation:     the  Spring   Framework
            itself.


            The  Spring   Framework      is divided   into  modules.    Applications     can  choose   which    modules    they  need.
            At the heart are the modules of the core container, including a configuration model and a
            dependency injection mechanism. Beyond that, the Spring Framework provides foundational
            support    for   different    application     architectures,     including    messaging,      transactional     data   and
            persistence, and web. It also includes the Servlet-based Spring MVC web framework and, in
            parallel, the  Spring   WebFlux     reactive   web   framework.


            A note about modules: Spring’s framework jars allow for deployment to JDK 9’s module path
            ("Jigsaw"). For use in Jigsaw-enabled applications, the Spring Framework 5 jars come with
            "Automatic-Module-Name" manifest entries which define stable language-level module names
            ("spring.core",   "spring.context",     etc.) independent     from    jar artifact  names    (the  jars follow   the  same
            naming    pattern   with   "-" instead   of  ".",  e.g.  "spring-core"  and   "spring-context").    Of  course,   Spring’s
            framework     jars  keep  working    fine  on  the  classpath   on  both  JDK  8  and  9+.

            1.2.    History            of   Spring          and       the      Spring          Framework


            Spring came into being in 2003 as a response to the complexity of the early J2EE specifications.
            While   some    consider   Java   EE  and   its modern-day      successor    Jakarta   EE  to  be  in  competition     with
            Spring, they are in fact complementary. The Spring programming model does not embrace the
            Jakarta    EE   platform      specification;    rather,    it  integrates     with    carefully    selected    individual

            specifications   from   the  traditional   EE  umbrella:


              • Servlet  API   (JSR 340)

              • WebSocket     API  (JSR  356)

              • Concurrency      Utilities (JSR  236)

              • JSON   Binding    API  (JSR 367)

              • Bean   Validation   (JSR  303)

              • JPA  (JSR  338)

              • JMS   (JSR 914)

              • as well  as  JTA/JCA   setups  for  transaction    coordination,    if necessary.


            The  Spring   Framework      also  supports    the Dependency       Injection   (JSR 330)  and   Common      Annotations
            (JSR 250) specifications, which application developers may choose to use instead of the Spring-
            specific  mechanisms      provided     by the  Spring   Framework.       Originally,  those   were   based   on  common
            javax  packages.

            As  of Spring   Framework       6.0, Spring   has  been   upgraded     to  the Jakarta   EE   9 level  (e.g. Servlet   5.0+,
            JPA  3.0+), based    on  the  jakarta   namespace      instead   of the  traditional   javax   packages.    With   EE  9  as
            the  minimum      and   EE  10  supported     already,   Spring   is prepared     to provide    out-of-the-box     support
            for the further evolution of the Jakarta EE APIs. Spring Framework 6.0 is fully compatible with
            Tomcat   10.1,  Jetty 11  and  Undertow     2.3  as web   servers,   and  also  with  Hibernate    ORM    6.1.


            Over   time,  the role  of  Java/Jakarta    EE  in application    development      has  evolved.    In the  early  days   of
            J2EE  and   Spring,  applications    were   created   to  be deployed     to an  application    server.  Today,   with  the
            help  of Spring   Boot,   applications    are  created   in a  devops-   and   cloud-friendly     way,  with   the  Servlet
            container   embedded      and   trivial  to change.   As  of  Spring   Framework      5, a  WebFlux     application    does
            not  even   use  the  Servlet   API  directly   and   can  run   on  servers   (such   as  Netty)  that  are  not   Servlet
            containers.


            Spring  continues    to  innovate   and   to evolve.  Beyond     the Spring   Framework,      there  are  other   projects,
            such as Spring Boot, Spring Security, Spring Data, Spring Cloud, Spring Batch, among others. It’s
            important to remember that each project has its own source code repository, issue tracker, and
            release  cadence.    See  spring.io/projects    for the  complete    list of Spring   projects.

            1.3.    Design           Philosophy


            When you learn about a framework, it’s important to know not only what it does but what
            principles   it  follows. Here  are  the  guiding   principles   of the  Spring   Framework:


              • Provide choice at every level. Spring lets you defer design decisions as late as possible. For
                example, you can switch persistence providers through configuration without changing your
                code.  The   same   is true  for  many   other   infrastructure     concerns    and  integration    with  third-party
                APIs.

              • Accommodate diverse perspectives. Spring embraces flexibility and is not opinionated about
                how things should be done. It supports a wide range of application needs with different
                perspectives.

              • Maintain strong backward compatibility. Spring’s evolution has been carefully managed to
                force  few   breaking    changes    between    versions.   Spring    supports   a  carefully   chosen   range   of  JDK
                versions and third-party libraries to facilitate maintenance of applications and libraries that
                depend    on  Spring.

              • Care   about  API   design.  The  Spring   team   puts   a lot of thought   and   time  into  making    APIs  that  are
                intuitive  and   that  hold  up  across  many    versions   and   many    years.

              • Set high standards for code quality. The Spring Framework puts a strong emphasis on
                meaningful,     current,   and   accurate    javadoc.   It is one   of very   few  projects   that  can   claim   clean
                code   structure   with  no  circular   dependencies     between     packages.

            1.4.    Feedback               and       Contributions


            For how-to questions or diagnosing or debugging issues, we suggest using Stack Overflow. Click
            here  for  a list of the  suggested    tags  to use  on  Stack   Overflow.    If  you’re fairly  certain   that there   is a
            problem    in the  Spring   Framework      or would    like to suggest   a feature,   please  use  the  GitHub    Issues.

            If you have a solution in mind or a suggested fix, you can submit a pull request on Github.
            However,    please   keep   in mind    that, for  all but  the  most   trivial issues,  we  expect   a  ticket to  be  filed
            in the issue  tracker,   where   discussions    take  place  and   leave  a record   for  future  reference.


            For more    details  see the  guidelines    at the CONTRIBUTING,         top-level  project  page.

            1.5.    Getting           Started


            If  you are  just getting   started   with  Spring,   you  may    want   to begin   using   the  Spring   Framework      by
            creating a Spring Boot-based application. Spring Boot provides a quick (and opinionated) way to
            create a production-ready Spring-based application. It is based on the Spring Framework, favors
            convention    over   configuration,    and  is designed    to get  you  up  and  running    as  quickly  as  possible.


            You  can  use  start.spring.io    to generate    a basic  project   or follow   one  of  the  "Getting   Started"  guides,
            such as Getting Started Building a RESTful Web Service. As well as being easier to digest, these
            guides   are  very   task  focused,   and   most   of them    are  based   on   Spring   Boot.  They   also   cover   other
            projects from the Spring portfolio that you might want to consider when solving a particular
            problem.

            Chapter                2.    Core           Technologies


            This  part  of the  reference    documentation       covers   all  the  technologies   that  are  absolutely   integral   to
            the Spring   Framework.


            Foremost    amongst    these   is  the  Spring Framework’s      Inversion    of Control   (IoC)  container.   A  thorough
            treatment    of the  Spring   Framework’s      IoC  container    is closely  followed    by  comprehensive       coverage
            of Spring’s   Aspect-Oriented      Programming        (AOP)   technologies.    The   Spring   Framework       has  its own
            AOP framework, which is conceptually easy to understand and which successfully addresses the
            80%   sweet  spot  of AOP   requirements      in Java   enterprise   programming.


            Coverage of Spring’s integration with AspectJ (currently the richest — in terms of features — and
            certainly  most   mature    AOP   implementation       in the  Java  enterprise   space)   is also provided.


            AOT processing can be used to optimize your application ahead-of-time. It is typically used for
            native  image   deployment      using  GraalVM.

            2.1.    The       IoC      Container


            This  chapter   covers   Spring’s  Inversion    of Control   (IoC)  container.


            2.1.1.   Introduction          to  the   Spring      IoC   Container        and    Beans

            This chapter covers the Spring Framework implementation of the Inversion of Control (IoC)
            principle. IoC is also known as dependency injection (DI). It is a process whereby objects define
            their dependencies      (that  is, the other   objects   they  work   with)   only  through    constructor    arguments,
            arguments to a factory method, or properties that are set on the object instance after it is
            constructed or returned from a factory method. The container then injects those dependencies
            when   it creates   the  bean.  This   process   is fundamentally      the  inverse   (hence   the  name,    Inversion    of
            Control) of the bean itself controlling the instantiation or location of its dependencies by using
            direct  construction    of classes  or  a mechanism      such   as the  Service  Locator    pattern.


            The  org.springframework.beans         and   org.springframework.context         packages     are  the  basis  for  Spring
            Framework’s       IoC   container.     The   BeanFactory      interface    provides     an   advanced      configuration
            mechanism capable of managing any type of object. ApplicationContext is a sub-interface of
            BeanFactory.   It adds:


              • Easier   integration   with  Spring’s   AOP   features

              • Message    resource    handling    (for use  in internationalization)

              • Event   publication

              • Application-layer       specific    contexts    such     as  the    WebApplicationContext         for   use   in   web
                applications.


            In short, the BeanFactory provides the configuration framework and basic functionality, and the
            ApplicationContext       adds    more     enterprise-specific      functionality.     The    ApplicationContext        is  a
            complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of
            Spring’s    IoC   container.     For    more     information      on    using    the   BeanFactory      instead    of   the

            ApplicationContext,      see  the  section  covering    the BeanFactory    API.


            In Spring, the objects that form the backbone of your application and that are managed by the
            Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and
            managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your
            application.   Beans,   and   the dependencies      among     them,   are  reflected   in the  configuration    metadata
            used  by  a container.


            2.1.2.   Container        Overview

            The  org.springframework.context.ApplicationContext                interface   represents    the  Spring   IoC  container
            and  is responsible     for instantiating,    configuring,    and   assembling     the  beans.   The  container    gets  its
            instructions on what objects to instantiate, configure, and assemble by reading configuration
            metadata.    The  configuration     metadata     is  represented   in  XML,   Java  annotations,    or  Java  code.  It lets
            you express the objects that compose your application and the rich interdependencies between
            those  objects.


            Several implementations of the ApplicationContext interface are supplied with Spring. In stand-
            alone applications, it is common to create an instance of ClassPathXmlApplicationContext or
            FileSystemXmlApplicationContext.           While     XML     has   been     the   traditional    format     for   defining
            configuration metadata, you can instruct the container to use Java annotations or code as the
            metadata    format   by  providing    a small   amount    of XML    configuration    to  declaratively   enable    support
            for these  additional    metadata    formats.


            In most application scenarios, explicit user code is not required to instantiate one or more
            instances   of a  Spring   IoC  container.    For  example,    in a  web   application    scenario,   a simple   eight   (or
            so) lines  of boilerplate    web   descriptor    XML    in the  web.xml    file of the  application    typically   suffices
            (see Convenient     ApplicationContext       Instantiation    for Web    Applications).    If you  use  the  Spring   Tools
            for Eclipse   (an  Eclipse-powered       development      environment),      you   can  easily  create   this  boilerplate
            configuration    with   a few  mouse    clicks  or keystrokes.


            The  following    diagram    shows    a high-level    view   of how   Spring    works.   Your   application    classes  are
            combined with configuration metadata so that, after the ApplicationContext is created and
            initialized,  you  have   a fully configured    and   executable    system   or  application.

            Figure  1.  The  Spring IoC container


            Configuration      Metadata

            As the preceding diagram shows, the Spring IoC container consumes a form of configuration
            metadata. This configuration metadata represents how you, as an application developer, tell the
            Spring  container    to instantiate,   configure,   and   assemble    the  objects  in your   application.


            Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is
            what   most  of  this chapter   uses  to convey    key  concepts    and  features   of the  Spring   IoC container.


                              XML-based     metadata     is not  the  only  allowed    form   of configuration     metadata.     The
                              Spring IoC container itself is totally decoupled from the format in which this
                             configuration metadata is actually written. These days, many developers choose
                              Java-based    configuration    for  their  Spring  applications.


            For information     about   using   other  forms   of metadata     with  the  Spring   container,   see:


              • Annotation-based         configuration:       Spring     2.5   introduced      support      for   annotation-based
                configuration     metadata.

              • Java-based configuration: Starting with Spring 3.0, many features provided by the Spring
                JavaConfig project became part of the core Spring Framework. Thus, you can define beans
                external to your application classes by using Java rather than XML files. To use these new
                features,   see the  @Configuration,     @Bean,  @Import,  and   @DependsOn   annotations.

            Spring   configuration     consists  of  at least  one   and  typically   more    than  one   bean   definition   that  the
            container must manage. XML-based configuration metadata configures these beans as <bean/>
            elements inside a top-level <beans/> element. Java configuration typically uses @Bean-annotated
            methods    within   a @Configuration     class.

            These   bean   definitions    correspond     to the  actual   objects   that  make   up   your   application.   Typically,
            you define service layer objects, data access objects (DAOs), presentation objects such as Struts
            Action instances, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so
            forth. Typically,   one   does  not  configure    fine-grained     domain    objects   in the  container,    because    it  is

            usually   the responsibility    of  DAOs   and   business    logic  to create  and   load  domain     objects.  However,
            you  can   use  Spring’s   integration    with  AspectJ    to configure    objects   that  have   been   created   outside
            the control   of an  IoC  container.   See  Using   AspectJ   to dependency-inject      domain     objects  with  Spring.


            The  following   example     shows   the  basic  structure   of XML-based      configuration     metadata:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="..."    class="...">      ①   ②
                         
                    </bean>


                    <bean   id="..."    class="...">
                         
                    </bean>


                    


              </beans>


            ① The    id attribute   is a string  that identifies   the individual    bean   definition.

            ② The    class  attribute   defines   the type  of the  bean   and  uses   the fully  qualified   classname.

            The  value   of the  id attribute   refers   to collaborating    objects.  The   XML    for referring   to  collaborating
            objects  is not shown    in  this example.    See  Dependencies      for more    information.


            Instantiating    a  Container

            The  location   path   or paths   supplied    to an  ApplicationContext       constructor    are  resource    strings  that
            let  the  container  load  configuration     metadata    from   a variety   of external   resources,    such  as  the local
            file  system, the  Java  CLASSPATH,   and   so on.


            Java


              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");



            Kotlin


              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")

                              After  you  learn   about   Spring’s   IoC  container,    you   may   want   to  know   more    about
                              Spring’s   Resource     abstraction     (as  described     in  Resources),     which     provides     a
                             convenient mechanism for reading an InputStream from locations defined in a
                              URI syntax. In particular, Resource paths are used to construct applications
                              contexts,  as  described    in Application    Contexts   and   Resource    Paths.


            The  following   example     shows   the  service   layer  objects  (services.xml)     configuration     file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    


                    <bean   id="petStore"
              class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
                         <property     name="accountDao"        ref="accountDao"/>
                         <property     name="itemDao"       ref="itemDao"/>
                         
                    </bean>


                    


              </beans>



            The  following   example     shows   the  data  access   objects  daos.xml   file:



              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="accountDao"
                         class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
                         
                    </bean>


                    <bean   id="itemDao"
              class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
                         
                    </bean>


                    


              </beans>

            In the  preceding    example,     the  service  layer   consists  of  the  PetStoreServiceImpl       class and   two   data
            access objects of the types JpaAccountDao and JpaItemDao (based on the JPA Object-Relational
            Mapping    standard).    The  property    name  element    refers  to the  name   of  the JavaBean     property,   and  the
            ref element refers to the name of another bean definition. This linkage between id and ref
            elements expresses the dependency between collaborating objects. For details of configuring an
            object’s  dependencies,     see  Dependencies.



            Composing    XML-based    Configuration   Metadata

            It can be useful to have bean definitions span multiple XML files. Often, each individual XML
            configuration    file represents    a logical  layer  or module     in your  architecture.


            You can use the application context constructor to load bean definitions from all these XML
            fragments.    This  constructor    takes  multiple   Resource   locations,   as was   shown    in the  previous    section.
            Alternatively,   use  one   or more    occurrences     of the  <import/>    element    to load   bean   definitions   from
            another   file or files. The  following    example    shows    how   to do  so:



              <beans>
                    <import    resource="services.xml"/>
                    <import    resource="resources/messageSource.xml"/>
                    <import    resource="/resources/themeSource.xml"/>


                    <bean   id="bean1"     class="..."/>
                    <bean   id="bean2"     class="..."/>
              </beans>



            In the preceding example, external bean definitions are loaded from three files: services.xml,
            messageSource.xml,      and  themeSource.xml.      All location   paths   are   relative  to  the  definition   file doing
            the importing,    so  services.xml    must    be in  the same    directory   or  classpath   location   as  the file doing
            the importing,     while  messageSource.xml       and  themeSource.xml      must   be  in  a resources    location   below
            the  location   of the  importing     file.  As  you can  see,  a leading    slash  is ignored.   However,     given   that
            these  paths   are  relative,  it is better  form   not  to  use  the  slash  at all. The  contents    of the  files being
            imported,    including   the  top  level  <beans/>   element,    must   be  valid  XML    bean   definitions,   according
            to the Spring   Schema.

                              It  is  possible,  but  not  recommended,     to reference    files in parent   directories   using   a
                              relative "../" path. Doing so creates a dependency on a file that is outside the
                              current    application.     In   particular,    this   reference     is  not   recommended          for
                              classpath: URLs (for example, classpath:../services.xml), where the runtime
                              resolution process chooses the “nearest” classpath root and then looks into its
                              parent directory. Classpath configuration changes may lead to the choice of a
                              different,  incorrect   directory.
                
                              You  can  always    use  fully qualified    resource   locations   instead   of  relative  paths:   for
                              example,        file:C:/config/services.xml             or     classpath:/config/services.xml.
                              However, be aware that you are coupling your application’s configuration to
                              specific  absolute   locations.   It  is  generally  preferable  to keep   an indirection    for such
                              absolute locations — for example, through "${…}" placeholders that are resolved
                              against  JVM   system   properties    at runtime.


            The  namespace      itself provides    the  import   directive   feature.  Further    configuration     features   beyond
            plain bean definitions are available in a selection of XML namespaces provided by Spring — for
            example,    the context   and   util  namespaces.



            The Groovy   Bean   Definition  DSL

            As a further example for externalized configuration metadata, bean definitions can also be
            expressed    in Spring’s   Groovy    Bean   Definition    DSL,  as known     from   the  Grails  framework.     Typically,
            such  configuration     live in a ".groovy"    file  with the structure   shown    in  the following    example:



              beans    {
                    dataSource(BasicDataSource)           {
                         driverClassName       =  "org.hsqldb.jdbcDriver"
                         url   =  "jdbc:hsqldb:mem:grailsDB"
                         username     = "sa"
                         password     = ""
                         settings     = [mynew:"setting"]
                    }
                    sessionFactory(SessionFactory)            {
                         dataSource     =  dataSource
                    }
                    myService(MyService)         {
                         nestedBean     =  {  AnotherBean     bean   ->
                               dataSource     =  dataSource
                         }
                    }
              }



            This  configuration     style  is largely  equivalent     to XML    bean   definitions    and  even   supports    Spring’s
            XML   configuration     namespaces.      It also  allows   for importing     XML    bean   definition   files through    an
            importBeans    directive.

            Using   the  Container

            The  ApplicationContext      is the  interface   for an  advanced     factory  capable    of maintaining     a registry   of
            different beans and their dependencies. By using the method T getBean(String name, Class<T>
            requiredType),    you  can  retrieve   instances   of  your  beans.

            The  ApplicationContext       lets you   read   bean   definitions   and   access   them,   as  the  following    example
            shows:


            Java


              //  create    and   configure    beans
              ApplicationContext        context    =  new   ClassPathXmlApplicationContext("services.xml",
              "daos.xml");


              //  retrieve     configured     instance
              PetStoreService       service    =  context.getBean("petStore",            PetStoreService.class);


              //  use   configured     instance
              List<String>      userList     = service.getUsernameList();



            Kotlin


              import    org.springframework.beans.factory.getBean


              //  create    and   configure    beans
              val   context    =  ClassPathXmlApplicationContext("services.xml",                  "daos.xml")


              //  retrieve     configured     instance
              val   service    =  context.getBean<PetStoreService>("petStore")


              //  use   configured     instance
              var   userList    =  service.getUsernameList()



            With    Groovy     configuration,      bootstrapping       looks    very    similar.   It  has    a   different    context
            implementation class which is Groovy-aware (but also understands XML bean definitions). The
            following   example    shows    Groovy    configuration:


            Java


              ApplicationContext        context    =  new   GenericGroovyApplicationContext("services.groovy",
              "daos.groovy");



            Kotlin


              val   context    =  GenericGroovyApplicationContext("services.groovy",                    "daos.groovy")



            The  most   flexible  variant   is GenericApplicationContext         in  combination     with   reader   delegates — for
            example,    with  XmlBeanDefinitionReader        for XML    files,  as  the  following example    shows:

            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml",                           "daos.xml")
              context.refresh()



            You  can  also  use  the GroovyBeanDefinitionReader         for Groovy    files, as the  following   example     shows:


            Java


              GenericApplicationContext           context    =  new  GenericApplicationContext();
              new   GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy");
              context.refresh();



            Kotlin


              val   context    =  GenericApplicationContext()
              GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy",
              "daos.groovy")
              context.refresh()



            You can mix and match such reader delegates on the same ApplicationContext, reading bean
            definitions   from   diverse  configuration     sources.


            You  can  then  use  getBean   to retrieve   instances    of your  beans.   The  ApplicationContext       interface   has  a
            few  other   methods    for  retrieving   beans,   but,  ideally, your   application    code   should   never   use  them.
            Indeed,   your  application    code   should   have   no  calls to  the getBean()    method    at  all  and thus  have   no
            dependency      on Spring   APIs   at all.  For  example,  Spring’s   integration    with  web   frameworks      provides
            dependency     injection   for  various   web   framework     components      such   as controllers    and  JSF-managed
            beans, letting you declare a dependency on a specific bean through metadata (such as an
            autowiring    annotation).


            2.1.3.   Bean     Overview

            A Spring   IoC  container    manages    one   or more    beans.  These   beans   are  created   with   the configuration
            metadata    that  you  supply   to the  container    (for example,    in the  form   of XML   <bean/>   definitions).


            Within   the  container    itself,  these bean   definitions   are  represented     as BeanDefinition     objects,   which
            contain   (among    other  information)     the  following   metadata:

              • A package-qualified class name: typically, the actual implementation class of the bean being

                defined.

              • Bean behavioral configuration elements, which state how the bean should behave in the
                container    (scope,  lifecycle  callbacks,   and  so  forth).

              • References     to other  beans   that  are  needed    for the  bean   to do  its work.  These   references    are  also
                called  collaborators    or  dependencies.

              • Other   configuration     settings   to set  in the  newly    created   object — for    example,    the  size  limit  of
                the  pool  or the  number     of connections     to use  in a bean   that  manages    a  connection    pool.


            This metadata translates to a set of properties that make up each bean definition. The following
            table describes    these  properties:


            Table 1. The  bean  definition

            Property                                                       Explained     in…

            Class                                                          Instantiating   Beans

            Name                                                           Naming    Beans

            Scope                                                          Bean   Scopes

            Constructor     arguments                                      Dependency      Injection

            Properties                                                     Dependency      Injection

            Autowiring     mode                                            Autowiring     Collaborators

            Lazy   initialization   mode                                   Lazy-initialized    Beans

            Initialization   method                                        Initialization   Callbacks

            Destruction     method                                         Destruction    Callbacks


            In addition to bean definitions that contain information on how to create a specific bean, the
            ApplicationContext      implementations       also  permit   the  registration   of existing   objects  that  are  created
            outside the container (by users). This is done by accessing the ApplicationContext’s BeanFactory
            through      the     getBeanFactory()        method,       which      returns      the    DefaultListableBeanFactory
            implementation.          DefaultListableBeanFactory            supports       this     registration       through       the
            registerSingleton(..)        and    registerBeanDefinition(..)          methods.     However,      typical   applications
            work   solely  with  beans   defined   through    regular   bean   definition   metadata.


                              Bean   metadata    and   manually    supplied    singleton   instances   need   to be  registered    as
                              early  as possible,   in order   for  the container    to properly    reason    about   them   during
                              autowiring    and   other  introspection     steps.  While   overriding    existing   metadata    and
                             existing  singleton    instances    is supported    to  some    degree,   the  registration   of  new
                              beans at runtime (concurrently with live access to the factory) is not officially
                              supported    and   may   lead  to  concurrent    access   exceptions,    inconsistent    state  in the
                              bean  container,    or both.



            Naming     Beans

            Every   bean   has  one  or  more   identifiers.  These   identifiers   must   be  unique    within   the container    that
            hosts  the  bean.   A bean   usually   has   only  one   identifier.  However,     if it  requires  more   than   one,  the

            extra  ones  can  be  considered     aliases.


            In XML-based      configuration    metadata,    you   use  the  id attribute,  the  name  attribute,  or  both  to specify
            the  bean   identifiers.  The   id  attribute   lets you   specify  exactly   one   id. Conventionally,     these   names
            are  alphanumeric      ('myBean',    'someService',    etc.), but  they  can  contain    special  characters    as  well. If
            you  want    to introduce    other   aliases  for  the  bean,   you  can   also  specify  them    in the  name   attribute,
            separated    by  a comma     (,), semicolon     (;), or white   space.   As  a historical   note,  in  versions   prior   to
            Spring   3.1,  the  id  attribute  was defined   as  an xsd:ID   type,  which   constrained     possible   characters.   As
            of 3.1, it is defined as an xsd:string type. Note that bean id uniqueness is still enforced by the
            container,   though   no  longer   by  XML   parsers.


            You  are  not  required   to supply    a name  or an  id for  a bean.   If  you do not  supply   a  name  or id explicitly,
            the container    generates    a unique    name    for that  bean.  However,     if you  want   to refer  to  that bean   by
            name, through the use of the ref element or a Service Locator style lookup, you must provide a
            name. Motivations for not supplying a name are related to using inner beans and autowiring
            collaborators.


                                                    Bean     Naming        Conventions

               The   convention     is  to  use  the  standard Java  convention     for  instance   field names    when    naming
               beans. That is, bean names start with a lowercase letter and are camel-cased from there.
               Examples     of such   names    include   accountManager,    accountService,     userDao,   loginController,     and
               so  forth.


               Naming     beans   consistently    makes    your   configuration     easier  to read   and   understand.     Also,  if
               you   use  Spring  AOP,   it  helps a lot when   applying    advice   to a set of beans    related  by  name.




                              With component scanning in the classpath, Spring generates bean names for
                              unnamed     components,      following    the rules  described    earlier:  essentially,   taking  the
                              simple   class  name    and  turning    its  initial  character  to lower-case.    However,     in the
                             (unusual)    special  case   when    there  is more    than   one   character    and  both   the  first
                              and  second   characters    are  upper   case,  the  original  casing   gets preserved.    These   are
                              the same    rules  as  defined   by  java.beans.Introspector.decapitalize            (which    Spring
                              uses  here).



            Aliasing a Bean   outside  the Bean  Definition

            In a bean definition itself, you can supply more than one name for the bean, by using a
            combination     of up  to  one  name    specified   by  the id  attribute  and   any  number     of other   names    in the
            name attribute. These names can be equivalent aliases to the same bean and are useful for some
            situations, such as letting each component in an application refer to a common dependency by
            using  a bean   name    that is specific  to that  component      itself.

            Specifying all aliases where the bean is actually defined is not always adequate, however. It is
            sometimes     desirable   to  introduce    an  alias  for a  bean   that  is defined   elsewhere.     This  is commonly
            the case in large systems where configuration is split amongst each subsystem, with each
            subsystem     having   its own   set  of object   definitions.   In XML-based      configuration     metadata,    you   can
            use the  <alias/>   element    to accomplish     this. The  following    example    shows    how   to do  so:

              <alias    name="fromName"       alias="toName"/>



            In this case, a bean (in the same container) named fromName may also, after the use of this alias
            definition,  be  referred   to as  toName.


            For example,     the configuration     metadata    for  subsystem     A may   refer  to a  DataSource     by the  name    of
            subsystemA-dataSource.       The  configuration     metadata     for  subsystem     B  may   refer  to a  DataSource     by
            the name of subsystemB-dataSource. When composing the main application that uses both these
            subsystems,    the  main   application    refers  to the  DataSource     by  the name    of myApp-dataSource.     To  have
            all three names refer to the same object, you can add the following alias definitions to the
            configuration    metadata:



              <alias    name="myApp-dataSource"          alias="subsystemA-dataSource"/>
              <alias    name="myApp-dataSource"          alias="subsystemB-dataSource"/>



            Now   each   component      and  the  main   application    can   refer  to the  dataSource    through    a  name   that  is
            unique   and   guaranteed      not  to clash   with  any   other   definition   (effectively   creating   a  namespace),
            yet they  refer  to the  same   bean.


                                                           Java-configuration

               If you   use  Javaconfiguration,      the  @Bean  annotation     can   be used   to  provide   aliases.  See   Using
               the  @Bean  Annotation     for details.




            Instantiating    Beans

            A bean   definition   is essentially   a recipe   for creating   one   or more   objects.   The  container    looks  at the
            recipe for a named bean when asked and uses the configuration metadata encapsulated by that
            bean  definition   to  create  (or acquire)   an  actual   object.


            If  you use  XML-based      configuration     metadata,    you  specify   the  type  (or  class) of  object  that  is to be
            instantiated   in  the class  attribute   of the  <bean/>   element.    This  class  attribute   (which,   internally,  is a
            Class   property      on   a   BeanDefinition      instance)     is  usually    mandatory.       (For   exceptions,     see
            Instantiation    by  Using   an  Instance   Factory    Method    and   Bean   Definition    Inheritance.)    You   can  use
            the Class  property    in one   of two  ways:


              • Typically, to specify the bean class to be constructed in the case where the container itself
                directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java
                code   with  the  new operator.

              • To specify the actual class containing the static factory method that is invoked to create the
                object,  in the  less common      case  where    the  container    invokes   a static   factory   method    on  a class
                to create   the  bean.   The  object   type  returned    from    the invocation     of the  static   factory   method
                may   be  the same    class or  another   class  entirely.

                                                          Nested      class    names

               If you   want   to configure    a  bean   definition   for  a nested   class,  you  may    use  either  the  binary
               name    or the  source   name    of the  nested   class.


               For example, if you have a class called SomeThing in the com.example package, and this
               SomeThing    class  has  a static   nested   class  called  OtherThing,    they  can   be  separated    by  a dollar
               sign ($) or a dot (.). So the value of the class attribute in a bean definition would be
               com.example.SomeThing$OtherThing           or com.example.SomeThing.OtherThing.





            Instantiation  with  a Constructor

            When you create a bean by the constructor approach, all normal classes are usable by and
            compatible    with   Spring.  That   is,  the  class  being developed    does   not  need   to implement     any   specific
            interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice.
            However,     depending     on  what    type  of  IoC  you  use   for that  specific   bean,   you  may    need   a default
            (empty)   constructor.


            The  Spring   IoC  container    can  manage     virtually   any  class  you  want   it to manage.     It  is  not  limited  to
            managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-
            argument) constructor and appropriate setters and getters modeled after the properties in the
            container.   You   can  also  have   more   exotic  non-bean-style      classes  in  your  container.    If,  for  example,
            you need to use a legacy connection pool that absolutely does not adhere to the JavaBean
            specification,   Spring   can  manage    it as well.


            With  XML-based      configuration     metadata    you  can   specify  your   bean   class as follows:



              <bean    id="exampleBean"       class="examples.ExampleBean"/>


              <bean    name="anotherExample"         class="examples.ExampleBeanTwo"/>



            For details about the mechanism for supplying arguments to the constructor (if required) and
            setting  object  instance   properties    after the  object  is constructed,    see  Injecting  Dependencies.



            Instantiation  with  a Static Factory  Method

            When    defining   a bean   that  you  create  with   a static factory   method,    use  the class   attribute  to specify
            the class  that  contains   the  static   factory   method    and   an  attribute   named    factory-method     to specify
            the name of the factory method itself. You should be able to call this method (with optional
            arguments,     as described    later)  and   return   a live  object,  which    subsequently     is treated   as  if it had
            been  created    through    a constructor.    One   use  for such   a bean   definition   is to call static   factories   in
            legacy  code.


            The  following    bean   definition   specifies   that  the  bean   will  be  created   by  calling   a factory   method.
            The definition does not specify the type (class) of the returned object, but rather the class
            containing the factory method. In this example, the createInstance() method must be a static
            method.   The   following   example     shows   how   to specify   a factory   method:

              <bean    id="clientService"
                    class="examples.ClientService"
                    factory-method="createInstance"/>



            The  following   example     shows   a class  that  would   work    with  the  preceding    bean   definition:


            Java


              public    class   ClientService      {
                    private    static   ClientService       clientService      =  new  ClientService();
                    private    ClientService()       {}


                    public   static    ClientService      createInstance()        {
                         return    clientService;
                    }
              }



            Kotlin


              class    ClientService      private    constructor()      {
                    companion     object   {
                         private    val   clientService      =  ClientService()
                         @JvmStatic
                         fun   createInstance()       =  clientService
                    }
              }



            For details about the mechanism for supplying (optional) arguments to the factory method and
            setting  object   instance   properties    after  the  object   is returned    from   the  factory,   see  Dependencies
            and  Configuration     in Detail.



            Instantiation  by Using  an  Instance  Factory  Method

            Similar to instantiation through a static factory method, instantiation with an instance factory
            method    invokes    a non-static   method     of an  existing   bean   from   the  container    to create   a new   bean.
            To  use  this mechanism,      leave   the  class   attribute  empty    and,   in the  factory-bean     attribute,  specify
            the name of a bean in the current (or parent or ancestor) container that contains the instance
            method    that  is  to  be  invoked to  create  the  object.  Set the  name    of the  factory   method    itself with  the
            factory-method     attribute.  The  following    example    shows    how   to configure    such  a bean:

              
              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              
              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>



            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                    }
                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }
              }



            One  factory   class can   also hold   more   than  one   factory  method,    as the  following    example    shows:



              <bean    id="serviceLocator"        class="examples.DefaultServiceLocator">
                    
              </bean>


              <bean    id="clientService"
                    factory-bean="serviceLocator"
                    factory-method="createClientServiceInstance"/>


              <bean    id="accountService"
                    factory-bean="serviceLocator"
                    factory-method="createAccountServiceInstance"/>

            The  following   example     shows   the  corresponding      class:


            Java


              public    class   DefaultServiceLocator         {


                    private    static   ClientService       clientService      =  new  ClientServiceImpl();


                    private    static   AccountService       accountService       = new   AccountServiceImpl();


                    public   ClientService       createClientServiceInstance()            {
                         return    clientService;
                    }


                    public   AccountService       createAccountServiceInstance()             {
                         return    accountService;
                    }
              }



            Kotlin


              class    DefaultServiceLocator         {
                    companion     object   {
                         private    val   clientService      =  ClientServiceImpl()
                         private    val   accountService      =  AccountServiceImpl()
                    }


                    fun  createClientServiceInstance():             ClientService      {
                         return    clientService
                    }


                    fun  createAccountServiceInstance():             AccountService       {
                         return    accountService
                    }
              }



            This approach shows that the factory bean itself can be managed and configured through
            dependency     injection   (DI). See  Dependencies      and   Configuration     in Detail.


                              In Spring   documentation,       "factory   bean"   refers  to a  bean   that is configured     in the
                              Spring container and that creates objects through an instance or static factory
                             method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-
                              specific  FactoryBean    implementation       class.



            Determining    a Bean’s Runtime    Type

            The runtime type of a specific bean is non-trivial to determine. A specified class in the bean
            metadata    definition   is just  an  initial class  reference,    potentially   combined      with  a  declared   factory
            method    or being   a  FactoryBean    class which    may   lead  to  a different   runtime    type  of the  bean,   or not

            being set at all in case of an instance-level factory method (which is resolved via the specified
            factory-bean name instead). Additionally, AOP proxying may wrap a bean instance with an
            interface-based     proxy   with   limited  exposure     of the  target   bean’s  actual   type  (just  its implemented
            interfaces).

            The recommended way to find out about the actual runtime type of a particular bean is a
            BeanFactory.getType      call  for the  specified   bean   name.   This   takes  all of the  above   cases   into account
            and  returns   the  type   of object   that a  BeanFactory.getBean       call is going   to return   for  the  same   bean
            name.

            2.1.4.   Dependencies

            A typical  enterprise    application    does   not  consist  of a  single  object  (or  bean   in the  Spring   parlance).
            Even   the  simplest   application    has   a few   objects   that  work   together    to present    what   the  end-user
            sees  as a  coherent    application.    This  next  section   explains    how   you   go  from   defining   a  number     of
            bean  definitions    that stand   alone  to  a fully realized   application    where   objects   collaborate    to achieve
            a goal.


            Dependency       Injection

            Dependency      injection   (DI) is a process   whereby     objects  define   their  dependencies      (that is, the  other
            objects  with  which    they  work)   only  through    constructor    arguments,     arguments     to a factory   method,
            or properties    that  are  set  on  the  object  instance    after  it  is  constructed  or  returned    from   a factory
            method. The container then injects those dependencies when it creates the bean. This process is
            fundamentally      the  inverse   (hence   the  name,   Inversion    of  Control)   of the  bean   itself controlling   the
            instantiation   or  location  of  its  dependencies    on  its own   by  using  direct  construction    of  classes  or the
            Service  Locator    pattern.


            Code   is cleaner   with  the  DI  principle,   and   decoupling    is more    effective  when    objects   are  provided
            with their dependencies. The object does not look up its dependencies and does not know the
            location   or class  of  the  dependencies.      As  a result,  your   classes   become    easier   to test, particularly
            when the dependencies are on interfaces or abstract base classes, which allow for stub or mock
            implementations       to be used   in unit  tests.


            DI  exists   in   two    major    variants:    Constructor-based        dependency       injection    and    Setter-based
            dependency     injection.



            Constructor-based    Dependency     Injection

            Constructor-based DI is accomplished by the container invoking a constructor with a number of
            arguments,      each   representing      a  dependency.       Calling   a   static   factory    method     with    specific
            arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a
            constructor    and  to  a static   factory  method     similarly.  The  following    example    shows    a class  that  can
            only  be dependency-injected        with  constructor     injection:

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  a MovieFinder
                    private    final   MovieFinder      movieFinder;


                    //  a  constructor     so  that   the   Spring   container     can   inject   a  MovieFinder
                    public   SimpleMovieLister(MovieFinder             movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              //  a  constructor      so  that   the  Spring    container     can  inject    a MovieFinder
              class    SimpleMovieLister(private          val   movieFinder:      MovieFinder)      {
                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Notice that there is nothing special about this class. It is a POJO that has no dependencies on
            container   specific  interfaces,   base   classes, or  annotations.


            Constructor     Argument      Resolution

            Constructor argument resolution matching occurs by using the argument’s type. If no potential
            ambiguity exists in the constructor arguments of a bean definition, the order in which the
            constructor    arguments     are  defined    in a bean   definition    is the order   in  which   those   arguments     are
            supplied   to the  appropriate     constructor    when   the  bean   is being   instantiated.   Consider    the following
            class:


            Java


              package    x.y;


              public    class   ThingOne     {


                    public   ThingOne(ThingTwo        thingTwo,     ThingThree     thingThree)      {
                         //  ...
                    }
              }

            Kotlin


              package    x.y


              class    ThingOne(thingTwo:        ThingTwo,    thingThree:      ThingThree)



            Assuming that the ThingTwo and ThingThree classes are not related by inheritance, no potential
            ambiguity    exists.  Thus,  the  following    configuration     works    fine, and   you  do  not  need   to  specify  the
            constructor    argument     indexes   or types   explicitly  in the  <constructor-arg/>      element.



              <beans>
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        ref="beanTwo"/>
                         <constructor-arg        ref="beanThree"/>
                    </bean>


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>


                    <bean   id="beanThree"       class="x.y.ThingThree"/>
              </beans>



            When    another   bean   is referenced,    the  type  is known,    and  matching     can  occur   (as was   the case   with
            the preceding example). When a simple type is used, such as <value>true</value>, Spring cannot
            determine    the  type  of  the  value,  and  so  cannot   match    by  type  without    help.  Consider    the following
            class:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    final   int   years;


                    //  The  Answer    to  Life,   the   Universe,     and  Everything
                    private    final   String    ultimateAnswer;


                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }

            Kotlin


              package    examples


              class    ExampleBean(
                    private    val  years:    Int,   //  Number    of  years   to  calculate     the  Ultimate     Answer
                    private    val  ultimateAnswer:       String    //  The   Answer   to  Life,    the  Universe,     and
              Everything
              )



            Constructor   argument    type  matching
            In the  preceding    scenario,    the  container    can  use  type  matching     with   simple   types  if you   explicitly
            specify  the  type  of  the  constructor    argument     by  using   the  type  attribute,  as  the  following    example
            shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       type="int"     value="7500000"/>
                    <constructor-arg       type="java.lang.String"          value="42"/>
              </bean>



            Constructor   argument    index
            You can use the index attribute to specify explicitly the index of constructor arguments, as the
            following   example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       index="0"     value="7500000"/>
                    <constructor-arg       index="1"     value="42"/>
              </bean>



            In addition to resolving the ambiguity of multiple simple values, specifying an index resolves
            ambiguity    where    a constructor    has  two  arguments     of  the same    type.

                             The  index   is  0-based.


            Constructor   argument    name
            You can also use the constructor parameter name for value disambiguation, as the following
            example    shows:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    <constructor-arg       name="years"      value="7500000"/>
                    <constructor-arg       name="ultimateAnswer"         value="42"/>
              </bean>



            Keep   in mind    that, to  make   this  work   out  of  the  box,  your   code  must    be  compiled    with   the  debug
            flag enabled    so that  Spring   can  look   up  the parameter     name    from   the  constructor.    If you  cannot    or

            do not  want   to  compile   your   code   with  the  debug   flag, you   can  use  the  @ConstructorProperties         JDK
            annotation to explicitly name your constructor arguments. The sample class would then have to
            look  as follows:


            Java


              package    examples;


              public    class   ExampleBean      {


                    //  Fields    omitted


                    @ConstructorProperties({"years",             "ultimateAnswer"})
                    public   ExampleBean(int       years,    String    ultimateAnswer)       {
                         this.years     =  years;
                         this.ultimateAnswer         =  ultimateAnswer;
                    }
              }



            Kotlin


              package    examples


              class    ExampleBean
              @ConstructorProperties("years",             "ultimateAnswer")
              constructor(val       years:    Int,   val  ultimateAnswer:       String)




            Setter-based  Dependency     Injection

            Setter-based DI is accomplished by the container calling setter methods on your beans after
            invoking a no-argument constructor or a no-argument static factory method to instantiate your
            bean.

            The following example shows a class that can only be dependency-injected by using pure setter
            injection.  This  class  is  conventional   Java.  It is  a  POJO that has  no  dependencies      on  container    specific
            interfaces,  base   classes,  or annotations.

            Java


              public    class   SimpleMovieLister        {


                    //  the  SimpleMovieLister        has   a dependency      on  the  MovieFinder
                    private    MovieFinder     movieFinder;


                    //  a  setter   method    so  that   the  Spring    container     can  inject    a  MovieFinder
                    public   void   setMovieFinder(MovieFinder           movieFinder)      {
                         this.movieFinder        = movieFinder;
                    }


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            Kotlin


              class    SimpleMovieLister       {


                    //  a  late-initialized       property    so   that  the   Spring    container    can   inject   a
              MovieFinder
                    lateinit    var   movieFinder:      MovieFinder


                    //  business    logic    that  actually     uses   the  injected     MovieFinder     is  omitted...
              }



            The  ApplicationContext      supports    constructor-based       and  setter-based    DI  for the  beans   it manages.    It
            also supports setter-based DI after some dependencies have already been injected through the
            constructor    approach.    You   configure    the  dependencies      in the  form   of  a BeanDefinition,     which    you
            use  in conjunction     with  PropertyEditor     instances    to convert   properties    from   one  format   to  another.
            However,    most   Spring   users   do  not  work   with   these  classes  directly   (that is, programmatically)       but
            rather  with   XML   bean  definitions,   annotated    components      (that  is,  classes annotated    with  @Component,
            @Controller,   and   so forth),  or @Bean   methods    in  Java-based    @Configuration     classes.  These   sources   are
            then converted internally into instances of BeanDefinition and used to load an entire Spring IoC
            container   instance.

                                           Constructor-based              or  setter-based          DI?

               Since   you   can  mix   constructor-based       and  setter-based     DI, it is a  good   rule  of thumb     to use
               constructors     for  mandatory      dependencies      and  setter   methods    or  configuration     methods     for
               optional    dependencies.     Note   that  use  of  the  @Autowired      annotation     on  a setter   method    can
               be  used   to make   the  property    be  a required    dependency;     however,     constructor    injection   with
               programmatic       validation   of arguments      is  preferable.

               The    Spring    team    generally     advocates     constructor     injection,    as  it  lets  you    implement
               application components as immutable objects and ensures that required dependencies are
               not null. Furthermore, constructor-injected components are always returned to the client
               (calling) code in a fully initialized state. As a side note, a large number of constructor
               arguments     is a bad   code  smell,  implying    that  the class  likely  has  too many    responsibilities    and
               should   be  refactored    to better  address    proper   separation    of concerns.


               Setter  injection   should   primarily    only  be  used   for optional   dependencies      that  can  be  assigned
               reasonable default values within the class. Otherwise, not-null checks must be performed
               everywhere the code uses the dependency. One benefit of setter injection is that setter
               methods make objects of that class amenable to reconfiguration or re-injection later.
               Management       through    JMX   MBeans     is  therefore  a compelling    use  case  for  setter  injection.


               Use   the  DI  style that  makes     the  most   sense   for a  particular   class.  Sometimes,     when    dealing
               with   third-party   classes   for which   you   do  not  have  the  source,   the  choice  is made    for you.  For
               example,    if a third-party    class  does  not  expose   any   setter  methods,    then  constructor     injection
               may   be  the  only  available   form   of DI.





            Dependency    Resolution   Process

            The  container    performs    bean   dependency      resolution   as  follows:


              • The   ApplicationContext      is created   and   initialized  with  configuration     metadata     that  describes   all
                the  beans.  Configuration     metadata     can  be  specified   by XML,   Java   code,  or annotations.

              • For  each  bean,   its dependencies      are expressed     in the  form  of  properties,   constructor    arguments,
                or arguments to the static-factory method (if you use that instead of a normal constructor).
                These   dependencies      are  provided    to the bean,   when    the bean   is actually   created.

              • Each   property    or constructor    argument     is an  actual   definition   of the  value  to  set,  or  a reference
                to another    bean   in the  container.

              • Each   property    or constructor     argument     that  is  a  value  is  converted  from   its  specified format    to
                the  actual  type  of  that property    or  constructor    argument.     By default,   Spring   can  convert   a value
                supplied   in  string  format   to all built-in  types,  such  as int,  long, String,   boolean,  and   so forth.

            The  Spring   container    validates   the configuration     of each   bean   as the  container    is  created. However,
            the bean properties themselves are not set until the bean is actually created. Beans that are
            singleton-scoped and set to be pre-instantiated (the default) are created when the container is
            created. Scopes are defined in Bean Scopes. Otherwise, the bean is created only when it is
            requested. Creation of a bean potentially causes a graph of beans to be created, as the bean’s
            dependencies      and  its dependencies'      dependencies      (and  so  on)  are  created   and   assigned.    Note  that

            resolution   mismatches      among     those  dependencies      may    show   up  late — that    is,  on  first  creation of
            the affected   bean.


                                                       Circular       dependencies

               If you use predominantly constructor injection, it is possible to create an unresolvable
               circular   dependency      scenario.


               For  example:    Class  A  requires   an  instance   of class  B through    constructor    injection,   and  class  B
               requires an instance of class A through constructor injection. If you configure beans for
               classes   A  and  B  to be  injected   into  each   other,  the  Spring   IoC  container    detects   this  circular
               reference    at runtime,    and  throws    a BeanCurrentlyInCreationException.


               One   possible    solution   is to edit  the  source   code   of  some   classes   to be   configured    by  setters
               rather than constructors. Alternatively, avoid constructor injection and use setter injection
               only.   In   other    words,    although     it  is  not    recommended,        you    can    configure     circular
               dependencies      with  setter  injection.


               Unlike   the  typical  case  (with   no  circular  dependencies),      a circular   dependency      between    bean
               A and bean B forces one of the beans to be injected into the other prior to being fully
               initialized   itself  (a  classic  chicken-and-egg   scenario).



            You can generally trust Spring to do the right thing. It detects configuration problems, such as
            references to non-existent beans and circular dependencies, at container load-time. Spring sets
            properties    and  resolves    dependencies      as late  as  possible,   when    the  bean   is actually   created.   This
            means    that a  Spring   container    that  has  loaded   correctly   can  later  generate    an  exception    when    you
            request an object if there is a problem creating that object or one of its dependencies — for
            example,    the bean   throws    an  exception    as a  result  of a missing   or  invalid   property.   This  potentially
            delayed visibility of some configuration issues is why ApplicationContext implementations by
            default pre-instantiate singleton beans. At the cost of some upfront time and memory to create
            these   beans    before    they    are   actually   needed,     you    discover    configuration      issues   when     the
            ApplicationContext      is created,  not  later. You   can  still  override  this default   behavior    so that  singleton
            beans   initialize lazily, rather   than  being   eagerly   pre-instantiated.


            If  no circular  dependencies      exist,  when    one  or  more   collaborating     beans   are  being   injected   into  a
            dependent bean, each collaborating bean is totally configured prior to being injected into the
            dependent     bean.  This   means    that, if bean   A  has  a dependency      on  bean   B, the  Spring   IoC  container
            completely    configures    bean    B prior   to invoking    the  setter  method     on  bean   A. In  other   words,   the
            bean is instantiated (if it is not a pre-instantiated singleton), its dependencies are set, and the
            relevant lifecycle methods (such as a configured init method or the InitializingBean callback
            method)    are  invoked.



            Examples   of Dependency     Injection

            The  following    example    uses  XML-based      configuration     metadata     for setter-based    DI. A  small   part  of
            a Spring   XML   configuration     file specifies  some   bean   definitions   as  follows:

              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <property     name="beanOne">
                         <ref   bean="anotherExampleBean"/>
                    </property>


                    
                    <property     name="beanTwo"      ref="yetAnotherBean"/>
                    <property     name="integerProperty"         value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   void   setBeanOne(AnotherBean          beanOne)    {
                         this.beanOne      =  beanOne;
                    }


                    public   void   setBeanTwo(YetAnotherBean           beanTwo)    {
                         this.beanTwo      =  beanTwo;
                    }


                    public   void   setIntegerProperty(int          i)  {
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean     {
                    lateinit    var   beanOne:    AnotherBean
                    lateinit    var   beanTwo:    YetAnotherBean
                    var  i:  Int   =  0
              }



            In the  preceding    example,    setters  are  declared    to match   against   the  properties    specified  in  the XML

            file.  The  following  example    uses  constructor-based       DI:



              <bean    id="exampleBean"       class="examples.ExampleBean">
                    
                    <constructor-arg>
                         <ref   bean="anotherExampleBean"/>
                    </constructor-arg>


                    
                    <constructor-arg       ref="yetAnotherBean"/>


                    <constructor-arg       type="int"     value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    private    AnotherBean     beanOne;


                    private    YetAnotherBean      beanTwo;


                    private    int  i;


                    public   ExampleBean(
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {
                         this.beanOne      =  anotherBean;
                         this.beanTwo      =  yetAnotherBean;
                         this.i    =  i;
                    }
              }



            Kotlin


              class    ExampleBean(
                         private    val   beanOne:    AnotherBean,
                         private    val   beanTwo:    YetAnotherBean,
                         private    val   i:  Int)



            The constructor arguments specified in the bean definition are used as arguments to the
            constructor    of the  ExampleBean.


            Now   consider    a variant   of this  example,    where,   instead   of using   a constructor,    Spring   is told  to call
            a static  factory   method    to return   an  instance   of the  object:

              <bean    id="exampleBean"       class="examples.ExampleBean"            factory-method="createInstance">
                    <constructor-arg       ref="anotherExampleBean"/>
                    <constructor-arg       ref="yetAnotherBean"/>
                    <constructor-arg       value="1"/>
              </bean>


              <bean    id="anotherExampleBean"          class="examples.AnotherBean"/>
              <bean    id="yetAnotherBean"        class="examples.YetAnotherBean"/>



            The  following   example     shows   the  corresponding      ExampleBean    class:


            Java


              public    class   ExampleBean      {


                    //  a  private    constructor
                    private    ExampleBean(...)       {
                         ...
                    }


                    //  a  static   factory    method;    the   arguments     to  this   method   can   be
                    //  considered     the   dependencies     of   the  bean   that   is  returned,
                    //  regardless     of  how   those   arguments     are  actually     used.
                    public   static    ExampleBean      createInstance      (
                         AnotherBean      anotherBean,      YetAnotherBean      yetAnotherBean,       int   i)  {


                         ExampleBean      eb  =  new  ExampleBean      (...);
                         //  some   other    operations...
                         return    eb;
                    }
              }



            Kotlin


              class    ExampleBean     private    constructor()      {
                    companion     object   {
                         //  a  static    factory    method;    the  arguments     to  this   method    can  be
                         //  considered      the  dependencies      of  the   bean  that   is  returned,
                         //  regardless      of  how  those   arguments     are   actually    used.
                         @JvmStatic
                         fun   createInstance(anotherBean:           AnotherBean,      yetAnotherBean:       YetAnotherBean,
              i:  Int):    ExampleBean     {
                               val  eb  =  ExampleBean      (...)
                               //  some   other   operations...
                               return   eb
                         }
                    }
              }

            Arguments     to  the  static   factory  method     are  supplied    by  <constructor-arg/>      elements,    exactly   the
            same   as if a constructor    had   actually   been  used.   The  type  of  the class  being   returned    by  the factory
            method    does   not  have   to be  of  the same    type  as  the  class  that  contains   the  static   factory   method
            (although, in this example, it is). An instance (non-static) factory method can be used in an
            essentially   identical   fashion   (aside  from    the  use  of the  factory-bean     attribute   instead   of  the  class
            attribute),  so we   do not  discuss   those  details  here.


            Dependencies       and  Configuration       in Detail

            As mentioned      in the previous    section,  you   can  define  bean   properties    and  constructor    arguments      as
            references    to other  managed      beans   (collaborators)    or  as values   defined    inline. Spring’s   XML-based
            configuration     metadata    supports    sub-element      types  within   its <property/>     and   <constructor-arg/>
            elements    for this purpose.



            Straight Values  (Primitives,  Strings,  and  so on)

            The  value   attribute   of the  <property/>     element    specifies   a property    or  constructor     argument     as  a
            human-readable       string  representation.      Spring’s   conversion    service   is used   to convert    these  values
            from   a String  to  the actual   type  of the  property    or argument.     The  following    example    shows    various
            values  being   set:



              <bean    id="myDataSource"       class="org.apache.commons.dbcp.BasicDataSource"                   destroy-
              method="close">
                    
                    <property     name="driverClassName"         value="com.mysql.jdbc.Driver"/>
                    <property     name="url"     value="jdbc:mysql://localhost:3306/mydb"/>
                    <property     name="username"       value="root"/>
                    <property     name="password"       value="misterkaoli"/>
              </bean>



            The  following   example     uses  the  p-namespace      for even   more   succinct   XML   configuration:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                    https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="myDataSource"        class="org.apache.commons.dbcp.BasicDataSource"
                         destroy-method="close"
                         p:driverClassName="com.mysql.jdbc.Driver"
                         p:url="jdbc:mysql://localhost:3306/mydb"
                         p:username="root"
                         p:password="misterkaoli"/>


              </beans>



            The  preceding    XML    is more   succinct.   However,     typos  are  discovered     at runtime    rather   than  design

            time, unless you use an IDE (such as IntelliJ IDEA or the Spring Tools for Eclipse) that supports
            automatic property completion when you create bean definitions. Such IDE assistance is highly
            recommended.


            You  can  also  configure   a  java.util.Properties      instance,   as  follows:



              <bean    id="mappings"
                    class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">


                    
                    <property     name="properties">
                         <value>
                               jdbc.driver.className=com.mysql.jdbc.Driver
                               jdbc.url=jdbc:mysql://localhost:3306/mydb
                         </value>
                    </property>
              </bean>



            The Spring container converts the text inside the <value/> element into a java.util.Properties
            instance   by  using  the  JavaBeans     PropertyEditor     mechanism.      This  is a  nice  shortcut,   and  is one  of  a
            few  places   where    the  Spring   team   do  favor   the  use  of the  nested    <value/>   element    over   the  value
            attribute  style.


            The  idref  element

            The  idref   element    is simply   an  error-proof    way   to  pass  the  id (a  string  value   -  not a reference)    of
            another bean in the container to a <constructor-arg/> or <property/> element. The following
            example    shows   how    to use  it:



              <bean    id="theTargetBean"        class="..."/>


              <bean    id="theClientBean"        class="...">
                    <property     name="targetName">
                         <idref    bean="theTargetBean"/>
                    </property>
              </bean>



            The  preceding    bean   definition   snippet   is exactly  equivalent    (at runtime)    to the  following   snippet:



              <bean    id="theTargetBean"        class="..."     />


              <bean    id="client"     class="...">
                    <property     name="targetName"       value="theTargetBean"/>
              </bean>



            The  first form   is preferable    to the  second,   because    using  the  idref   tag lets the  container    validate   at
            deployment time that the referenced, named bean actually exists. In the second variation, no

            validation   is performed      on  the  value   that is passed    to the  targetName    property    of  the  client  bean.
            Typos are only discovered (with most likely fatal results) when the client bean is actually
            instantiated.   If the  client  bean   is a  prototype    bean,  this  typo  and   the  resulting   exception    may   only
            be discovered     long  after the  container    is  deployed.


                              The  local   attribute   on  the  idref   element    is no  longer   supported     in the  4.0  beans
                              XSD, since it does not provide value over a regular bean reference any more.
                             Change    your  existing   idref   local   references    to idref   bean  when    upgrading     to the
                              4.0 schema.


            A common      place   (at least  in  versions   earlier   than   Spring   2.0)  where    the  <idref/>   element    brings
            value is in the configuration of AOP interceptors in a ProxyFactoryBean bean definition. Using
            <idref/> elements when you specify the interceptor names prevents you from misspelling an
            interceptor   ID.



            References   to Other  Beans  (Collaborators)

            The  ref  element    is the  final element    inside   a <constructor-arg/>      or  <property/>    definition   element.
            Here, you set the value of the specified property of a bean to be a reference to another bean (a
            collaborator)    managed     by  the  container.    The  referenced     bean   is a  dependency      of the  bean   whose
            property    is to be  set, and   it is initialized   on  demand     as  needed    before   the  property    is set. (If the
            collaborator    is a singleton    bean,  it may   already    be  initialized  by  the  container.)    All references    are
            ultimately   a reference    to another    object.  Scoping   and   validation   depend    on  whether    you   specify  the
            ID or  name   of the  other   object  through    the bean  or  parent  attribute.


            Specifying   the  target  bean   through    the  bean  attribute   of the  <ref/>  tag  is the most   general    form  and
            allows  creation    of a reference    to any   bean   in the  same   container    or parent    container,   regardless    of
            whether it is in the same XML file. The value of the bean attribute may be the same as the id
            attribute   of the  target  bean   or  be  the  same   as  one   of the  values   in the  name   attribute   of the  target
            bean.  The  following    example    shows    how   to use  a ref  element:



              <ref   bean="someBean"/>



            Specifying    the  target  bean   through    the  parent   attribute   creates   a  reference    to a  bean   that  is in  a
            parent container of the current container. The value of the parent attribute may be the same as
            either  the id  attribute  of  the target  bean   or  one  of the  values   in the  name  attribute  of  the target  bean.
            The target bean must be in a parent container of the current one. You should use this bean
            reference variant mainly when you have a hierarchy of containers and you want to wrap an
            existing  bean   in  a parent   container    with   a proxy    that  has  the  same   name    as  the  parent   bean.   The
            following   pair  of listings  shows   how   to use  the  parent   attribute:



              
              <bean    id="accountService"        class="com.something.SimpleAccountService">
                    
              </bean>

              
              <bean    id="accountService"        
                    class="org.springframework.aop.framework.ProxyFactoryBean">
                    <property     name="target">
                         <ref   parent="accountService"/>           
                    </property>
                    
              </bean>




                              The  local  attribute   on  the  ref element    is no  longer   supported    in the  4.0 beans    XSD,
                             since it does not provide value over a regular bean reference any more. Change
                              your  existing   ref  local  references    to ref  bean  when    upgrading     to the 4.0  schema.



            Inner Beans

            A <bean/>   element    inside   the  <property/>    or  <constructor-arg/>      elements    defines   an  inner   bean,   as
            the following    example    shows:



              <bean    id="outer"     class="...">
                    
                    <property     name="target">
                         <bean    class="com.example.Person">           
                               <property     name="name"     value="Fiona      Apple"/>
                               <property     name="age"     value="25"/>
                         </bean>
                    </property>
              </bean>



            An  inner  bean   definition   does   not  require   a defined   ID  or name.    If specified,  the  container    does  not
            use such a value as an identifier. The container also ignores the scope flag on creation, because
            inner  beans   are  always   anonymous       and  are  always    created   with  the  outer  bean.   It  is  not  possible  to
            access inner beans independently or to inject them into collaborating beans other than into the
            enclosing   bean.


            As a  corner   case,  it  is  possible  to  receive  destruction  callbacks    from   a custom    scope — for    example,
            for a request-scoped      inner   bean   contained    within   a singleton    bean.  The   creation   of  the inner   bean
            instance is tied to its containing bean, but destruction callbacks let it participate in the request
            scope’s  lifecycle.  This  is  not  a common    scenario.   Inner   beans   typically  simply   share   their  containing
            bean’s  scope.



            Collections

            The <list/>, <set/>, <map/>, and <props/> elements set the properties and arguments of the Java
            Collection    types  List,  Set,  Map, and   Properties,    respectively.   The   following    example     shows   how    to
            use them:

              <bean    id="moreComplexObject"         class="example.ComplexObject">
                    
                    <property     name="adminEmails">
                         <props>
                               <prop   key="administrator">administrator@example.org</prop>
                               <prop   key="support">support@example.org</prop>
                               <prop   key="development">development@example.org</prop>
                         </props>
                    </property>
                    
                    <property     name="someList">
                         <list>
                               <value>a    list   element    followed    by   a reference</value>
                               <ref   bean="myDataSource"        />
                         </list>
                    </property>
                    
                    <property     name="someMap">
                         <map>
                               <entry   key="an    entry"    value="just      some  string"/>
                               <entry   key="a    ref"   value-ref="myDataSource"/>
                         </map>
                    </property>
                    
                    <property     name="someSet">
                         <set>
                               <value>just     some   string</value>
                               <ref   bean="myDataSource"        />
                         </set>
                    </property>
              </bean>



            The  value  of  a map   key  or  value,  or a set  value,  can  also  be any  of  the following    elements:



              bean   |  ref  |  idref   |  list   |  set  |  map   | props    | value    | null



            Collection    Merging

            The Spring container also supports merging collections. An application developer can define a
            parent   <list/>,  <map/>,  <set/>   or  <props/>   element    and  have   child  <list/>,  <map/>,   <set/>  or  <props/>
            elements inherit and override values from the parent collection. That is, the child collection’s
            values   are  the  result  of merging     the  elements    of the  parent    and  child   collections,   with  the  child’s
            collection  elements    overriding    values   specified   in the  parent   collection.


            This section on merging discusses the parent-child bean mechanism. Readers unfamiliar with
            parent   and  child  bean   definitions   may   wish   to read  the  relevant   section   before  continuing.


            The  following   example     demonstrates     collection   merging:

              <beans>
                    <bean   id="parent"      abstract="true"       class="example.ComplexObject">
                         <property     name="adminEmails">
                               <props>
                                    <prop    key="administrator">administrator@example.com</prop>
                                    <prop    key="support">support@example.com</prop>
                               </props>
                         </property>
                    </bean>
                    <bean   id="child"     parent="parent">
                         <property     name="adminEmails">
                               
                               <props   merge="true">
                                    <prop    key="sales">sales@example.com</prop>
                                    <prop    key="support">support@example.co.uk</prop>
                               </props>
                         </property>
                    </bean>
              <beans>



            Notice  the  use  of the  merge=true    attribute  on  the  <props/>   element    of the  adminEmails    property    of the
            child bean definition. When the child bean is resolved and instantiated by the container, the
            resulting   instance   has  an  adminEmails     Properties    collection   that  contains   the  result  of  merging    the
            child’s  adminEmails    collection   with   the  parent’s   adminEmails    collection.   The   following    listing shows
            the result:



              administrator=administrator@example.com
              sales=sales@example.com
              support=support@example.co.uk



            The  child  Properties    collection’s   value   set inherits   all property    elements    from   the  parent   <props/>,
            and  the  child’s value   for the  support   value  overrides    the  value  in  the parent   collection.


            This  merging    behavior     applies   similarly   to the  <list/>,   <map/>,   and  <set/>   collection   types.   In the
            specific  case  of the  <list/>   element,    the  semantics    associated    with   the List   collection   type  (that  is,
            the notion    of an  ordered   collection   of  values)  is maintained.     The   parent’s   values   precede    all of the
            child list’s values. In the case of the Map, Set, and Properties collection types, no ordering exists.
            Hence,   no  ordering    semantics    are  in effect  for  the collection   types   that  underlie   the  associated    Map,
            Set, and  Properties    implementation       types  that  the container    uses  internally.


            Limitations     of Collection    Merging

            You  cannot   merge    different   collection  types   (such  as  a Map and   a List).  If  you do  attempt   to do  so, an
            appropriate    Exception    is  thrown.  The  merge   attribute  must   be  specified   on  the lower,   inherited,   child
            definition.  Specifying    the  merge  attribute   on a  parent   collection  definition    is  redundant   and   does  not
            result in  the desired   merging.

            Strongly-typed      collection

            Thanks to Java’s support for generic types, you can use strongly typed collections. That is, it is
            possible   to declare   a Collection    type  such   that  it  can  only contain   (for example)     String   elements.   If
            you use Spring to dependency-inject a strongly-typed Collection into a bean, you can take
            advantage of Spring’s type-conversion support such that the elements of your strongly-typed
            Collection    instances   are  converted     to the  appropriate     type  prior  to  being   added   to  the Collection.
            The  following   Java   class and   bean  definition   show    how   to do  so:


            Java


              public    class   SomeClass     {


                    private    Map<String,     Float>    accounts;


                    public   void   setAccounts(Map<String,          Float>    accounts)     {
                         this.accounts       = accounts;
                    }
              }



            Kotlin


              class    SomeClass    {
                    lateinit    var   accounts:    Map<String,      Float>
              }




              <beans>
                    <bean   id="something"       class="x.y.SomeClass">
                         <property     name="accounts">
                               <map>
                                    <entry    key="one"     value="9.99"/>
                                    <entry    key="two"     value="2.75"/>
                                    <entry    key="six"     value="3.99"/>
                               </map>
                         </property>
                    </bean>
              </beans>



            When     the   accounts    property     of  the   something     bean    is  prepared     for   injection,   the   generics
            information about the element type of the strongly-typed Map<String, Float> is available by
            reflection.  Thus,   Spring’s   type  conversion     infrastructure     recognizes    the  various    value  elements     as
            being  of  type  Float,  and   the  string  values   (9.99,  2.75,  and  3.99)   are  converted    into  an  actual   Float
            type.



            Null and  Empty   String Values

            Spring   treats  empty    arguments     for  properties    and   the  like  as empty    Strings.   The   following    XML-
            based   configuration    metadata     snippet   sets the  email  property    to the empty    String   value  ("").

              <bean    class="ExampleBean">
                    <property     name="email"     value=""/>
              </bean>



            The  preceding    example    is equivalent    to the  following    Java  code:


            Java


              exampleBean.setEmail("");



            Kotlin


              exampleBean.email        =  ""



            The  <null/>   element    handles   null  values.  The   following   listing  shows   an  example:



              <bean    class="ExampleBean">
                    <property     name="email">
                         <null/>
                    </property>
              </bean>



            The  preceding    configuration     is  equivalent   to the following    Java  code:


            Java


              exampleBean.setEmail(null);



            Kotlin


              exampleBean.email        =  null




            XML  Shortcut   with  the p-namespace

            The  p-namespace      lets you   use  the bean  element’s    attributes   (instead   of nested   <property/>    elements)
            to describe   your   property   values   collaborating    beans,   or both.


            Spring supports extensible configuration formats with namespaces, which are based on an XML
            Schema    definition.   The   beans  configuration     format    discussed    in this  chapter   is defined    in an  XML
            Schema    document.     However,     the  p-namespace       is not  defined   in  an  XSD   file and  exists  only   in the
            core  of Spring.


            The following example shows two XML snippets (the first uses standard XML format and the
            second   uses  the  p-namespace)      that resolve   to the  same   result:

              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="classic"       class="com.example.ExampleBean">
                         <property     name="email"      value="someone@somewhere.com"/>
                    </bean>


                    <bean   name="p-namespace"        class="com.example.ExampleBean"
                         p:email="someone@somewhere.com"/>
              </beans>



            The  example     shows    an  attribute   in the  p-namespace       called  email  in  the  bean   definition.   This  tells
            Spring   to include   a property    declaration.    As  previously    mentioned,     the p-namespace       does  not  have
            a schema    definition,   so you  can  set  the name    of the  attribute   to the property    name.


            This  next  example    includes   two   more   bean   definitions   that  both  have   a reference    to another   bean:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:p="http://www.springframework.org/schema/p"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   name="john-classic"         class="com.example.Person">
                         <property     name="name"      value="John     Doe"/>
                         <property     name="spouse"      ref="jane"/>
                    </bean>


                    <bean   name="john-modern"
                         class="com.example.Person"
                         p:name="John      Doe"
                         p:spouse-ref="jane"/>


                    <bean   name="jane"      class="com.example.Person">
                         <property     name="name"      value="Jane     Doe"/>
                    </bean>
              </beans>



            This example includes not only a property value using the p-namespace but also uses a special
            format    to   declare    property     references.     Whereas       the   first  bean    definition     uses   <property
            name="spouse" ref="jane"/> to create a reference from bean john to bean jane, the second bean
            definition   uses  p:spouse-ref="jane"       as an  attribute   to do  the exact   same   thing.  In this  case,  spouse  is
            the property name, whereas the -ref part indicates that this is not a straight value but rather a
            reference   to another    bean.

                              The  p-namespace       is  not  as  flexible  as  the  standard  XML    format.   For  example,    the
                              format   for  declaring    property    references    clashes   with   properties   that  end   in  Ref,
                             whereas    the  standard    XML   format    does  not.  We   recommend       that  you  choose   your
                              approach     carefully    and    communicate        this  to   your   team    members       to  avoid
                              producing    XML    documents     that  use  all  three approaches     at the  same   time.



            XML  Shortcut   with  the c-namespace

            Similar to the XML Shortcut with the p-namespace, the c-namespace, introduced in Spring 3.1,
            allows  inlined   attributes   for configuring     the constructor    arguments      rather  then   nested   constructor-
            arg elements.


            The  following    example    uses   the  c: namespace      to do  the  same    thing  as the  from   Constructor-based
            Dependency      Injection:



              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:c="http://www.springframework.org/schema/c"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd">


                    <bean   id="beanTwo"      class="x.y.ThingTwo"/>
                    <bean   id="beanThree"       class="x.y.ThingThree"/>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne">
                         <constructor-arg        name="thingTwo"       ref="beanTwo"/>
                         <constructor-arg        name="thingThree"       ref="beanThree"/>
                         <constructor-arg        name="email"      value="something@somewhere.com"/>
                    </bean>


                    
                    <bean   id="beanOne"      class="x.y.ThingOne"         c:thingTwo-ref="beanTwo"
                         c:thingThree-ref="beanThree"            c:email="something@somewhere.com"/>


              </beans>



            The  c: namespace      uses   the same    conventions     as the  p: one   (a trailing  -ref  for  bean   references)    for
            setting  the  constructor    arguments     by  their  names.   Similarly,   it needs   to be  declared   in  the  XML   file
            even  though    it  is  not  defined  in  an  XSD  schema  (it  exists  inside  the  Spring core).

            For the  rare  cases   where   the  constructor    argument     names    are  not  available   (usually   if  the  bytecode
            was   compiled    without    debugging     information),     you   can  use  fallback   to  the  argument     indexes,    as
            follows:

              
              <bean    id="beanOne"     class="x.y.ThingOne"         c:_0-ref="beanTwo"        c:_1-ref="beanThree"
                    c:_2="something@somewhere.com"/>




                              Due  to  the XML    grammar,     the  index   notation    requires   the  presence    of the  leading
                              _, as XML attribute names cannot start with a number (even though some IDEs
                             allow it). A corresponding index notation is also available for <constructor-arg>
                              elements but not commonly used since the plain order of declaration is usually
                              sufficient  there.


            In practice, the constructor resolution mechanism is quite efficient in matching arguments, so
            unless  you   really need   to, we  recommend       using   the name    notation   throughout     your   configuration.



            Compound     Property  Names

            You can use compound or nested property names when you set bean properties, as long as all
            components      of the  path   except   the  final property    name    are  not   null. Consider    the  following    bean
            definition:



              <bean    id="something"      class="things.ThingOne">
                    <property     name="fred.bob.sammy"         value="123"     />
              </bean>



            The  something    bean   has  a fred  property,    which   has  a  bob property,    which   has  a  sammy  property,   and
            that final  sammy  property    is being  set  to a value   of 123. In  order  for  this to work,   the  fred  property    of
            something   and   the  bob property    of  fred  must   not  be  null  after  the bean   is constructed.    Otherwise,     a
            NullPointerException      is thrown.


            Using   depends-on

            If  a  bean is  a  dependency    of another    bean,  that  usually   means    that  one  bean   is set as  a property    of
            another. Typically you accomplish this with the <ref/> element in XML-based configuration
            metadata.    However,     sometimes     dependencies      between    beans   are  less  direct. An   example    is when    a
            static initializer in a class needs to be triggered, such as for database driver registration. The
            depends-on    attribute   can  explicitly  force   one  or  more   beans    to be  initialized  before   the  bean   using
            this element is initialized. The following example uses the depends-on attribute to express a
            dependency     on  a single   bean:



              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager"/>
              <bean    id="manager"     class="ManagerBean"         />



            To express    a dependency      on  multiple   beans,   supply   a list  of  bean  names  as  the value   of the  depends-
            on attribute   (commas,    whitespace,     and  semicolons     are valid  delimiters):

              <bean    id="beanOne"     class="ExampleBean"         depends-on="manager,accountDao">
                    <property     name="manager"      ref="manager"      />
              </bean>


              <bean    id="manager"     class="ManagerBean"         />
              <bean    id="accountDao"       class="x.y.jdbc.JdbcAccountDao"             />




                              The  depends-on    attribute  can   specify  both   an initialization-time     dependency      and,  in
                              the case of singleton beans only, a corresponding destruction-time dependency.
                             Dependent beans that define a depends-on relationship with a given bean are
                              destroyed    first,  prior  to  the  given  bean itself being   destroyed.   Thus,   depends-on    can
                              also control   shutdown     order.



            Lazy-initialized     Beans

            By  default,  ApplicationContext      implementations       eagerly   create   and  configure    all singleton   beans    as
            part  of the  initialization  process.   Generally,    this pre-instantiation     is desirable,   because   errors   in the
            configuration or surrounding environment are discovered immediately, as opposed to hours or
            even days later. When this behavior is not desirable, you can prevent pre-instantiation of a
            singleton   bean   by  marking    the  bean   definition   as being   lazy-initialized.   A  lazy-initialized   bean   tells
            the IoC  container    to create  a bean   instance   when    it is  first  requested, rather   than  at startup.


            In XML, this behavior is controlled by the lazy-init attribute on the <bean/> element, as the
            following   example    shows:



              <bean    id="lazy"    class="com.something.ExpensiveToCreateBean"                  lazy-init="true"/>
              <bean    name="not.lazy"       class="com.something.AnotherBean"/>



            When the preceding configuration is consumed by an ApplicationContext, the lazy bean is not
            eagerly   pre-instantiated     when    the  ApplicationContext      starts,  whereas    the  not.lazy    bean   is eagerly
            pre-instantiated.


            However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-
            initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must
            satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean
            elsewhere    that  is  not  lazy-initialized.

            You can also control lazy-initialization at the container level by using the default-lazy-init
            attribute  on  the  <beans/>   element,   as  the following    example    shows:



              <beans    default-lazy-init="true">
                    
              </beans>

            Autowiring     Collaborators

            The  Spring   container    can   autowire    relationships     between    collaborating     beans.   You  can   let Spring
            resolve   collaborators    (other   beans)   automatically     for  your   bean   by  inspecting    the  contents    of the
            ApplicationContext.      Autowiring    has  the  following    advantages:

              • Autowiring can significantly reduce the need to specify properties or constructor arguments.
                (Other mechanisms such as a bean template discussed elsewhere in this chapter are also
                valuable    in this regard.)

              • Autowiring     can  update    a configuration    as  your  objects   evolve.  For  example,    if you  need   to add   a
                dependency      to  a class,  that dependency       can  be  satisfied  automatically     without    you   needing    to
                modify the configuration. Thus autowiring can be especially useful during development,
                without    negating    the option   of  switching    to explicit  wiring    when    the code   base   becomes     more
                stable.


            When using XML-based configuration metadata (see Dependency Injection), you can specify the
            autowire mode for a bean definition with the autowire attribute of the <bean/> element. The
            autowiring functionality has four modes. You specify autowiring per bean and can thus choose
            which   ones  to  autowire.   The   following   table  describes   the  four  autowiring     modes:


            Table 2. Autowiring    modes

            Mode                     Explanation
            no                       (Default)   No  autowiring.    Bean   references    must   be  defined   by  ref elements.
                                     Changing     the default   setting  is not  recommended       for  larger  deployments,
                                     because    specifying   collaborators     explicitly  gives  greater   control  and   clarity. To
                                     some    extent,  it  documents    the structure   of  a system.
            byName                   Autowiring     by  property    name.   Spring   looks  for a  bean  with   the same    name   as
                                     the  property    that needs   to be  autowired.    For  example,    if a bean   definition   is
                                     set to  autowire    by name    and  it contains   a master   property    (that is, it  has  a
                                     setMaster(..)     method),    Spring   looks  for a  bean  definition   named     master  and
                                     uses  it to set the  property.
            byType                   Lets  a property    be  autowired    if exactly  one   bean  of  the property    type  exists  in
                                     the  container.   If more   than   one  exists, a  fatal exception    is  thrown,  which
                                     indicates   that  you  may   not  use  byType   autowiring    for that  bean.   If  there are no
                                     matching     beans,  nothing    happens    (the  property   is not  set).
            constructor              Analogous     to byType   but  applies  to constructor    arguments.     If there  is not
                                     exactly   one  bean   of the  constructor    argument     type  in the  container,   a fatal
                                     error   is  raised.


            With byType or constructor autowiring mode, you can wire arrays and typed collections. In such
            cases,  all autowire    candidates     within   the  container    that  match    the  expected    type  are  provided     to
            satisfy  the  dependency.     You   can  autowire     strongly-typed     Map  instances   if the  expected    key   type  is
            String. An autowired Map instance’s values consist of all bean instances that match the expected
            type, and   the Map  instance’s   keys  contain   the  corresponding      bean   names.

            Limitations  and  Disadvantages    of Autowiring

            Autowiring works best when it is used consistently across a project. If autowiring is not used in
            general,  it might   be confusing    to developers     to use  it  to  wire  only  one  or  two  bean definitions.


            Consider   the  limitations   and   disadvantages     of autowiring:

              • Explicit  dependencies      in  property   and  constructor-arg      settings  always    override   autowiring.     You
                cannot    autowire    simple   properties    such  as  primitives,   Strings,   and   Classes   (and  arrays   of such
                simple   properties).   This  limitation   is by-design.

              • Autowiring     is less  exact  than   explicit  wiring.   Although,    as  noted   in  the  earlier  table,  Spring   is
                careful to avoid guessing in case of ambiguity that might have unexpected results. The
                relationships    between    your   Spring-managed       objects   are  no longer   documented      explicitly.

              • Wiring information may not be available to tools that may generate documentation from a
                Spring   container.

              • Multiple bean definitions within the container may match the type specified by the setter
                method    or  constructor    argument     to be  autowired.    For  arrays,  collections,   or Map  instances,   this is
                not  necessarily    a problem.    However,     for dependencies      that  expect   a single  value,  this  ambiguity
                is not  arbitrarily  resolved.   If no  unique   bean   definition   is available,   an  exception   is thrown.


            In the  latter scenario,   you  have   several   options:

              • Abandon     autowiring     in favor  of explicit  wiring.

              • Avoid   autowiring     for  a bean   definition    by  setting  its autowire-candidate       attributes   to false,   as
                described    in the  next  section.

              • Designate    a single  bean   definition   as the  primary    candidate    by  setting  the  primary  attribute   of its
                <bean/>   element    to true.

              • Implement the more fine-grained control available with annotation-based configuration, as
                described    in Annotation-based       Container    Configuration.



            Excluding   a  Bean from  Autowiring

            On a per-bean basis, you can exclude a bean from autowiring. In Spring’s XML format, set the
            autowire-candidate      attribute   of the  <bean/>  element    to false.  The   container    makes   that  specific  bean
            definition   unavailable     to the  autowiring     infrastructure     (including   annotation     style  configurations
            such  as @Autowired).


                              The  autowire-candidate       attribute   is designed    to only  affect  type-based     autowiring.
                              It does not affect explicit references by name, which get resolved even if the
                             specified bean is not marked as an autowire candidate. As a consequence,
                              autowiring    by  name    nevertheless    injects  a bean   if  the  name  matches.


            You can also limit autowire candidates based on pattern-matching against bean names. The top-
            level <beans/> element accepts one or more patterns within its default-autowire-candidates
            attribute. For example, to limit autowire candidate status to any bean whose name ends with
            Repository,   provide    a value   of *Repository.    To  provide    multiple   patterns,   define   them   in  a comma-
            separated    list.  An  explicit  value of true  or  false  for  a bean   definition’s   autowire-candidate      attribute

            always   takes  precedence.     For  such  beans,   the pattern   matching     rules  do  not apply.


            These techniques are useful for beans that you never want to be injected into other beans by
            autowiring. It does not mean that an excluded bean cannot itself be configured by using
            autowiring.    Rather,   the bean   itself is not a  candidate    for autowiring    other   beans.


            Method    Injection

            In most   application    scenarios,    most   beans   in the  container    are   singletons.   When    a  singleton   bean
            needs   to collaborate    with  another    singleton   bean   or a  non-singleton     bean   needs   to collaborate    with
            another non-singleton bean, you typically handle the dependency by defining one bean as a
            property    of the  other.  A  problem     arises  when    the  bean   lifecycles   are  different.  Suppose     singleton
            bean   A  needs   to use   non-singleton     (prototype)    bean   B, perhaps     on  each   method    invocation     on  A.
            The  container    creates   the singleton    bean   A only  once,   and  thus   only  gets  one  opportunity     to set the
            properties.   The   container    cannot   provide    bean   A  with  a  new   instance   of  bean   B every   time   one  is
            needed.

            A solution   is to  forego   some   inversion    of control.   You  can   make   bean   A  aware    of the  container    by
            implementing the ApplicationContextAware interface, and by making a getBean("B") call to the
            container ask for (a typically new) bean B instance every time bean A needs it. The following
            example    shows   this  approach:

            Java


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple;


              //  Spring-API      imports
              import    org.springframework.beans.BeansException;
              import    org.springframework.context.ApplicationContext;
              import    org.springframework.context.ApplicationContextAware;


              public    class   CommandManager       implements     ApplicationContextAware          {


                    private    ApplicationContext        applicationContext;


                    public   Object    process(Map      commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    protected     Command    createCommand()       {
                         //  notice    the   Spring   API   dependency!
                         return    this.applicationContext.getBean("command",                 Command.class);
                    }


                    public   void   setApplicationContext(
                               ApplicationContext        applicationContext)        throws    BeansException       {
                         this.applicationContext          =  applicationContext;
                    }
              }

            Kotlin


              //  a  class   that   uses   a  stateful    Command-style       class   to  perform    some   processing
              package    fiona.apple


              //  Spring-API      imports
              import    org.springframework.context.ApplicationContext
              import    org.springframework.context.ApplicationContextAware


              class    CommandManager      :  ApplicationContextAware          {


                    private    lateinit    var   applicationContext:        ApplicationContext


                    fun  process(commandState:          Map<*,   *>):   Any   {
                         //  grab   a  new   instance    of  the   appropriate     Command
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  notice    the  Spring    API  dependency!
                    protected     fun  createCommand()       =
                               applicationContext.getBean("command",               Command::class.java)


                    override    fun   setApplicationContext(applicationContext:                ApplicationContext)         {
                         this.applicationContext          =  applicationContext
                    }
              }



            The preceding is not desirable, because the business code is aware of and coupled to the Spring
            Framework.      Method    Injection,   a somewhat      advanced     feature   of  the  Spring   IoC  container,   lets  you
            handle   this use  case  cleanly.



               You   can  read  more   about   the  motivation    for  Method    Injection   in this blog  entry.





            Lookup   Method   Injection

            Lookup    method    injection   is the  ability of  the  container   to  override   methods     on  container-managed
            beans   and  return   the  lookup    result  for another    named     bean   in the  container.    The  lookup    typically
            involves a prototype bean, as in the scenario described in the preceding section. The Spring
            Framework      implements     this  method    injection   by  using  bytecode    generation    from   the  CGLIB    library
            to dynamically     generate   a  subclass   that overrides    the  method.

                                • For  this  dynamic    subclassing    to  work,   the  class that  the  Spring   bean   container
                                  subclasses    cannot   be  final,  and   the  method    to  be  overridden     cannot   be  final,
                                  either.

                                • Unit-testing    a class  that  has   an  abstract   method     requires    you  to  subclass   the
                                  class  yourself   and  to supply   a stub  implementation       of the  abstract   method.
                               • Concrete    methods     are  also necessary     for component      scanning,    which    requires
                                  concrete   classes   to pick  up.

                                • A further key limitation is that lookup methods do not work with factory
                                  methods and in particular not with @Bean methods in configuration classes,
                                  since,  in  that  case, the  container    is not  in  charge   of  creating   the  instance   and
                                  therefore   cannot    create  a runtime-generated        subclass   on  the fly.


            In the case of the CommandManager class in the previous code snippet, the Spring container
            dynamically     overrides    the implementation       of the  createCommand()      method.    The  CommandManager     class
            does  not  have   any  Spring   dependencies,     as the  reworked     example    shows:


            Java


              package    fiona.apple;


              //  no   more  Spring    imports!


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         Command    command    =  createCommand();
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.setState(commandState);
                         return    command.execute();
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              package    fiona.apple


              //  no   more  Spring    imports!


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         //  grab   a  new   instance    of  the   appropriate     Command    interface
                         val   command    =  createCommand()
                         //  set   the  state    on  the  (hopefully     brand    new)   Command    instance
                         command.state       = commandState
                         return    command.execute()
                    }


                    //  okay...    but  where    is  the  implementation       of  this   method?
                    protected     abstract    fun  createCommand():        Command
              }



            In the client class that contains the method to be injected (the CommandManager in this case), the
            method    to be  injected  requires    a signature   of the  following    form:



              <public|protected>        [abstract]      <return-type>      theMethodName(no-arguments);



            If  the  method   is abstract,   the  dynamically-generated         subclass   implements      the  method.    Otherwise,
            the dynamically-generated subclass overrides the concrete method defined in the original class.
            Consider   the  following    example:



              
              <bean    id="myCommand"      class="fiona.apple.AsyncCommand"              scope="prototype">
                    
              </bean>


              
              <bean    id="commandManager"        class="fiona.apple.CommandManager">
                    <lookup-method      name="createCommand"         bean="myCommand"/>
              </bean>



            The bean identified as commandManager calls its own createCommand() method whenever it needs a
            new   instance   of the  myCommand   bean.   You  must   be  careful  to deploy   the  myCommand    bean   as a prototype
            if that is actually what is needed. If it is a singleton, the same instance of the myCommand bean is
            returned   each   time.


            Alternatively, within the annotation-based component model, you can declare a lookup method
            through   the  @Lookup   annotation,    as the  following   example     shows:

            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup("myCommand")
                    protected     abstract    Command    createCommand();
              }



            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup("myCommand")
                    protected     abstract    fun  createCommand():        Command
              }



            Or, more    idiomatically,   you   can  rely on  the  target  bean   getting   resolved   against   the  declared   return
            type  of the lookup    method:


            Java


              public    abstract    class    CommandManager      {


                    public   Object    process(Object       commandState)      {
                         Command    command    =  createCommand();
                         command.setState(commandState);
                         return    command.execute();
                    }


                    @Lookup
                    protected     abstract    Command    createCommand();
              }

            Kotlin


              abstract     class   CommandManager       {


                    fun  process(commandState:          Any):   Any  {
                         val   command    =  createCommand()
                         command.state       = commandState
                         return    command.execute()
                    }


                    @Lookup
                    protected     abstract    fun  createCommand():        Command
              }



            Note that you should typically declare such annotated lookup methods with a concrete stub
            implementation,      in order   for them    to be  compatible    with   Spring’s  component      scanning    rules  where
            abstract classes get ignored by default. This limitation does not apply to explicitly registered or
            explicitly  imported    bean   classes.


                              Another way of accessing differently scoped target beans is an ObjectFactory/
                              Provider   injection  point.  See  Scoped    Beans   as Dependencies.
                 
                              You       may        also      find       the       ServiceLocatorFactoryBean             (in      the
                              org.springframework.beans.factory.config             package)    to be useful.



            Arbitrary  Method   Replacement

            A less useful form of method injection than lookup method injection is the ability to replace
            arbitrary   methods     in a  managed     bean    with  another    method     implementation.       You  can   safely  skip
            the rest  of this section   until you   actually  need   this functionality.


            With XML-based configuration metadata, you can use the replaced-method element to replace an
            existing  method     implementation       with   another,   for  a  deployed    bean.   Consider    the  following    class,
            which   has  a method    called  computeValue     that  we  want   to override:


            Java


              public    class   MyValueCalculator        {


                    public   String    computeValue(String         input)   {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }

            Kotlin


              class    MyValueCalculator       {


                    fun  computeValue(input:         String):    String    {
                         //  some   real   code...
                    }


                    //  some   other   methods...
              }



            A class that implements the org.springframework.beans.factory.support.MethodReplacer interface
            provides   the  new   method    definition,   as the  following   example     shows:


            Java


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              public    class   ReplacementComputeValue          implements     MethodReplacer       {


                    public   Object    reimplement(Object        o,  Method    m,  Object[]    args)    throws   Throwable     {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         String    input   =  (String)    args[0];
                         ...
                         return    ...;
                    }
              }



            Kotlin


              /**
               *  meant    to  be  used   to  override    the   existing    computeValue(String)
               *  implementation       in  MyValueCalculator
               */
              class    ReplacementComputeValue          : MethodReplacer       {


                    override    fun   reimplement(obj:       Any,   method:    Method,    args:   Array<out     Any>):    Any  {
                         //  get   the  input    value,   work   with   it,   and  return    a computed     result
                         val   input   =  args[0]    as  String;
                         ...
                         return    ...;
                    }
              }



            The  bean   definition    to deploy   the  original   class  and   specify   the  method    override    would    resemble
            the following    example:

              <bean    id="myValueCalculator"         class="x.y.z.MyValueCalculator">
                    
                    <replaced-method       name="computeValue"         replacer="replacementComputeValue">
                         <arg-type>String</arg-type>
                    </replaced-method>
              </bean>


              <bean    id="replacementComputeValue"           class="a.b.c.ReplacementComputeValue"/>



            You  can   use  one   or more    <arg-type/>    elements     within   the  <replaced-method/>       element    to indicate
            the method signature of the method being overridden. The signature for the arguments is
            necessary only if the method is overloaded and multiple variants exist within the class. For
            convenience,     the  type  string  for  an  argument     may   be  a  substring   of  the  fully qualified   type   name.
            For example,    the  following    all  match  java.lang.String:



              java.lang.String
              String
              Str



            Because   the  number     of arguments     is often  enough     to distinguish   between     each  possible   choice,   this
            shortcut can save a lot of typing, by letting you type only the shortest string that matches an
            argument     type.

            2.1.5.   Bean     Scopes

            When    you   create   a bean   definition,   you   create   a recipe   for  creating   actual   instances    of the  class
            defined   by  that  bean   definition.   The  idea  that  a bean   definition    is a recipe   is  important,   because   it
            means   that,  as with   a class, you  can  create   many    object  instances   from   a single  recipe.


            You  can  control   not  only  the  various   dependencies      and   configuration     values   that are  to  be plugged
            into an object that is created from a particular bean definition but also control the scope of the
            objects  created   from    a particular   bean   definition.   This   approach    is powerful     and  flexible,  because
            you  can  choose    the scope   of  the objects   you  create   through    configuration    instead   of  having   to bake
            in the  scope   of  an  object  at  the  Java  class  level.  Beans   can   be  defined   to  be  deployed    in  one  of  a
            number     of scopes.   The  Spring    Framework      supports    six scopes,   four   of which    are  available   only  if
            you  use  a web-aware      ApplicationContext.      You  can  also  create  a custom    scope.

            The  following   table  describes    the supported     scopes:


            Table 3. Bean   scopes

            Scope                    Description

            singleton                (Default)   Scopes   a single  bean   definition   to a single  object   instance   for each
                                     Spring   IoC  container.

            prototype                Scopes   a  single  bean  definition   to  any  number     of object  instances.

            Scope                    Description

            request                  Scopes   a  single  bean  definition   to  the lifecycle  of a single   HTTP   request.   That
                                     is, each  HTTP    request   has  its  own  instance   of a bean   created   off the  back  of  a
                                     single  bean   definition.   Only  valid  in  the context   of a web-aware      Spring
                                     ApplicationContext.

            session                  Scopes   a  single  bean  definition   to  the lifecycle  of an  HTTP    Session.  Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            application              Scopes   a  single  bean  definition   to  the lifecycle  of a ServletContext.     Only   valid
                                     in the  context   of a web-aware      Spring   ApplicationContext.

            websocket                Scopes   a  single  bean  definition   to  the lifecycle  of a WebSocket.    Only  valid  in the
                                     context   of a  web-aware     Spring   ApplicationContext.



                              As  of Spring   3.0,  a thread    scope   is available   but  is  not  registered   by   default.  For
                             more   information,     see  the  documentation       for  SimpleThreadScope.      For  instructions
                              on how    to register  this or  any  other  custom    scope,  see  Using   a Custom    Scope.



            The  Singleton    Scope

            Only  one   shared   instance    of a singleton    bean   is  managed,   and   all requests   for  beans   with   an  ID  or
            IDs that  match    that  bean   definition   result  in  that one   specific  bean   instance    being  returned    by  the
            Spring  container.


            To put  it another    way,  when    you  define   a bean   definition   and   it  is  scoped as a singleton,   the  Spring
            IoC container    creates   exactly   one  instance    of the  object  defined   by  that  bean   definition.   This  single
            instance   is stored   in a  cache   of such   singleton    beans,   and  all subsequent      requests   and   references
            for that  named    bean   return   the  cached    object.  The  following    image   shows    how   the  singleton   scope
            works:








































            Spring’s   concept   of  a singleton    bean   differs  from    the  singleton   pattern   as  defined    in the  Gang    of
            Four  (GoF)   patterns    book.  The   GoF   singleton   hard-codes     the  scope   of  an  object  such   that  one  and

            only  one  instance   of  a particular   class  is created   per  ClassLoader.     The  scope   of the  Spring   singleton
            is  best  described  as being   per-container     and   per-bean.   This  means    that,  if  you  define one  bean   for  a
            particular   class in  a single  Spring   container,   the  Spring   container    creates  one   and  only  one   instance
            of the  class  defined   by  that  bean   definition.   The   singleton   scope   is the  default   scope   in Spring.   To
            define  a bean   as  a singleton   in XML,   you   can  define  a bean   as  shown    in the  following   example:



              <bean    id="accountService"        class="com.something.DefaultAccountService"/>


              
              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="singleton"/>




            The  Prototype     Scope

            The non-singleton prototype scope of bean deployment results in the creation of a new bean
            instance every time a request for that specific bean is made. That is, the bean is injected into
            another    bean   or  you  request    it through    a getBean()    method     call on  the  container.    As  a  rule,  you
            should   use  the prototype    scope   for all stateful  beans   and   the singleton   scope   for  stateless  beans.


            The  following   diagram     illustrates  the Spring   prototype    scope:








































            (A data   access  object   (DAO)   is not  typically   configured    as  a prototype,    because    a  typical  DAO    does
            not hold   any  conversational     state. It was   easier  for us  to reuse  the  core  of the  singleton   diagram.)

            The  following   example     defines   a bean   as a prototype    in XML:



              <bean    id="accountService"        class="com.something.DefaultAccountService"
              scope="prototype"/>



            In contrast   to the  other   scopes,  Spring   does   not  manage     the complete     lifecycle  of a prototype    bean.

            The  container    instantiates,   configures,    and  otherwise     assembles    a  prototype    object  and   hands   it to
            the client,  with   no  further   record   of that  prototype    instance.   Thus,   although    initialization   lifecycle
            callback   methods    are  called  on  all objects   regardless    of scope,  in  the case  of  prototypes,    configured
            destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped
            objects  and   release  expensive     resources    that  the  prototype    beans   hold.  To  get the  Spring   container
            to release  resources    held  by  prototype-scoped      beans,   try  using  a custom    bean   post-processor,     which
            holds  a reference    to beans   that  need   to be cleaned    up.


            In some   respects,   the  Spring   container’s   role  in  regard   to a prototype-scoped       bean  is a  replacement
            for the  Java  new  operator.    All lifecycle  management        past  that  point  must    be  handled    by  the  client.
            (For details  on  the  lifecycle  of a bean   in the  Spring   container,   see  Lifecycle   Callbacks.)


            Singleton    Beans   with   Prototype-bean       Dependencies

            When you use singleton-scoped beans with dependencies on prototype beans, be aware that
            dependencies     are  resolved    at instantiation    time.  Thus,   if  you dependency-inject      a  prototype-scoped
            bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-
            injected  into  the  singleton   bean.   The  prototype    instance    is  the  sole  instance that  is ever  supplied    to
            the singleton-scoped      bean.


            However,    suppose    you   want   the  singleton-scoped      bean   to acquire   a  new   instance   of the  prototype-
            scoped bean repeatedly at runtime. You cannot dependency-inject a prototype-scoped bean into
            your   singleton     bean,    because    that   injection    occurs    only    once,   when     the   Spring    container
            instantiates the singleton bean and resolves and injects its dependencies. If you need a new
            instance   of a prototype    bean   at runtime    more   than   once,  see Method     Injection.


            Request,    Session,   Application,     and   WebSocket      Scopes

            The  request,   session,   application,    and   websocket   scopes   are   available   only  if you   use  a web-aware
            Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you use these
            scopes    with   regular     Spring    IoC   containers,     such   as   the   ClassPathXmlApplicationContext,           an
            IllegalStateException       that complains     about   an  unknown     bean   scope   is thrown.



            Initial  Web Configuration

            To support the scoping of beans at the request, session, application, and websocket levels (web-
            scoped beans), some minor initial configuration is required before you define your beans. (This
            initial setup  is not  required   for  the standard    scopes:   singleton   and   prototype.)


            How   you  accomplish     this  initial setup  depends    on  your   particular   Servlet  environment.


            If  you access  scoped    beans   within   Spring   Web    MVC,   in effect,  within   a request   that  is processed    by
            the  Spring   DispatcherServlet,      no  special   setup   is necessary.   DispatcherServlet       already   exposes    all
            relevant   state.


            If  you use  a  Servlet   web   container,    with  requests    processed    outside   of  Spring’s   DispatcherServlet
            (for     example,        when        using      JSF      or      Struts),     you       need       to     register      the
            org.springframework.web.context.request.RequestContextListener ServletRequestListener. This can
            be done    programmatically       by  using   the WebApplicationInitializer         interface.   Alternatively,    add  the
            following   declaration    to your   web   application’s   web.xml   file:

              <web-app>
                    ...
                    <listener>
                         <listener-class>
                               org.springframework.web.context.request.RequestContextListener
                         </listener-class>
                    </listener>
                    ...
              </web-app>



            Alternatively,     if   there    are    issues     with    your     listener     setup,    consider      using    Spring’s
            RequestContextFilter.        The    filter   mapping       depends      on   the    surrounding       web     application
            configuration,    so you   have   to change    it  as  appropriate.  The  following    listing shows    the  filter part  of
            a web   application:



              <web-app>
                    ...
                    <filter>
                         <filter-name>requestContextFilter</filter-name>
                         <filter-class>org.springframework.web.filter.RequestContextFilter</filter-
              class>
                    </filter>
                    <filter-mapping>
                         <filter-name>requestContextFilter</filter-name>
                         <url-pattern>/*</url-pattern>
                    </filter-mapping>
                    ...
              </web-app>



            DispatcherServlet,     RequestContextListener,        and   RequestContextFilter       all do  exactly   the  same   thing,
            namely    bind  the  HTTP    request   object  to  the  Thread  that  is servicing   that  request.   This  makes    beans
            that are  request-   and  session-scoped      available   further  down    the  call chain.



            Request  scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="loginAction"       class="com.something.LoginAction"              scope="request"/>



            The  Spring   container    creates   a new   instance   of  the LoginAction     bean   by using   the  loginAction    bean
            definition for each and every HTTP request. That is, the loginAction bean is scoped at the HTTP
            request   level. You  can   change   the  internal   state of  the instance    that is created   as  much   as  you  want,
            because other instances created from the same loginAction bean definition do not see these
            changes in state. They are particular to an individual request. When the request completes
            processing,   the  bean   that is scoped   to  the request   is discarded.


            When    using  annotation-driven       components      or Java  configuration,     the  @RequestScope    annotation     can

            be used   to assign  a  component     to the  request   scope.  The   following   example     shows   how   to do  so:


            Java


              @RequestScope
              @Component
              public    class   LoginAction      {
                    //  ...
              }



            Kotlin


              @RequestScope
              @Component
              class    LoginAction     {
                    //  ...
              }




            Session  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>



            The   Spring     container     creates    a  new     instance    of   the   UserPreferences       bean    by   using    the
            userPreferences bean definition for the lifetime of a single HTTP Session. In other words, the
            userPreferences     bean   is effectively   scoped   at the  HTTP    Session   level. As  with   request-scoped     beans,
            you  can  change    the  internal  state  of the  instance   that  is created   as much    as you   want,   knowing    that
            other  HTTP    Session   instances    that  are  also  using  instances    created   from   the  same    userPreferences
            bean  definition    do not  see  these  changes    in state,  because   they   are particular    to an  individual   HTTP
            Session.  When     the  HTTP   Session   is eventually    discarded,    the  bean   that  is scoped   to  that  particular
            HTTP   Session   is also discarded.


            When using annotation-driven components or Java configuration, you can use the @SessionScope
            annotation    to assign   a component      to the session   scope.


            Java


              @SessionScope
              @Component
              public    class   UserPreferences       {
                    //  ...
              }

            Kotlin


              @SessionScope
              @Component
              class    UserPreferences       {
                    //  ...
              }




            Application  Scope

            Consider   the  following    XML   configuration     for a bean   definition:



              <bean    id="appPreferences"        class="com.something.AppPreferences"               scope="application"/>



            The  Spring   container    creates  a  new   instance   of the  AppPreferences     bean   by  using  the  appPreferences
            bean  definition   once   for the  entire  web   application.    That  is, the appPreferences     bean   is scoped   at the
            ServletContext     level  and  stored   as a  regular   ServletContext     attribute.  This  is somewhat      similar   to a
            Spring  singleton    bean  but  differs  in two   important    ways:   It is  a singleton  per ServletContext,     not  per
            Spring   ApplicationContext      (for  which   there   may   be  several   in any   given  web   application),    and   it  is
            actually  exposed    and   therefore   visible  as a ServletContext     attribute.


            When      using     annotation-driven        components         or   Java     configuration,      you     can    use    the
            @ApplicationScope annotation to assign a component to the application scope. The following
            example    shows   how    to do so:


            Java


              @ApplicationScope
              @Component
              public    class   AppPreferences       {
                    //  ...
              }



            Kotlin


              @ApplicationScope
              @Component
              class    AppPreferences      {
                    //  ...
              }




            WebSocket    Scope

            WebSocket     scope   is associated   with   the  lifecycle  of a WebSocket      session  and   applies   to STOMP     over
            WebSocket     applications,   see  WebSocket     scope   for  more   details.

            Scoped  Beans   as Dependencies

            The  Spring   IoC  container     manages     not  only  the  instantiation    of  your   objects  (beans),   but  also  the
            wiring   up  of collaborators     (or dependencies).      If  you want   to inject  (for  example)    an  HTTP    request-
            scoped   bean   into  another    bean   of a  longer-lived    scope,  you   may   choose    to inject  an  AOP   proxy    in
            place  of  the  scoped   bean.   That   is,  you need   to  inject  a proxy    object  that  exposes    the  same   public
            interface as the scoped object but that can also retrieve the real target object from the relevant
            scope  (such   as an  HTTP   request)   and   delegate   method    calls  onto  the  real object.


                              You  may   also  use  <aop:scoped-proxy/>       between    beans   that  are  scoped   as  singleton,
                              with  the  reference    then   going   through    an  intermediate     proxy    that  is serializable
                              and  therefore   able  to  re-obtain   the target  singleton    bean  on  deserialization.


                              When declaring <aop:scoped-proxy/> against a bean of scope prototype, every
                              method    call on  the  shared    proxy   leads   to the  creation   of a  new   target  instance    to
                              which   the  call is  then being  forwarded.

                              Also, scoped    proxies   are  not  the only   way   to access  beans    from   shorter   scopes  in  a
                              lifecycle-safe fashion. You may also declare your injection point (that is, the
                             constructor    or setter  argument     or  autowired    field)  as ObjectFactory<MyTargetBean>,
                              allowing   for  a  getObject()    call to  retrieve   the  current   instance    on  demand     every
                              time  it  is  needed — without    holding    on to  the instance   or  storing  it separately.


                              As an extended variant, you may declare ObjectProvider<MyTargetBean> which
                              delivers    several     additional     access     variants,    including      getIfAvailable      and
                              getIfUnique.


                              The    JSR-330     variant     of   this    is   called    Provider     and     is   used    with     a
                              Provider<MyTargetBean> declaration and a corresponding get() call for every
                              retrieval  attempt.   See  here  for  more   details  on  JSR-330   overall.


            The  configuration     in  the following    example     is only  one   line, but  it is important    to  understand     the
            “why”   as well  as  the “how”    behind   it:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    
                    <bean   id="userPreferences"         class="com.something.UserPreferences"               scope="session">
                         
                         <aop:scoped-proxy/>         ①
                    </bean>


                    
                    <bean   id="userService"       class="com.something.SimpleUserService">
                         
                         <property     name="userPreferences"          ref="userPreferences"/>
                    </bean>
              </beans>


            ① The    line that  defines   the proxy.

            To create   such  a proxy,   you  insert  a child  <aop:scoped-proxy/>       element    into  a scoped   bean   definition
            (see Choosing the Type of Proxy to Create and XML Schema-based configuration). Why do
            definitions   of beans   scoped   at  the request,   session   and  custom-scope      levels  require   the  <aop:scoped-
            proxy/> element? Consider the following singleton bean definition and contrast it with what you
            need to define for the aforementioned scopes (note that the following userPreferences bean
            definition   as it  stands is incomplete):



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session"/>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            In the  preceding    example,    the  singleton   bean   (userManager)    is injected   with  a  reference   to  the HTTP
            Session-scoped bean (userPreferences). The salient point here is that the userManager bean is a
            singleton:   it  is  instantiated exactly   once   per  container,   and   its dependencies      (in this case   only  one,
            the userPreferences bean) are also injected only once. This means that the userManager bean
            operates   only  on  the  exact  same   userPreferences      object  (that  is,  the  one  with which   it was  originally
            injected).

            This  is not  the  behavior    you   want   when    injecting   a  shorter-lived    scoped    bean   into  a longer-lived
            scoped   bean   (for  example,    injecting   an   HTTP   Session-scoped      collaborating     bean   as  a dependency
            into singleton    bean).  Rather,   you   need   a single  userManager     object,  and,  for  the lifetime   of an  HTTP
            Session,  you   need   a userPreferences      object  that  is specific  to the  HTTP    Session.   Thus,  the  container

            creates  an  object   that  exposes   the  exact   same   public   interface   as  the  UserPreferences     class  (ideally
            an  object  that  is a UserPreferences      instance),   which    can  fetch  the  real  UserPreferences      object  from
            the scoping mechanism (HTTP request, Session, and so forth). The container injects this proxy
            object  into the  userManager    bean,   which   is unaware     that  this UserPreferences     reference    is a proxy.   In
            this  example,     when     a   UserManager     instance     invokes    a   method     on   the   dependency-injected
            UserPreferences     object,  it is actually   invoking    a  method     on  the  proxy.   The  proxy    then  fetches   the
            real UserPreferences object from (in this case) the HTTP Session and delegates the method
            invocation    onto  the  retrieved   real UserPreferences      object.

            Thus, you need the following (correct and complete) configuration when injecting request- and
            session-scoped     beans   into collaborating     objects,  as the  following   example    shows:



              <bean    id="userPreferences"        class="com.something.UserPreferences"                scope="session">
                    <aop:scoped-proxy/>
              </bean>


              <bean    id="userManager"       class="com.something.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>




            Choosing    the  Type   of  Proxy   to  Create

            By default, when the Spring container creates a proxy for a bean that is marked up with the
            <aop:scoped-proxy/>      element,    a CGLIB-based     class  proxy   is created.


                              CGLIB   proxies   intercept    only  public   method    calls! Do   not  call non-public    methods
                             on such   a proxy.   They  are  not  delegated    to the  actual  scoped   target  object.


            Alternatively, you can configure the Spring container to create standard JDK interface-based
            proxies   for such   scoped   beans,   by  specifying   false   for the  value   of the  proxy-target-class      attribute
            of the  <aop:scoped-proxy/>      element.    Using   JDK  interface-based      proxies   means    that  you  do  not  need
            additional   libraries   in your   application    classpath    to affect  such   proxying.    However,     it also  means
            that the  class  of  the  scoped   bean   must    implement     at  least one   interface   and   that  all collaborators
            into which    the  scoped    bean   is injected   must   reference    the  bean   through    one  of  its interfaces.   The
            following   example    shows    a proxy   based   on  an  interface:



              
              <bean    id="userPreferences"        class="com.stuff.DefaultUserPreferences"                 scope="session">
                    <aop:scoped-proxy        proxy-target-class="false"/>
              </bean>


              <bean    id="userManager"       class="com.stuff.UserManager">
                    <property     name="userPreferences"         ref="userPreferences"/>
              </bean>



            For   more    detailed    information      about    choosing     class-based     or  interface-based      proxying,     see
            Proxying    Mechanisms.

            Custom    Scopes

            The bean scoping mechanism is extensible. You can define your own scopes or even redefine
            existing  scopes,   although    the  latter is considered     bad  practice   and   you  cannot    override   the  built-in
            singleton   and   prototype   scopes.



            Creating  a Custom   Scope

            To   integrate    your    custom     scopes    into   the   Spring    container,     you    need    to   implement      the
            org.springframework.beans.factory.config.Scope               interface,  which    is  described  in  this section.  For  an
            idea  of how    to implement     your   own    scopes,  see  the  Scope   implementations       that  are  supplied    with
            the Spring Framework itself and the Scope javadoc, which explains the methods you need to
            implement     in more   detail.


            The  Scope   interface   has  four  methods     to  get objects   from   the  scope,   remove    them    from   the  scope,
            and  let them   be  destroyed.


            The session scope implementation, for example, returns the session-scoped bean (if it does not
            exist, the  method    returns   a new   instance   of  the bean,   after  having   bound    it  to  the  session  for  future
            reference).   The  following    method    returns   the  object  from   the underlying     scope:


            Java


              Object    get(String     name,   ObjectFactory<?>        objectFactory)



            Kotlin


              fun   get(name:     String,    objectFactory:      ObjectFactory<*>):        Any



            The session scope implementation, for example, removes the session-scoped bean from the
            underlying    session.   The   object  should    be  returned,    but  you  can   return   null  if the  object   with  the
            specified  name    is not  found.  The   following   method     removes    the  object  from   the underlying     scope:


            Java


              Object    remove(String      name)



            Kotlin


              fun   remove(name:      String):    Any



            The following method registers a callback that the scope should invoke when it is destroyed or
            when   the  specified   object  in the  scope   is  destroyed:


            Java


              void   registerDestructionCallback(String              name,    Runnable    destructionCallback)

            Kotlin


              fun   registerDestructionCallback(name:              String,    destructionCallback:        Runnable)



            See the  javadoc   or  a Spring   scope   implementation      for  more   information     on  destruction    callbacks.

            The  following   method     obtains   the conversation     identifier   for the  underlying    scope:


            Java


              String    getConversationId()



            Kotlin


              fun   getConversationId():         String



            This  identifier  is different   for  each   scope.  For  a  session   scoped   implementation,       this identifier   can
            be the  session   identifier.



            Using a Custom    Scope

            After  you  write   and   test one  or  more   custom    Scope   implementations,       you  need   to make    the  Spring
            container   aware    of your   new   scopes.   The  following    method    is the  central   method    to register   a new
            Scope  with  the  Spring   container:


            Java


              void   registerScope(String         scopeName,     Scope   scope);



            Kotlin


              fun   registerScope(scopeName:          String,    scope:    Scope)



            This  method     is declared   on   the  ConfigurableBeanFactory        interface,   which    is available   through    the
            BeanFactory property on most of the concrete ApplicationContext implementations that ship with
            Spring.


            The  first argument      to the  registerScope(..)       method    is the  unique    name    associated    with   a  scope.
            Examples of such names in the Spring container itself are singleton and prototype. The second
            argument      to   the   registerScope(..)        method      is   an   actual    instance     of   the   custom      Scope
            implementation      that  you  wish   to register  and   use.

            Suppose that you write your custom Scope implementation, and then register it as shown in the
            next  example.

                              The  next  example     uses  SimpleThreadScope,      which   is included    with  Spring   but  is not
                             registered by default. The instructions would be the same for your own custom
                              Scope  implementations.


            Java


              Scope    threadScope     =  new  SimpleThreadScope();
              beanFactory.registerScope("thread",               threadScope);



            Kotlin


              val   threadScope     =  SimpleThreadScope()
              beanFactory.registerScope("thread",               threadScope)



            You can then create bean definitions that adhere to the scoping rules of your custom Scope, as
            follows:



              <bean    id="..."    class="..."     scope="thread">



            With  a  custom   Scope   implementation,      you  are  not  limited   to programmatic      registration    of the  scope.
            You  can  also  do  the  Scope  registration   declaratively,    by  using  the  CustomScopeConfigurer       class,  as the
            following   example    shows:

              <?xml    version="1.0"      encoding="UTF-8"?>
              <beans    xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:aop="http://www.springframework.org/schema/aop"
                    xsi:schemaLocation="http://www.springframework.org/schema/beans
                         https://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/aop
                         https://www.springframework.org/schema/aop/spring-aop.xsd">


                    <bean   class="org.springframework.beans.factory.config.CustomScopeConfigurer">
                         <property     name="scopes">
                               <map>
                                    <entry    key="thread">
                                          <bean
              class="org.springframework.context.support.SimpleThreadScope"/>
                                    </entry>
                               </map>
                         </property>
                    </bean>


                    <bean   id="thing2"      class="x.y.Thing2"        scope="thread">
                         <property     name="name"      value="Rick"/>
                         <aop:scoped-proxy/>
                    </bean>


                    <bean   id="thing1"      class="x.y.Thing1">
                         <property     name="thing2"      ref="thing2"/>
                    </bean>


              </beans>




                              When    you  place   <aop:scoped-proxy/>       within   a <bean>   declaration    for a  FactoryBean
                             implementation,      it is the factory   bean   itself that  is scoped,   not  the  object  returned
                              from  getObject().


            2.1.6.   Customizing          the   Nature       of  a Bean

            The  Spring   Framework       provides    a number     of  interfaces   you   can  use  to  customize    the  nature   of  a
            bean.  This  section   groups   them   as follows:

              • Lifecycle   Callbacks

              • ApplicationContextAware        and  BeanNameAware

              • Other   Aware  Interfaces


            Lifecycle   Callbacks

            To  interact  with   the  container’s    management       of  the bean    lifecycle,  you  can   implement     the  Spring
            InitializingBean and DisposableBean interfaces. The container calls afterPropertiesSet() for the

            former   and   destroy()    for the  latter  to let the  bean   perform     certain  actions   upon    initialization  and
            destruction    of your  beans.


                              The  JSR-250   @PostConstruct      and  @PreDestroy     annotations     are  generally   considered
                              best practice   for receiving    lifecycle  callbacks   in a modern     Spring   application.   Using
                              these annotations means that your beans are not coupled to Spring-specific
                             interfaces.  For  details,  see Using   @PostConstruct     and   @PreDestroy.


                              If you do not want to use the JSR-250 annotations but you still want to remove
                              coupling,   consider   init-method    and   destroy-method     bean   definition   metadata.


            Internally,  the  Spring   Framework       uses  BeanPostProcessor       implementations       to process   any   callback
            interfaces it can find and call the appropriate methods. If you need custom features or other
            lifecycle  behavior    Spring  does   not  by default   offer, you   can  implement     a BeanPostProcessor      yourself.
            For more    information,    see  Container    Extension    Points.


            In addition to the initialization and destruction callbacks, Spring-managed objects may also
            implement     the  Lifecycle   interface   so  that those   objects  can  participate    in the  startup  and   shutdown
            process,  as  driven   by the  container’s    own   lifecycle.


            The  lifecycle  callback   interfaces   are  described    in this section.



            Initialization Callbacks

            The     org.springframework.beans.factory.InitializingBean                   interface     lets    a    bean      perform
            initialization    work    after   the   container     has   set   all  necessary     properties     on   the   bean.    The
            InitializingBean     interface   specifies   a single  method:



              void   afterPropertiesSet()         throws    Exception;



            We  recommend       that  you  do  not  use  the InitializingBean      interface,   because   it unnecessarily     couples
            the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a
            POJO   initialization  method.    In  the  case  of XML-based      configuration    metadata,    you   can  use  the  init-
            method attribute to specify the name of the method that has a void no-argument signature. With
            Java  configuration,    you   can  use  the  initMethod    attribute   of @Bean.  See  Receiving    Lifecycle   Callbacks.
            Consider   the  following    example:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            init-method="init"/>



            Java


              public    class   ExampleBean      {


                    public   void   init()    {
                         //  do   some  initialization       work
                    }
              }

            Kotlin


              class    ExampleBean     {


                    fun  init()    {
                         //  do   some  initialization       work
                    }
              }



            The  preceding    example     has  almost   exactly  the  same   effect  as the  following    example    (which   consists
            of two  listings):



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     InitializingBean        {


                    @Override
                    public   void   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            Kotlin


              class    AnotherExampleBean        : InitializingBean        {


                    override    fun   afterPropertiesSet()         {
                         //  do   some  initialization       work
                    }
              }



            However,    the  first of the  two  preceding    examples     does  not  couple   the  code  to Spring.



            Destruction   Callbacks

            Implementing the org.springframework.beans.factory.DisposableBean interface lets a bean get a
            callback   when    the  container    that  contains   it is destroyed.    The   DisposableBean     interface   specifies   a
            single  method:



              void   destroy()     throws    Exception;



            We  recommend       that  you   do  not  use  the DisposableBean      callback   interface,  because    it unnecessarily
            couples   the  code  to Spring.   Alternatively,    we  suggest   using   the @PreDestroy     annotation    or  specifying
            a generic   method     that  is supported     by  bean   definitions.   With   XML-based      configuration     metadata,
            you  can   use  the  destroy-method     attribute   on  the  <bean/>.   With   Java  configuration,     you   can  use  the

            destroyMethod      attribute    of  @Bean.   See    Receiving     Lifecycle    Callbacks.    Consider     the   following
            definition:



              <bean    id="exampleInitBean"        class="examples.ExampleBean"            destroy-method="cleanup"/>



            Java


              public    class   ExampleBean      {


                    public   void   cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    ExampleBean     {


                    fun  cleanup()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            The  preceding    definition   has  almost   exactly   the same    effect as  the following    definition:



              <bean    id="exampleInitBean"        class="examples.AnotherExampleBean"/>



            Java


              public    class   AnotherExampleBean        implements     DisposableBean       {


                    @Override
                    public   void   destroy()     {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }



            Kotlin


              class    AnotherExampleBean        : DisposableBean       {


                    override    fun   destroy()    {
                         //  do   some  destruction      work   (like   releasing     pooled   connections)
                    }
              }

            However,    the  first of the  two  preceding    definitions   does   not  couple   the code   to Spring.


                              You  can  assign   the destroy-method     attribute   of a <bean>   element    a special  (inferred)
                              value, which instructs Spring to automatically detect a public close or shutdown
                              method       on     the    specific     bean      class.     (Any     class     that    implements
                              java.lang.AutoCloseable or java.io.Closeable would therefore match.) You can
                             also  set this  special  (inferred)    value   on  the  default-destroy-method        attribute   of  a
                              <beans> element to apply this behavior to an entire set of beans (see Default
                              Initialization  and   Destroy   Methods).    Note   that this  is  the  default behavior   with   Java
                              configuration.



            Default  Initialization and  Destroy  Methods

            When you write initialization and destroy method callbacks that do not use the Spring-specific
            InitializingBean      and  DisposableBean      callback   interfaces,   you   typically   write  methods     with   names
            such as init(), initialize(), dispose(), and so on. Ideally, the names of such lifecycle callback
            methods    are  standardized      across  a  project  so  that  all developers    use   the same    method    names    and
            ensure   consistency.


            You can configure the Spring container to “look” for named initialization and destroy callback
            method names on every bean. This means that you, as an application developer, can write your
            application    classes  and   use  an  initialization   callback   called  init(),   without   having    to configure    an
            init-method="init"      attribute   with  each   bean   definition.   The  Spring    IoC container    calls  that  method
            when   the  bean   is created   (and  in accordance     with   the standard    lifecycle  callback   contract   described
            previously).   This  feature   also enforces    a consistent   naming     convention    for  initialization   and  destroy
            method    callbacks.

            Suppose that your initialization callback methods are named init() and your destroy callback
            methods    are  named    destroy().   Your   class then   resembles    the  class  in the following    example:


            Java


              public    class   DefaultBlogService        implements     BlogService      {


                    private    BlogDao    blogDao;


                    public   void   setBlogDao(BlogDao        blogDao)     {
                         this.blogDao      =  blogDao;
                    }


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    public   void   init()    {
                         if  (this.blogDao       ==  null)   {
                               throw   new   IllegalStateException("The           [blogDao]    property     must   be  set.");
                         }
                    }
              }

            Kotlin


              class    DefaultBlogService        : BlogService      {


                    private    var  blogDao:     BlogDao?    =  null


                    //  this   is  (unsurprisingly)       the   initialization      callback     method
                    fun  init()    {
                         if  (blogDao     ==  null)   {
                               throw   IllegalStateException("The           [blogDao]     property    must   be  set.")
                         }
                    }
              }



            You  could  then   use  that class  in a bean   resembling     the  following:



              <beans    default-init-method="init">


                    <bean   id="blogService"       class="com.something.DefaultBlogService">
                         <property     name="blogDao"       ref="blogDao"      />
                    </bean>


              </beans>



            The  presence    of the  default-init-method      attribute   on  the  top-level  <beans/>    element   attribute   causes
            the  Spring   IoC  container    to recognize     a method     called  init  on  the  bean    class  as the  initialization
            method    callback.   When    a  bean   is  created  and  assembled,     if the bean    class has   such  a  method,    it  is
            invoked   at the  appropriate     time.


            You can configure destroy method callbacks similarly (in XML, that is) by using the default-
            destroy-method     attribute  on  the  top-level  <beans/>    element.


            Where    existing   bean   classes   already   have   callback    methods    that  are   named    at  variance    with  the
            convention,    you   can  override   the  default   by  specifying   (in  XML,   that  is) the method     name    by using
            the init-method    and   destroy-method     attributes   of the  <bean/>  itself.


            The  Spring   container    guarantees    that  a configured    initialization   callback   is called  immediately     after
            a bean   is supplied   with   all dependencies.     Thus,   the  initialization  callback    is  called on  the raw   bean
            reference,   which   means    that  AOP   interceptors    and   so forth  are  not  yet  applied   to the  bean.  A  target
            bean  is fully  created   first and  then  an  AOP   proxy   (for  example)    with  its interceptor    chain   is  applied.
            If  the  target bean   and  the  proxy    are  defined   separately,   your   code   can  even   interact   with  the  raw
            target  bean,   bypassing    the  proxy.   Hence,   it would    be  inconsistent    to  apply   the  interceptors    to the
            init method, because doing so would couple the lifecycle of the target bean to its proxy or
            interceptors and leave strange semantics when your code interacts directly with the raw target
            bean.

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Chroma/Chroma Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/chroma/chroma-compose.yaml)

services:
  chroma:
    image: '{imageName}'
    ports:
      - '8000'

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Chroma/Chroma With Token Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/chroma/chroma-with-token-compose.yaml)

services:
  chroma:
    image: '{imageName}'
    ports:
      - '8000'
    environment:
      - CHROMA_SERVER_AUTHN_CREDENTIALS=secret
      - CHROMA_SERVER_AUTHN_PROVIDER=chromadb.auth.token_authn.TokenAuthenticationServerProvider

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Docker/Docker Agents Gateway Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/docker/docker-agents-gateway-compose.yaml)

services:
  mcp-gateway:
    image: '{imageName}'
    ports:
      - 8811
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    command:
      - --transport=sse

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Milvus/Milvus Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/milvus/milvus-compose.yaml)

services:
  milvus:
    image: '{imageName}'
    command: milvus run standalone
    ports:
      - '9091'
      - '19530'
    environment:
      - COMMON_STORAGETYPE=local
      - DEPLOY_MODE=STANDALONE
      - ETCD_USE_EMBED=true
      - ETCD_DATA_DIR=/var/lib/milvus/etcd
      - ETCD_CONFIG_PATH=/milvus/configs/embedEtcd.yaml
    configs:
      - source: embedEtcd
        target: /milvus/configs/embedEtcd.yaml

configs:
  embedEtcd:
    content: |
      listen-client-urls: http://0.0.0.0:2379
      advertise-client-urls: http://0.0.0.0:2379

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Mongo/Mongo Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/mongo/mongo-compose.yaml)

services:
  mongo:
    image: '{imageName}'
    ports:
      - '27017'

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Ollama/Ollama Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/ollama/ollama-compose.yaml)

services:
  ollama:
    image: '{imageName}'
    ports:
      - '11434'

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Opensearch/Localstack Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/opensearch/localstack-compose.yaml)

services:
  localstack:
    image: '{imageName}'
    ports:
      - '4566'

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Opensearch/Opensearch Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/opensearch/opensearch-compose.yaml)

services:
  opensearch:
    image: '{imageName}'
    ports:
      - '9200'
    environment:
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=D3v3l0p-ment
      - discovery.type=single-node

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Qdrant/Qdrant Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/qdrant/qdrant-compose.yaml)

services:
  qdrant:
    image: '{imageName}'
    ports:
      - '6334'
    environment:
      - QDRANT__SERVICE__API_KEY=springai

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Typesense/Typesense Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/typesense/typesense-compose.yaml)

services:
  typesense:
    image: '{imageName}'
    ports:
      - '8108'
    command: '--data-dir /tmp --enable-cors'
    environment:
        - TYPESENSE_API_KEY=secret

---

### Spring Ai Spring Boot Docker Compose/Src/Test/Resources/Org/Springframework/Ai/Docker/Compose/Service/Connection/Weaviate/Weaviate Compose.Yaml (spring-ai-spring-boot-docker-compose/src/test/resources/org/springframework/ai/docker/compose/service/connection/weaviate/weaviate-compose.yaml)

services:
  weaviate:
    image: '{imageName}'
    ports:
      - '8080'
    environment:
      - AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true
      - PERSISTENCE_DATA_PATH=/var/lib/weaviate

---

### Spring Ai Test/README (spring-ai-test/README.md)

# Spring AI Test

The Spring AI Test module provides utilities and base classes for testing AI applications built with Spring AI.

## Features

- **BasicEvaluationTest**: A base test class for evaluating question-answer quality using AI models
- **Vector Store Testing**: Utilities for testing vector store implementations
- **Audio Testing**: Utilities for testing audio-related functionality

## BasicEvaluationTest

The `BasicEvaluationTest` class provides a framework for evaluating the quality and relevance of AI-generated answers to questions.

### Usage

Extend the `BasicEvaluationTest` class in your test classes:

```java
@SpringBootTest
public class MyAiEvaluationTest extends BasicEvaluationTest {

    @Test
    public void testQuestionAnswerAccuracy() {
        String question = "What is the capital of France?";
        String answer = "The capital of France is Paris.";
        
        // Evaluate if the answer is accurate and related to the question
        evaluateQuestionAndAnswer(question, answer, true);
    }
}
```

### Configuration

The test requires:
- A `ChatModel` bean (typically OpenAI)
- Evaluation prompt templates located in `classpath:/prompts/spring/test/evaluation/`

### Evaluation Types

- **Fact-based evaluation**: Use `factBased = true` for questions requiring factual accuracy
- **General evaluation**: Use `factBased = false` for more subjective questions

The evaluation process:
1. Checks if the answer is related to the question
2. Evaluates the accuracy/appropriateness of the answer
3. Fails the test with detailed feedback if the answer is inadequate

---

### Spring Ai Test/Src/Main/Resources/Test/Data/Great.Depression (spring-ai-test/src/main/resources/test/data/great.depression.txt)

The Great Depression (1929–1939) was an economic shock that affected most countries across the world. It was a period of economic depression that became evident after a major fall in stock prices in the United States.[1] The economic contagion began around September 1929 and led to the Wall Street stock market crash of October 24 (Black Thursday). It was the longest, deepest, and most widespread depression of the 20th century.[2]
Between 1929 and 1932, worldwide gross domestic product (GDP) fell by an estimated 15%. By comparison, worldwide GDP fell by less than 1% from 2008 to 2009 during the Great Recession.[3] Some economies started to recover by the mid-1930s. However, in many countries,[specify] the negative effects of the Great Depression lasted until the beginning of World War II. Devastating effects were seen in both rich and poor countries with falling personal income, prices, tax revenues, and profits. International trade fell by more than 50%, unemployment in the U.S. rose to 23% and in some countries rose as high as 33%.[4]
Cities around the world were hit hard, especially those dependent on heavy industry. Construction was virtually halted in many countries. Farming communities and rural areas suffered as crop prices fell by about 60%.[5][6][7] Faced with plummeting demand and few job alternatives, areas dependent on primary sector industries suffered the most.[8]
Economic historians usually consider the catalyst of the Great Depression to be the sudden devastating collapse of U.S. stock market prices, starting on October 24, 1929. However, some dispute this conclusion, seeing the stock crash less than a cause of the Depression and more as a symptom of the rising nervousness of investors partly due to gradual price declines caused by falling sales of consumer goods (as a result of overproduction because of new production techniques, falling exports and income inequality, among other factors) that had already been underway as part of a gradual Depression

---

### Spring Ai Test/Src/Main/Resources/Test/Data/Spring.Ai (spring-ai-test/src/main/resources/test/data/spring.ai.txt)

The Spring AI project aims to streamline the development of applications that incorporate artificial intelligence functionality without unnecessary complexity.
The project draws inspiration from notable Python projects, such as LangChain and LlamaIndex, but Spring AI is not a direct port of those projects. The project was founded with the belief that the next wave of Generative AI applications will not be only for Python developers but will be ubiquitous across many programming languages.
At its core, Spring AI provides abstractions that serve as the foundation for developing AI applications. These abstractions have multiple implementations, enabling easy component swapping with minimal code changes. For example, Spring AI introduces the ChatModel interface with implementations for OpenAI and Azure OpenAI.
In addition to these core abstractions, Spring AI aims to provide higher-level functionalities to address common use cases such as “Q&A over your documentation” or “Chat with your documentation.” As the complexity of the use cases increases, the Spring AI project will integrate with other projects in the Spring Ecosystem, such as Spring Integration, Spring Batch, and Spring Data.
To simplify setup, Spring Boot starters are available to help set up essential dependencies and classes. There is also a collection of sample applications to help you explore the project’s features. Lastly, the new Spring CLI project also enables you to get started quickly by using the spring boot new AI command for new projects or spring boot add AI for adding AI capabilities to your existing application.

---

### Spring Ai Test/Src/Main/Resources/Test/Data/Time.Shelter (spring-ai-test/src/main/resources/test/data/time.shelter.txt)

Somewhere in the Andes, they believe in this very day that the future is behind you. It comes up from behind your back, surprising and unforeseeable, while the past is always before your eyes, that which has already happened. When they talk about the past, the people of the Aymara tribe point in front of them. You walk forward facing the past, and you turn back toward the future.
― Georgi Gospodinov, Time Shelter

---

### Spring Ai Tool Search Tool/Src/Main/Resources/DEFAULT SYSTEM PROMPT SUFFIX (spring-ai-tool-search-tool/src/main/resources/DEFAULT_SYSTEM_PROMPT_SUFFIX.md)

You have access to a special tool called `toolSearchTool` that allows you to discover relevant tools on-demand. When you need to perform an action but don't see an appropriate tool in your current context, use `toolSearchTool` to search for it.

---

### Spring Ai Tool Search Tool/Src/Main/Resources/DEFAULT SYSTEM PROMPT SUFFIX LARGE (spring-ai-tool-search-tool/src/main/resources/DEFAULT_SYSTEM_PROMPT_SUFFIX_LARGE.md)

You are an AI assistant with access to a large library of tools. However, not all tools are loaded into your context initially to conserve context window space and improve accuracy.

### Tool Discovery Process

You have access to a special tool called `toolSearchTool` that allows you to discover relevant tools on-demand. When you need to perform an action but don't see an appropriate tool in your current context, use `toolSearchTool` to search for it.

**How tool search works:**
1. When you receive a request that may require tools not currently visible to you, call `toolSearchTool` with a search query describing what capability you need
2. The search will return references to matching tools (typically 3-5 most relevant)
3. These tool references will be automatically expanded into full tool definitions that you can then use
4. Select the most appropriate discovered tool and invoke it with the required parameters

**When to use tool search:**
- When you need a capability not provided by your currently available tools
- When the user's request implies operations (database queries, API calls, file operations, etc.) that require specific tools
- When you're unsure which tool to use for a complex task - search can help you discover the right one

**Search query best practices:**
- Use descriptive keywords related to the functionality you need
- Include domain-specific terms (e.g., "github pull request", "slack message", "database query")
- You can search by functionality ("send notification"), by service ("jira"), or by action type ("create ticket")

**Available tool categories in this system:**
[PLACEHOLDER: List your tool categories here, e.g., "Slack messaging, GitHub operations, database queries, file management, calendar scheduling"]

Remember: After discovering tools via search, you must still invoke them using the standard tool calling mechanism. The search only makes tools visible to you - it doesn't execute them.

---

### Spring Ai Vector Store/Src/Main/Resources/META INF/Additional Spring Configuration Metadata.Json (spring-ai-vector-store/src/main/resources/META-INF/additional-spring-configuration-metadata.json)

{
  "groups": [],
  "properties": [
    {
      "name": "spring.ai.vectorstore.type",
      "type": "java.lang.String",
      "description": "Vector store type. Requires a vector store."
    }
  ],
  "hints": [],
  "ignored": {
    "properties": []
  }
}

---

### Src/Checkstyle/Checkstyle Header (src/checkstyle/checkstyle-header.txt)

^\Q/*\E$
^\Q * Copyright 2023-present the original author or authors.\E$
^\Q *\E$
^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$
^\Q * you may not use this file except in compliance with the License.\E$
^\Q * You may obtain a copy of the License at\E$
^\Q *\E$
^\Q *      https://www.apache.org/licenses/LICENSE-2.0\E$
^\Q *\E$
^\Q * Unless required by applicable law or agreed to in writing, software\E$
^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$
^\Q * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\E$
^\Q * See the License for the specific language governing permissions and\E$
^\Q * limitations under the License.\E$
^\Q */\E$
^$
^.*$

---

### Src/Ecosystem Ci/README (src/ecosystem-ci/README.md)

# Ecosystem CI Dashboard

This directory contains the configuration for the Spring AI Ecosystem CI Dashboard, which monitors the CI health of key ecosystem dependencies.

## Overview

The dashboard workflow runs daily and:
1. Queries CI status for each monitored repository
2. Updates the [Wiki Dashboard](https://github.com/spring-projects/spring-ai/wiki/Ecosystem-CI-Dashboard) with current status
3. Posts alerts to [Issue #5334](https://github.com/spring-projects/spring-ai/issues/5334) when dependencies fail for extended periods

## Subscribing to Alerts

To receive notifications when ecosystem dependencies fail CI:

1. Go to [Issue #5334](https://github.com/spring-projects/spring-ai/issues/5334)
2. Click **Subscribe** in the right sidebar
3. You'll receive GitHub notifications when alerts are posted

## Alert Policy

| Condition | Action |
|-----------|--------|
| Dependency fails (day 1) | Dashboard updated, no alert |
| Dependency fails for 2+ days | Alert comment posted (triggers notification) |
| Dependency recovers | Dashboard updated, no alert |

The `alert_after_days` setting in `ci-alert-config.json` controls the threshold (default: 2 days).

## Adding or Removing Dependencies

Edit `ci-alert-config.json`:

```json
{
  "dependencies": [
    { "owner": "org-name", "repo": "repo-name" },
    ...
  ]
}
```

Each dependency must have:
- `owner`: GitHub organization or user
- `repo`: Repository name

The workflow monitors the branch specified by `tracked_branch` (default: `main`).

## Configuration Reference

| Field | Description | Default |
|-------|-------------|---------|
| `issue_number` | GitHub issue for dashboard and alerts | 5334 |
| `tracked_branch` | Branch to monitor for each repo | main |
| `alert_after_days` | Days of failure before alerting | 2 |
| `heartbeat_days` | Minimum days between repeat alerts | 1 |

## Manual Trigger

To run the dashboard manually:

1. Go to [Actions > Ecosystem CI Dashboard](https://github.com/spring-projects/spring-ai/actions/workflows/dependency-ci-dashboard.yml)
2. Click **Run workflow**
3. Select the `main` branch and click **Run workflow**

## Files

- `ci-alert-config.json` - Dashboard configuration
- `../../.github/workflows/dependency-ci-dashboard.yml` - GitHub Actions workflow

---

### Src/Ecosystem Ci/Ci Alert Config.Json (src/ecosystem-ci/ci-alert-config.json)

{
  "issue_number": 5334,
  "tracked_branch": "main",
  "alert_after_days": 2,
  "heartbeat_days": 1,
  "dependencies": [
    { "owner": "modelcontextprotocol", "repo": "java-sdk" },
    { "owner": "spring-projects", "repo": "spring-ai-examples" },
    { "owner": "spring-projects", "repo": "spring-ai-integration-tests" },
    { "owner": "spring-ai-community", "repo": "spring-ai-tool-search-tool" },
    { "owner": "spring-ai-community", "repo": "spring-ai-agent-utils" },
    { "owner": "spring-ai-community", "repo": "mcp-security" },
    { "owner": "spring-ai-community", "repo": "mcp-annotations" }
  ]
}

---

### Src/Prompts/Update To M7 (src/prompts/update-to-m7.txt)

Please perform the following three tasks in my project:

  Important: File Access Instructions

  - For all file reading operations, use the view tool to view file contents. e.g. cat on linux/mac
  - For multi-module projects, you'll need to examine multiple pom.xml or build.gradle files
  - Examples:
  cat pom.xml                   # For Maven root project
  cat module/pom.xml            # For Maven modules
  cat build.gradle              # For Gradle
  cat module/build.gradle       # For Gradle modules
  cat build.gradle.kts          # For Kotlin DSL

  Task 1: Update Spring AI BOM Version to 1.0.0-M7

  For Maven (pom.xml):
  - Replace <version>1.0.0-M6</version> or older versions with <version>1.0.0-M7</version> within the spring-ai-bom dependency
  - Use the exact whitespace/indentation from the original file

  For Gradle (build.gradle or build.gradle.kts):
  - Update implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-M6") or older versions to:
  implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-M7")

  Task 2: Ensure All Required Repositories Exist

  For Maven (pom.xml):
  - Verify these three repositories exist in pom.xml file:

  <repository>
    <id>spring-milestones</id>
    <name>Spring Milestones</name>
    <url>https://repo.spring.io/milestone</url>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>

  - Add any missing repositories to the <repositories> section
  - Use the existing indentation style from the pom.xml file

  For Gradle:
  - Add any missing repositories with proper formatting:
  repositories {
      mavenCentral()
      maven {
          url = uri("https://repo.spring.io/milestone")
          mavenContent {
              releasesOnly()
          }
      }
  }

  Task 3: Update Spring AI Artifact IDs

  Apply this pattern for all Spring AI starters:
  - Model starters: spring-ai-{model}-spring-boot-starter → spring-ai-starter-model-{model}
  - Vector Store starters: spring-ai-{store}-store-spring-boot-starter → spring-ai-starter-vector-store-{store}
  - MCP starters: spring-ai-mcp-{type}-spring-boot-starter → spring-ai-starter-mcp-{type}

  For Maven (pom.xml) - Examples:
  
  <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
  </dependency>

  
  <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-starter-model-openai</artifactId>
  </dependency>

  For Gradle - Examples:
  // BEFORE
  implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
  implementation 'org.springframework.ai:spring-ai-redis-store-spring-boot-starter'

  // AFTER
  implementation 'org.springframework.ai:spring-ai-starter-model-openai'
  implementation 'org.springframework.ai:spring-ai-starter-vector-store-redis'

  CRITICAL - Do NOT make these changes:

  1. Do NOT change any XML tags such as:
    - Do NOT change <name> to <n> (leave all <name> tags exactly as they are)
    - Do NOT modify any other XML elements like <description>, <properties>, etc.
  2. Do NOT attempt to fix XML formatting:
    - Do NOT add or remove whitespace except where specifically instructed
    - Do NOT add or remove newlines
    - Do NOT reformat XML indentation
  3. Make ONLY the three specific changes described above:
    - Update spring-ai-bom version to 1.0.0-M7
    - Add missing repositories from the list above
    - Update Spring AI artifactIds using the specified patterns

  For all replacements, maintain the exact indentation and whitespace from the original file.

---

### Src/Prompts/Update To Snapshot (src/prompts/update-to-snapshot.txt)

Please perform the following three tasks in my project:

  Important: File Access Instructions

  - For all file reading operations, use the view tool to view file contents. e.g. cat on linux/mac
  - For multi-module projects, you'll need to examine multiple pom.xml or build.gradle files
  - Examples:
  cat pom.xml                   # For Maven root project
  cat module/pom.xml            # For Maven modules
  cat build.gradle              # For Gradle
  cat module/build.gradle       # For Gradle modules
  cat build.gradle.kts          # For Kotlin DSL

  Task 1: Update Spring AI BOM Version to 1.0.0-SNAPSHOT

  For Maven (pom.xml):
  - Replace <version>1.0.0-M5</version> with <version>1.0.0-SNAPSHOT</version> within the spring-ai-bom dependency
  - Use the exact whitespace/indentation from the original file

  For Gradle (build.gradle or build.gradle.kts):
  - Update implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-M5") to:
  implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT")

  Task 2: Ensure All Required Repositories Exist

  For Maven (pom.xml):
  - Verify these three repositories exist in pom.xml file:

  <repository>
    <id>spring-milestones</id>
    <name>Spring Milestones</name>
    <url>https://repo.spring.io/milestone</url>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>

  <repository>
    <id>spring-snapshots</id>
    <name>Spring Snapshots</name>
    <url>https://repo.spring.io/snapshot</url>
    <releases>
      <enabled>false</enabled>
    </releases>
  </repository>

  <repository>
    <id>central-portal-snapshots</id>
    <name>Central Portal Snapshots</name>
    <url>https://central.sonatype.com/repository/maven-snapshots/</url>
    <releases>
      <enabled>false</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>

  - Add any missing repositories to the <repositories> section
  - Use the existing indentation style from the pom.xml file

  For Gradle:
  - Add any missing repositories with proper formatting:
  repositories {
      mavenCentral()
      maven {
          url = uri("https://repo.spring.io/milestone")
          mavenContent {
              releasesOnly()
          }
      }
      maven {
          url = uri("https://repo.spring.io/snapshot")
          mavenContent {
              snapshotsOnly()
          }
      }
      maven {
          url = uri("https://central.sonatype.com/repository/maven-snapshots/")
          mavenContent {
              snapshotsOnly()
          }
      }
  }

  Task 3: Update Spring AI Artifact IDs

  Apply this pattern for all Spring AI starters:
  - Model starters: spring-ai-{model}-spring-boot-starter → spring-ai-starter-model-{model}
  - Vector Store starters: spring-ai-{store}-store-spring-boot-starter → spring-ai-starter-vector-store-{store}
  - MCP starters: spring-ai-mcp-{type}-spring-boot-starter → spring-ai-starter-mcp-{type}

  For Maven (pom.xml) - Examples:
  
  <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
  </dependency>

  
  <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-starter-model-openai</artifactId>
  </dependency>

  For Gradle - Examples:
  // BEFORE
  implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
  implementation 'org.springframework.ai:spring-ai-redis-store-spring-boot-starter'

  // AFTER
  implementation 'org.springframework.ai:spring-ai-starter-model-openai'
  implementation 'org.springframework.ai:spring-ai-starter-vector-store-redis'

  CRITICAL - Do NOT make these changes:

  1. Do NOT change any XML tags such as:
    - Do NOT change <name> to <n> (leave all <name> tags exactly as they are)
    - Do NOT modify any other XML elements like <description>, <properties>, etc.
  2. Do NOT attempt to fix XML formatting:
    - Do NOT add or remove whitespace except where specifically instructed
    - Do NOT add or remove newlines
    - Do NOT reformat XML indentation
  3. Make ONLY the three specific changes described above:
    - Update spring-ai-bom version to 1.0.0-SNAPSHOT
    - Add missing repositories from the list above
    - Update Spring AI artifactIds using the specified patterns

  For all replacements, maintain the exact indentation and whitespace from the original file.

---

### Src/Rewrite/Migrate To 2 0 0 M3.Yaml (src/rewrite/migrate-to-2-0-0-M3.yaml)

---
type: specs.openrewrite.org/v1beta/recipe
name: org.springframework.ai.migration.MigrateToSpringAI200M3
displayName: Migrate to Spring AI 2.0.0-M3
description: >
  Umbrella recipe that applies all breaking-change migrations required for
  Spring AI 2.0.0-M3. Run this recipe to perform all changes in one step.

  Included migrations:
    - M3MigrateMcpAnnotations:              org.springaicommunity:mcp-annotations → spring-ai-mcp-annotations
    - M3MigrateMcpSpringTransports:         io.modelcontextprotocol.sdk mcp-spring-webflux/webmvc → org.springframework.ai
    - M3MigrateMcpClientCustomizer:         McpAsyncClientCustomizer / McpSyncClientCustomizer → McpClientCustomizer<B>

tags:
  - spring-ai
  - mcp
  - migration

recipeList:
  - org.springframework.ai.migration.M3MigrateMcpAnnotations
  - org.springframework.ai.migration.M3MigrateMcpSpringTransports
  - org.springframework.ai.migration.M3MigrateMcpClientCustomizer

---
type: specs.openrewrite.org/v1beta/recipe
name: org.springframework.ai.migration.M3MigrateMcpAnnotations
displayName: Migrate MCP annotations from springaicommunity to Spring AI
description: >
  Migrates all MCP annotation, method-callback, provider, and context classes from the
  removed `org.springaicommunity:mcp-annotations` library to their new locations
  inside `org.springframework.ai:spring-ai-mcp-annotations`.

  Package changes:
    org.springaicommunity.mcp.annotation.*  → org.springframework.ai.mcp.annotation.*
    org.springaicommunity.mcp.method.*      → org.springframework.ai.mcp.annotation.method.*
    org.springaicommunity.mcp.provider.*    → org.springframework.ai.mcp.annotation.provider.*
    org.springaicommunity.mcp.context.*     → org.springframework.ai.mcp.annotation.context.*

tags:
  - spring-ai
  - mcp
  - migration

recipeList:

  # -------------------------------------------------------------------------
  # Maven: remove the old external dependency (classes are now in spring-ai)
  # -------------------------------------------------------------------------
  - org.openrewrite.maven.RemoveDependency:
      groupId: org.springaicommunity
      artifactId: mcp-annotations

  # -------------------------------------------------------------------------
  # Java: text-based package renamings (no classpath resolution needed).
  # Sub-packages (method, provider, context) must come before the parent
  # annotation package to avoid double-rewriting already-replaced strings.
  # -------------------------------------------------------------------------

  - org.openrewrite.text.FindAndReplace:
      find: "org.springaicommunity.mcp.method."
      replace: "org.springframework.ai.mcp.annotation.method."
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "org.springaicommunity.mcp.provider."
      replace: "org.springframework.ai.mcp.annotation.provider."
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "org.springaicommunity.mcp.context."
      replace: "org.springframework.ai.mcp.annotation.context."
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "org.springaicommunity.mcp.annotation."
      replace: "org.springframework.ai.mcp.annotation."
      filePattern: "**/*.java"

---
type: specs.openrewrite.org/v1beta/recipe
name: org.springframework.ai.migration.M3MigrateMcpSpringTransports
displayName: Migrate MCP Spring transport modules from MCP Java SDK to Spring AI
description: >
  Migrates the `mcp-spring-webflux` and `mcp-spring-webmvc` transport modules
  from the MCP Java SDK (`io.modelcontextprotocol.sdk`) to Spring AI
  (`org.springframework.ai`).

  Maven dependency group ID changes:
    io.modelcontextprotocol.sdk:mcp-spring-webflux  → org.springframework.ai:mcp-spring-webflux
    io.modelcontextprotocol.sdk:mcp-spring-webmvc   → org.springframework.ai:mcp-spring-webmvc

  Java package changes (server transports):
    io.modelcontextprotocol.server.transport.WebFluxSseServerTransportProvider        → org.springframework.ai.mcp.server.webflux.transport
    io.modelcontextprotocol.server.transport.WebFluxStreamableServerTransportProvider → org.springframework.ai.mcp.server.webflux.transport
    io.modelcontextprotocol.server.transport.WebFluxStatelessServerTransport           → org.springframework.ai.mcp.server.webflux.transport
    io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider         → org.springframework.ai.mcp.server.webmvc.transport
    io.modelcontextprotocol.server.transport.WebMvcStreamableServerTransportProvider  → org.springframework.ai.mcp.server.webmvc.transport
    io.modelcontextprotocol.server.transport.WebMvcStatelessServerTransport            → org.springframework.ai.mcp.server.webmvc.transport

  Java package changes (client transports):
    io.modelcontextprotocol.client.transport.WebFluxSseClientTransport          → org.springframework.ai.mcp.client.webflux.transport
    io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport   → org.springframework.ai.mcp.client.webflux.transport

tags:
  - spring-ai
  - mcp
  - migration

recipeList:

  # -------------------------------------------------------------------------
  # Maven: change group ID for the WebFlux transport.
  # Text-based regex replacement is used instead of
  # org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId because that
  # recipe requires Maven to fully resolve the POM model first — which fails
  # when the dependency declares no <version> (version managed via BOM/parent).
  # The \s+ capture group preserves whatever whitespace/indentation the file uses.
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "<groupId>io\\.modelcontextprotocol\\.sdk</groupId>(\\s+)<artifactId>mcp-spring-webflux</artifactId>"
      replace: "<groupId>org.springframework.ai</groupId>$1<artifactId>mcp-spring-webflux</artifactId>"
      regex: true
      filePattern: "**/pom.xml"

  # -------------------------------------------------------------------------
  # Maven: change group ID for the WebMvc transport (same rationale as above).
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "<groupId>io\\.modelcontextprotocol\\.sdk</groupId>(\\s+)<artifactId>mcp-spring-webmvc</artifactId>"
      replace: "<groupId>org.springframework.ai</groupId>$1<artifactId>mcp-spring-webmvc</artifactId>"
      regex: true
      filePattern: "**/pom.xml"

  # -------------------------------------------------------------------------
  # Java: server transport classes (WebFlux)
  # FindAndReplace is used instead of ChangeType because the old artifacts are
  # no longer on the classpath, making AST-based type resolution impossible.
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.server.transport.WebFluxSseServerTransportProvider"
      replace: "org.springframework.ai.mcp.server.webflux.transport.WebFluxSseServerTransportProvider"
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.server.transport.WebFluxStreamableServerTransportProvider"
      replace: "org.springframework.ai.mcp.server.webflux.transport.WebFluxStreamableServerTransportProvider"
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.server.transport.WebFluxStatelessServerTransport"
      replace: "org.springframework.ai.mcp.server.webflux.transport.WebFluxStatelessServerTransport"
      filePattern: "**/*.java"

  # -------------------------------------------------------------------------
  # Java: server transport classes (WebMvc)
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider"
      replace: "org.springframework.ai.mcp.server.webmvc.transport.WebMvcSseServerTransportProvider"
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.server.transport.WebMvcStreamableServerTransportProvider"
      replace: "org.springframework.ai.mcp.server.webmvc.transport.WebMvcStreamableServerTransportProvider"
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.server.transport.WebMvcStatelessServerTransport"
      replace: "org.springframework.ai.mcp.server.webmvc.transport.WebMvcStatelessServerTransport"
      filePattern: "**/*.java"

  # -------------------------------------------------------------------------
  # Java: client transport classes (WebFlux)
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.client.transport.WebFluxSseClientTransport"
      replace: "org.springframework.ai.mcp.client.webflux.transport.WebFluxSseClientTransport"
      filePattern: "**/*.java"

  - org.openrewrite.text.FindAndReplace:
      find: "io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport"
      replace: "org.springframework.ai.mcp.client.webflux.transport.WebClientStreamableHttpTransport"
      filePattern: "**/*.java"

  # -------------------------------------------------------------------------
  # Java: McpJsonMapper.createDefault() → McpJsonDefaults.getMapper()
  # The factory method moved from McpJsonMapper to McpJsonDefaults.
  # Replace the call first, then the import so the import line is also updated.
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "McpJsonMapper.createDefault()"
      replace: "McpJsonDefaults.getMapper()"
      filePattern: "**/*.java"

  # Always add the McpJsonDefaults import alongside McpJsonMapper.
  # If McpJsonMapper is no longer used after the call-site replacement above,
  # it will surface as an unused-import warning for manual cleanup.
  - org.openrewrite.text.FindAndReplace:
      find: "import io.modelcontextprotocol.json.McpJsonMapper;"
      replace: "import io.modelcontextprotocol.json.McpJsonDefaults;\nimport io.modelcontextprotocol.json.McpJsonMapper;"
      filePattern: "**/*.java"

---
type: specs.openrewrite.org/v1beta/recipe
name: org.springframework.ai.migration.M3MigrateMcpClientCustomizer
displayName: Migrate McpAsyncClientCustomizer and McpSyncClientCustomizer to McpClientCustomizer
description: >
  Replaces the removed `McpAsyncClientCustomizer` and `McpSyncClientCustomizer` interfaces
  with the new generic `McpClientCustomizer<B>` interface introduced in Spring AI 2.0.0-M3.

  Changes applied:
    - Import `org.springframework.ai.mcp.customizer.McpAsyncClientCustomizer`
        → `org.springframework.ai.mcp.customizer.McpClientCustomizer`
        + adds `import io.modelcontextprotocol.client.McpClient;`
    - Import `org.springframework.ai.mcp.customizer.McpSyncClientCustomizer`
        → `org.springframework.ai.mcp.customizer.McpClientCustomizer`
        + adds `import io.modelcontextprotocol.client.McpClient;`
    - Simple-name usage `McpAsyncClientCustomizer` → `McpClientCustomizer<McpClient.AsyncSpec>`
    - Simple-name usage `McpSyncClientCustomizer` → `McpClientCustomizer<McpClient.SyncSpec>`

  NOTE: `McpSyncHttpClientRequestCustomizer` and `McpAsyncHttpClientRequestCustomizer`
  (from `io.modelcontextprotocol.client.transport.customizer`) are no longer applied by
  the auto-configurations. Migrate them manually to
  `McpClientCustomizer<HttpClientSseClientTransport.Builder>` or
  `McpClientCustomizer<HttpClientStreamableHttpTransport.Builder>` as appropriate.

tags:
  - spring-ai
  - mcp
  - migration

recipeList:

  # -------------------------------------------------------------------------
  # Step 1 — rewrite the fully-qualified import for McpAsyncClientCustomizer.
  # The McpClient import is added at the same time because the new parameterised
  # type McpClientCustomizer<McpClient.AsyncSpec> requires it at the call-site.
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "import org.springframework.ai.mcp.customizer.McpAsyncClientCustomizer;"
      replace: "import io.modelcontextprotocol.client.McpClient;\nimport org.springframework.ai.mcp.customizer.McpClientCustomizer;"
      filePattern: "**/*.java"

  # -------------------------------------------------------------------------
  # Step 2 — rewrite the fully-qualified import for McpSyncClientCustomizer.
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "import org.springframework.ai.mcp.customizer.McpSyncClientCustomizer;"
      replace: "import io.modelcontextprotocol.client.McpClient;\nimport org.springframework.ai.mcp.customizer.McpClientCustomizer;"
      filePattern: "**/*.java"

  # -------------------------------------------------------------------------
  # Step 3 — replace simple-name occurrences of McpAsyncClientCustomizer
  # (return types, implements clauses, parameter types, variable declarations).
  # Must run AFTER the import replacement so the import line is not touched
  # again (it no longer contains "McpAsyncClientCustomizer" at this point).
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "McpAsyncClientCustomizer"
      replace: "McpClientCustomizer<McpClient.AsyncSpec>"
      filePattern: "**/*.java"

  # -------------------------------------------------------------------------
  # Step 4 — replace simple-name occurrences of McpSyncClientCustomizer.
  # -------------------------------------------------------------------------
  - org.openrewrite.text.FindAndReplace:
      find: "McpSyncClientCustomizer"
      replace: "McpClientCustomizer<McpClient.SyncSpec>"
      filePattern: "**/*.java"

---

### Vector Stores/Spring Ai Azure Store/README (vector-stores/spring-ai-azure-store/README.md)

[Azure AI Search Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/azure.html)

---

### Vector Stores/Spring Ai Cassandra Store/README (vector-stores/spring-ai-cassandra-store/README.md)

[Apache Cassandra Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/apache-cassandra.html)

---

### Vector Stores/Spring Ai Chroma Store/README (vector-stores/spring-ai-chroma-store/README.md)

[Chroma Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/chroma.html)

---

### Vector Stores/Spring Ai Coherence Store/README (vector-stores/spring-ai-coherence-store/README.md)

[Oracle Coherence Vector Search Documentation](https://docs.oracle.com/)

---

### Vector Stores/Spring Ai Couchbase Store/README (vector-stores/spring-ai-couchbase-store/README.md)

[Couchbase Vector Store Documentation](https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/vectordbs/couchbase.html)

---

### Vector Stores/Spring Ai Gemfire Store/README (vector-stores/spring-ai-gemfire-store/README.md)

[GemFire Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/gemfire.html)

---

### Vector Stores/Spring Ai Mariadb Store/README (vector-stores/spring-ai-mariadb-store/README.md)

[MariaDB Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/mariadb.html)

---

### Vector Stores/Spring Ai Milvus Store/README (vector-stores/spring-ai-milvus-store/README.md)

[Milvus Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/milvus.html)

---

### Vector Stores/Spring Ai Neo4j Store/README (vector-stores/spring-ai-neo4j-store/README.md)

[Neo4j Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/neo4j.html)

---

### Vector Stores/Spring Ai Oracle Store/README (vector-stores/spring-ai-oracle-store/README.md)

[Oracle AI Vector Search Documentation](https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/ai_vector_search.html)

---

### Vector Stores/Spring Ai Pgvector Store/README (vector-stores/spring-ai-pgvector-store/README.md)

[PGvector Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/pgvector.html)

---

### Vector Stores/Spring Ai Pinecone Store/README (vector-stores/spring-ai-pinecone-store/README.md)

[Pinecone Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/pinecone.html)

---

### Vector Stores/Spring Ai Qdrant Store/README (vector-stores/spring-ai-qdrant-store/README.md)

# Qdrant Vector Store

[Reference Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/qdrant.html)

## Run locally

### Accessing the Web UI

First, run the Docker container:

```
docker run -p 6333:6333 -p 6334:6334 \
    -v $(pwd)/qdrant_storage:/qdrant/storage:z \
    qdrant/qdrant
```

### Security: Adding API Key to Qdrant Container
To enhance security, you can add an API key to your Qdrant container using the environment variable.

```
-e QDRANT__SERVICE__API_KEY=<your_generated_api_key_here>
```

This ensures that only authorized users with the correct API key can access the Qdrant service.

The GUI is available at http://localhost:6333/dashboard

## Qdrant references

- https://qdrant.tech/documentation/interfaces/
- https://github.com/qdrant/java-client

---

### Vector Stores/Spring Ai Redis Semantic Cache/README (vector-stores/spring-ai-redis-semantic-cache/README.md)

# Redis Semantic Cache for Spring AI

This module provides a Redis-based implementation of semantic caching for Spring AI.

## Overview

Semantic caching allows storing and retrieving chat responses based on the semantic similarity of user queries.
This implementation uses Redis vector search capabilities to efficiently find similar queries and return cached responses.

## Features

- Store chat responses with their associated queries in Redis
- Retrieve responses based on semantic similarity
- Support for time-based expiration of cached entries
- Includes a ChatClient advisor for automatic caching
- Built on Redis vector search technology

## Requirements

- Redis Stack with Redis Query Engine and RedisJSON modules
- Java 17 or later
- Spring AI core dependencies
- An embedding model for vector generation

## Usage

### Maven Configuration

```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-redis-semantic-cache</artifactId>
</dependency>
```

For Spring Boot applications, you can use the starter:

```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-vector-store-redis-semantic-cache</artifactId>
</dependency>
```

### Basic Usage

```java
// Create Redis client
RedisClient jedisClient = RedisClient.builder().hostAndPort("localhost", 6379).build();

// Create the embedding model
EmbeddingModel embeddingModel = new OpenAiEmbeddingModel(apiKey);

// Create the semantic cache
SemanticCache semanticCache = DefaultSemanticCache.builder()
    .jedisClient(jedisClient)
    .embeddingModel(embeddingModel)
    .similarityThreshold(0.85) // Optional: adjust similarity threshold (0-1)
    .build();

// Create the cache advisor
SemanticCacheAdvisor cacheAdvisor = SemanticCacheAdvisor.builder()
    .cache(semanticCache)
    .build();

// Use with ChatClient
ChatResponse response = ChatClient.builder(chatModel)
    .build()
    .prompt("What is the capital of France?")
    .advisors(cacheAdvisor) // Add the advisor
    .call()
    .chatResponse();
```

### Direct Cache Usage

You can also use the cache directly:

```java
// Store a response
semanticCache.set("What is the capital of France?", parisResponse);

// Store with expiration
semanticCache.set("What's the weather today?", weatherResponse, Duration.ofHours(1));

// Retrieve a semantically similar response
Optional<ChatResponse> response = semanticCache.get("Tell me the capital city of France");

// Clear the cache
semanticCache.clear();
```

## Configuration Options

The `DefaultSemanticCache` can be configured with the following options:

- `jedisClient` - The Redis client
- `vectorStore` - Optional existing vector store to use
- `embeddingModel` - The embedding model for vector generation
- `similarityThreshold` - Threshold for determining similarity (0-1)
- `indexName` - The name of the Redis search index
- `prefix` - Key prefix for Redis documents

## Spring Boot Integration

When using Spring Boot and the Redis Semantic Cache starter, the components will be automatically configured.
You can customize behavior using properties in `application.properties` or `application.yml`:

```yaml
spring:
  ai:
    vectorstore:
      redis:
        semantic-cache:
          host: localhost
          port: 6379
          similarity-threshold: 0.85
          index-name: semantic-cache
```

---

### Vector Stores/Spring Ai Redis Store/README (vector-stores/spring-ai-redis-store/README.md)

# Spring AI Redis Vector Store

A Redis-based vector store implementation for Spring AI using Redis Stack with Redis Query Engine and RedisJSON.

## Documentation

For comprehensive documentation, see
the [Redis Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/redis.html).

## Features

- Vector similarity search using KNN
- Range-based vector search with radius threshold
- Text-based search on TEXT fields
- Support for multiple distance metrics (COSINE, L2, IP)
- Multiple text scoring algorithms (BM25, TFIDF, etc.)
- HNSW and FLAT vector indexing algorithms
- Configurable metadata fields (TEXT, TAG, NUMERIC)
- Filter expressions for advanced filtering
- Batch processing support

## Usage

### KNN Search

The standard similarity search returns the k-nearest neighbors:

```java
// Create Redis client
RedisClient jedisClient = RedisClient.builder().hostAndPort("localhost", 6379).build();

// Create the vector store
RedisVectorStore vectorStore = RedisVectorStore.builder(jedisClient, embeddingModel)
    .indexName("my-index")
    .vectorAlgorithm(Algorithm.HNSW)
    .distanceMetric(DistanceMetric.COSINE)
    .build();

// Add documents
vectorStore.add(List.of(
    new Document("content1", Map.of("category", "AI")),
    new Document("content2", Map.of("category", "DB"))
));

// Search with KNN
List<Document> results = vectorStore.similaritySearch(
    SearchRequest.builder()
        .query("AI and machine learning")
        .topK(5)
        .similarityThreshold(0.7)
        .filterExpression("category == 'AI'")
        .build()
);
```

### Text Search

The text search capability allows you to find documents based on keywords and phrases in TEXT fields:

```java
// Search for documents containing specific text
List<Document> textResults = vectorStore.searchByText(
    "machine learning",   // search query
    "content",            // field to search (must be TEXT type)
    10,                   // limit
    "category == 'AI'"    // optional filter expression
);
```

Text search supports:

- Single word searches
- Phrase searches with exact matching when `inOrder` is true
- Term-based searches with OR semantics when `inOrder` is false
- Stopword filtering to ignore common words
- Multiple text scoring algorithms (BM25, TFIDF, DISMAX, etc.)

Configure text search behavior at construction time:

```java
RedisClient jedisClient = RedisClient.builder().hostAndPort("localhost", 6379).build();
RedisVectorStore vectorStore = RedisVectorStore.builder(jedisClient, embeddingModel)
    .textScorer(TextScorer.TFIDF)                    // Text scoring algorithm
    .inOrder(true)                                   // Match terms in order
    .stopwords(Set.of("is", "a", "the", "and"))      // Ignore common words
    .metadataFields(MetadataField.text("description")) // Define TEXT fields
    .build();
```

### Range Search

The range search returns all documents within a specified radius:

```java
// Search with radius
List<Document> rangeResults = vectorStore.searchByRange(
    "AI and machine learning",  // query
    0.8,                        // radius (similarity threshold)
    "category == 'AI'"          // optional filter expression
);
```

You can also set a default range threshold at construction time:

```java
RedisClient jedisClient = RedisClient.builder().hostAndPort("localhost", 6379).build();
RedisVectorStore vectorStore = RedisVectorStore.builder(jedisClient, embeddingModel)
    .defaultRangeThreshold(0.8)  // Set default threshold
    .build();

// Use default threshold
List<Document> results = vectorStore.searchByRange("query");
```

## Configuration Options

The Redis Vector Store supports multiple configuration options:

```java
RedisClient jedisClient = RedisClient.builder().hostAndPort("localhost", 6379).build();
RedisVectorStore vectorStore = RedisVectorStore.builder(jedisClient, embeddingModel)
    .indexName("custom-index")        // Redis index name
    .prefix("custom-prefix")          // Redis key prefix
    .contentFieldName("content")      // Field for document content
    .embeddingFieldName("embedding")  // Field for vector embeddings
    .vectorAlgorithm(Algorithm.HNSW)  // Vector algorithm (HNSW or FLAT)
    .distanceMetric(DistanceMetric.COSINE) // Distance metric
    .hnswM(32)                        // HNSW parameter for connections
    .hnswEfConstruction(100)          // HNSW parameter for index building
    .hnswEfRuntime(50)                // HNSW parameter for search
    .defaultRangeThreshold(0.8)       // Default radius for range searches
    .textScorer(TextScorer.BM25)      // Text scoring algorithm
    .inOrder(true)                    // Match terms in order
    .stopwords(Set.of("the", "and"))  // Stopwords to ignore
    .metadataFields(                  // Metadata field definitions
        MetadataField.tag("category"),
        MetadataField.numeric("year"),
        MetadataField.text("description")
    )
    .initializeSchema(true)           // Auto-create index schema
    .build();
```

## Distance Metrics

The Redis Vector Store supports three distance metrics:

- **COSINE**: Cosine similarity (default)
- **L2**: Euclidean distance
- **IP**: Inner Product

Each metric is automatically normalized to a 0-1 similarity score, where 1 is most similar.

## Text Scoring Algorithms

For text search, several scoring algorithms are supported:

- **BM25**: Modern version of TF-IDF with term saturation (default)
- **TFIDF**: Classic term frequency-inverse document frequency
- **BM25STD**: Standardized BM25
- **DISMAX**: Disjunction max
- **DOCSCORE**: Document score

Scores are normalized to a 0-1 range for consistency with vector similarity scores.

---

### Vector Stores/Spring Ai Weaviate Store/README (vector-stores/spring-ai-weaviate-store/README.md)

[Weaviate Vector Store Documentation](https://docs.spring.io/spring-ai/reference/api/vectordbs/weaviate.html)

---

### Vector Stores/Spring Ai Weaviate Store/Src/Test/Resources/Docker Compose.Yml (vector-stores/spring-ai-weaviate-store/src/test/resources/docker-compose.yml)

version: '3.4'
services:
  weaviate:
    command:
    - --host
    - 0.0.0.0
    - --port
    - '8080'
    - --scheme
    - http
    image: semitechnologies/weaviate:1.31.22
    ports:
    - "8080:8080"
    restart: on-failure:0
    environment:
      QUERY_DEFAULTS_LIMIT: 25
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
      DEFAULT_VECTORIZER_MODULE: 'none'
      CLUSTER_HOSTNAME: 'node1'

---

### .Github/PULL REQUEST TEMPLATE (.github/PULL_REQUEST_TEMPLATE.md)

Thank you for taking time to contribute this pull request!
You might have already read the [contributor guide][1], but as a reminder, please make sure to:

* Add a Signed-off-by line to each commit (`git commit -s`) per the [DCO](https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring#how-to-use-developer-certificate-of-origin)
* Rebase your changes on the latest `main` branch and squash your commits
* Add/Update unit tests as needed
* Run a build and make sure all tests pass prior to submission

For more details, please check the [contributor guide][1].
Thank you upfront!

[1]: https://github.com/spring-projects/spring-ai/blob/main/CONTRIBUTING.adoc

---

### .Github/Release Files Spec.Json (.github/release-files-spec.json)

{
  "files": [
    {
      "aql": {
        "items.find": {
          "$and": [
            {
              "@build.name": "${buildname}",
              "@build.number": "${buildnumber}",
              "path": {"$match": "org*"}
            },
            {
              "$or": [
                {
                  "name": {"$match": "*.pom"}
                },
                {
                  "name": {"$match": "*.jar"}
                }
              ]
            }
          ]
        }
      },
      "target": "nexus/"
    }
  ]
}

---

### .Github/Workflow Generator.Yml (.github/workflow-generator.yml)

workflow:
  generator:
    project:
      java:
        versions:
          primary: 17
    workflows:
      release-train:
        build:
          env:
            COMMERCIAL_ARTIFACTORY_USERNAME: secrets.COMMERCIAL_ARTIFACTORY_USERNAME
            COMMERCIAL_ARTIFACTORY_PASSWORD: secrets.COMMERCIAL_ARTIFACTORY_PASSWORD
            COMMERCIAL_RELEASE_REPO_URL: vars.COMMERCIAL_RELEASE_REPO_URL
        test:
          env:
            COMMERCIAL_ARTIFACTORY_USERNAME: secrets.COMMERCIAL_ARTIFACTORY_USERNAME
            COMMERCIAL_ARTIFACTORY_PASSWORD: secrets.COMMERCIAL_ARTIFACTORY_PASSWORD
            COMMERCIAL_RELEASE_REPO_URL: vars.COMMERCIAL_RELEASE_REPO_URL

---

### .Github/Actions/Create Github Release/Action.Yml (.github/actions/create-github-release/action.yml)

name: Create GitHub Release
description: 'Create the release on GitHub with a changelog'
inputs:
  commercial:
    description: 'Whether to generate the changelog for the commercial release'
    required: true
  draft:
    description: 'Whether to create the release as a draft'
    required: false
    default: 'false'
  latest:
    description: 'Whether the release is the latest release'
    required: false
    default: 'false'
  milestone:
    description: 'Name of the GitHub milestone for which a release will be created'
    required: true
  pre-release:
    description: 'Whether the release is a pre-release (a milestone or release candidate)'
    required: false
    default: 'false'
  token:
    description: 'Token to use for authentication with GitHub'
    required: true
runs:
  using: composite
  steps:
    - name: Generate Changelog
      uses: spring-io/github-changelog-generator@f7d7a87a3e7c627ecb8c26cf086c38ac5a939721 #v0.0.14
      with:
        config-file: ${{ inputs.commercial == 'true' && '.github/actions/create-github-release/changelog-generator-commercial.yml' || '.github/actions/create-github-release/changelog-generator-oss.yml' }}
        milestone: ${{ inputs.milestone }}
        token: ${{ inputs.token }}
    - name: Create GitHub Release
      shell: bash
      env:
        GITHUB_TOKEN: ${{ inputs.token }}
        TAG: ${{ format('v{0}', inputs.milestone) }}
      run: gh release create "$TAG" --title "$TAG" --verify-tag --notes-file changelog.md ${{ inputs.pre-release == 'true' && '--prerelease' || format('--latest={0}', inputs.latest) }} ${{ inputs.draft == 'true' && '--draft' || '' }}

---

### .Github/Actions/Create Github Release/Changelog Generator Commercial.Yml (.github/actions/create-github-release/changelog-generator-commercial.yml)

changelog:
  issues:
    generate_links: false
contributors:
  exclude:
    names:
      - "tzolov"
      - "sdeleuze"
      - "ilayaperumalg"
      - "ericbottard"
      - "sobychacko"
      - "dimitarproynov"

---

### .Github/Actions/Create Github Release/Changelog Generator Oss.Yml (.github/actions/create-github-release/changelog-generator-oss.yml)

changelog:
  issues:
    generate_links: true
contributors:
  exclude:
    names:
      - "tzolov"
      - "sdeleuze"
      - "ilayaperumalg"
      - "ericbottard"
      - "sobychacko"
      - "dimitarproynov"

---

### .Github/Actions/Do Autoconfigure Test/Action.Yml (.github/actions/do-autoconfigure-test/action.yml)

name: "Run Spring AI Autoconfigure Integration Tests"
description: "Run integration tests for all Spring AI auto-configuration modules"

inputs:
  spring-ai-branch:
    description: "Spring AI branch being tested (used for branch-specific test conditions)"
    required: true
    default: "main"
  maven-properties:
    description: "Additional Maven properties to pass to the build"
    required: false
    default: ""
  spring-boot-version:
    description: "Spring Boot version to test against (leave empty to use the project default)"
    required: false
    default: ""

runs:
  using: "composite"
  steps:
    - name: Check environment
      uses: actions/github-script@v7
      with:
        script: |
          const env = ${{ toJson(env) }}
          const emptyEnvEntries = Object.entries(env).filter(e => e[1].length === 0)
          emptyEnvEntries.length > 0 &&
            core.setFailed('Missing value for environment variable(s): ' + emptyEnvEntries.map(e => e[0]).join(', '));

    - name: Run Spring AI Retry Autoconfigure test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/common/spring-ai-autoconfigure-retry \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Chat Observation test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/chat/observation/spring-ai-autoconfigure-model-chat-observation \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Embedding Observation test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/embedding/observation/spring-ai-autoconfigure-model-embedding-observation \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Image Observation test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/image/observation/spring-ai-autoconfigure-model-image-observation \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Chat Client test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/chat/client/spring-ai-autoconfigure-model-chat-client \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Neo4j Chat memory repository test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-neo4j \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Cassandra Chat memory repository test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-cassandra \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure JDBC Chat memory repository test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MongoDB Chat memory repository test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-mongodb \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Redis Chat memory test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/chat/memory/spring-ai-autoconfigure-model-chat-memory-redis \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Tooling test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/tool/spring-ai-autoconfigure-model-tool \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Anthropic Model test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-anthropic \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure DeepSeek test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-deepseek \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure ElevenLabs test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-elevenlabs \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Google GenAI test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-google-genai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Azure OpenAI test
      if: ${{ inputs.spring-ai-branch == '1.0.x' || inputs.spring-ai-branch == '1.1.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-azure-openai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Bedrock AI test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-bedrock-ai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Huggingface test
      if: ${{ inputs.spring-ai-branch == '1.1.x' || inputs.spring-ai-branch == '1.0.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-huggingface \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Minimax test
      if: ${{ inputs.spring-ai-branch == '1.0.x' || inputs.spring-ai-branch == '1.1.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-minimax \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Mistral AI test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-mistral-ai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure OCI GenAI test
      if: ${{ inputs.spring-ai-branch == '1.1.x' || inputs.spring-ai-branch == '1.0.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-oci-genai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Ollama test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-ollama \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure OpenAI test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-openai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure PostgresML Embedding test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-postgresml-embedding \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Stability AI test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-stability-ai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Transformers test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-transformers \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Vertex AI test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-vertex-ai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure ZhipuAI test
      if: ${{ inputs.spring-ai-branch == '1.1.x' || inputs.spring-ai-branch == '1.0.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/models/spring-ai-autoconfigure-model-zhipuai \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Azure vector store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-azure \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Azure Cosmos DB test
      if: ${{ inputs.spring-ai-branch == '1.1.x' || inputs.spring-ai-branch == '1.0.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-azure-cosmos-db \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Cassandra Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-cassandra \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Chroma Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-chroma \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Couchbase Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-couchbase \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure ElasticSearch Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-elasticsearch \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure GemFire Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-gemfire \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Mariadb Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mariadb \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Milvus Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-milvus \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MongoDB Atlas Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-mongodb-atlas \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Neo4j Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-neo4j \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Vector Store Observation test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-observation \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Opensearch Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-opensearch \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Oracle Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-oracle \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Pgvector test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pgvector \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Pinecone Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-pinecone \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Qdrant Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-qdrant \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Redis Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-redis \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Redis Semantic Cache Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-redis-semantic-cache \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Typesense Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-typesense \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure Weaviate Vector Store test
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/vector-stores/spring-ai-autoconfigure-vector-store-weaviate \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP Client test
      if: ${{ inputs.spring-ai-branch == '1.0.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-client \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP common Client test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-common \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP HTTP Client test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP Webflux Client test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-webflux \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP Server test
      if: ${{ inputs.spring-ai-branch == '1.0.x' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-server \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP common Server test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP Webflux Server test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webflux \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

    - name: Run Spring AI Autoconfigure MCP WebMVC Server test
      if: ${{ inputs.spring-ai-branch == 'main' }}
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webmvc \
          -Pintegration-tests ${{ inputs.maven-properties }} ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} -Dfailsafe.rerunFailingTestsCount=2 verify

---

### .Github/Actions/Do Integration Test/Action.Yml (.github/actions/do-integration-test/action.yml)

name: "Run Spring AI Integration Test"
description: "Run integration tests for a single Spring AI model module"

inputs:
  model-name:
    description: "Spring AI model to integration test (e.g. ollama, anthropic, mistral-ai)"
    required: true
  maven-properties:
    description: "Additional Maven properties to pass to the build"
    required: false
    default: ""
  spring-boot-version:
    description: "Spring Boot version to test against (leave empty to use the project default)"
    required: false
    default: ""

runs:
  using: "composite"
  steps:
    - name: Check environment
      uses: actions/github-script@v7
      with:
        script: |
          const env = ${{ toJson(env) }}
          const emptyEnvEntries = Object.entries(env).filter(e => e[1].length === 0)
          emptyEnvEntries.length > 0 &&
            core.setFailed('Missing value for environment variable(s): ' + emptyEnvEntries.map(e => e[0]).join(', '));

    - name: Run ${{ inputs.model-name }} model tests
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl models/spring-ai-${{ inputs.model-name }} \
          -Pintegration-tests \
          ${{ inputs.maven-properties }} \
          ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} \
          -Dfailsafe.rerunFailingTestsCount=2 \
          verify

---

### .Github/Actions/Do Multi Module Test/Action.Yml (.github/actions/do-multi-module-test/action.yml)

name: "Run Spring AI Multi-Module Integration Tests"
description: "Run integration tests for multiple Spring AI modules"

inputs:
  modules:
    description: "Comma-separated list of modules to test"
    required: true
  maven-properties:
    description: "Additional Maven properties to pass to the build"
    required: false
    default: ""
  spring-boot-version:
    description: "Spring Boot version to test against (leave empty to use the project default)"
    required: false
    default: ""

runs:
  using: "composite"
  steps:
    - name: Check environment
      uses: actions/github-script@v7
      with:
        script: |
          const env = ${{ toJson(env) }}
          const emptyEnvEntries = Object.entries(env).filter(e => e[1].length === 0)
          emptyEnvEntries.length > 0 &&
            core.setFailed('Missing value for environment variable(s): ' + emptyEnvEntries.map(e => e[0]).join(', '));

    - name: Run integration tests
      shell: bash
      run: |
        echo 'Running with maven properties:' ${{ inputs.maven-properties }}
        ./mvnw --batch-mode -ntp --no-snapshot-updates \
          -pl ${{ inputs.modules }} \
          -Pintegration-tests \
          ${{ inputs.maven-properties }} \
          ${{ inputs.spring-boot-version != '' && format('-Dspring-boot.version={0}', inputs.spring-boot-version) || '' }} \
          -Dfailsafe.rerunFailingTestsCount=2 \
          verify

---

### .Github/Actions/Release Train Build/Action.Yml (.github/actions/release-train-build/action.yml)

name: Build Release
runs:
  using: composite
  steps:
    - name: Build Release
      shell: bash
      run: ./mvnw --batch-mode -ntp -PreleaseTrain --settings release-train-settings.xml -DaltDeploymentRepository="release-train::file://$(pwd)/deployment-repository" -Dmaven.test.skip deploy

---

### .Github/Actions/Release Train Test/Action.Yml (.github/actions/release-train-test/action.yml)

name: Test Release
runs:
  using: composite
  steps:
    - name: Test Release
      shell: bash
      run: ./mvnw --batch-mode -ntp -PreleaseTrain --settings release-train-settings.xml test

---

### .Github/ISSUE TEMPLATE/Bug Report (.github/ISSUE_TEMPLATE/bug_report.md)

---
name: Bug report
about: Create a bug report to help us improve the project
title: ''
labels: 'type: bug, status: waiting-for-triage'
assignees: ''

---

Please do a quick search on GitHub issues first, there might be already a duplicate issue for the one you are about to create.
If the bug is trivial, just go ahead and create the issue. Otherwise, please take a few moments and fill in the following sections:

**Bug description**
A clear and concise description of what the bug is about.

**Environment**
Please provide as many details as possible: Spring AI version, Java version, which vector store you use if any, etc

**Steps to reproduce**
Steps to reproduce the issue.

**Expected behavior**
A clear and concise description of what you expected to happen.

**Minimal Complete Reproducible example**
Please provide a failing test or a minimal complete verifiable example that reproduces the issue.
Bug reports that are reproducible will take priority in resolution over reports that are not reproducible.

---

### .Github/ISSUE TEMPLATE/Config.Yml (.github/ISSUE_TEMPLATE/config.yml)

blank_issues_enabled: false
contact_links:
  - name: Questions and Community Support
    url: https://stackoverflow.com/questions/tagged/spring-ai
    about: Please ask and answer questions on StackOverflow with the spring-ai tag

---

### .Github/ISSUE TEMPLATE/Feature Request (.github/ISSUE_TEMPLATE/feature_request.md)

---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'status: waiting-for-triage, type: feature'
assignees: ''

---

Please do a quick search on GitHub issues first, the feature you are about to request might have already been requested.

**Expected Behavior**



**Current Behavior**



**Context**

---

### .Github/ISSUE TEMPLATE/Miscellaneous (.github/ISSUE_TEMPLATE/miscellaneous.md)

---
name: Miscellaneous
about: Suggest an improvement for this project
title: ''
labels: 'status: waiting-for-triage'
assignees: ''

---

For anything other than bug reports and feature requests (performance, refactoring, etc),
just go ahead and file the issue. Please provide as many details as possible.

If you have a question or a support request, please open a new discussion on [GitHub Discussions](https://github.com/spring-projects/spring-ai/discussions)
or ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/spring-ai).

Please do **not** create issues on the [Issue Tracker](https://github.com/spring-projects/spring-ai/issues) for questions or support requests.
We would like to keep the issue tracker **exclusively** for bug reports and feature requests.

---

### .Github/Workflows/Auto Cherry Pick.Yml (.github/workflows/auto-cherry-pick.yml)

name: Auto Cherry-Pick

on:
  push:
    branches:
      - main
      - '*.x'

jobs:
  cherry-pick-commit:
    uses: spring-io/spring-github-workflows/.github/workflows/spring-cherry-pick.yml@v5
    secrets:
      GH_ACTIONS_REPO_TOKEN: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}

---

### .Github/Workflows/Backport Issue.Yml (.github/workflows/backport-issue.yml)

name: Backport Bot

on:
  issues:
    types: [labeled]
  pull_request:
    types: [labeled]
  push:
    branches:
      - '[0-9]+.[0-9]+.x'
      - 'main'
jobs:
  backport-issue:
    permissions:
      contents: read
      issues: write
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      - name: Create Backport Issue
        uses: spring-io/backport-bot@v0.0.1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

---

### .Github/Workflows/Build And Deploy Snapshot.Yml (.github/workflows/build-and-deploy-snapshot.yml)

name: Build and Deploy Snapshot

on:
  push:
    branches:
      - 'main'
      - '[0-9].[0-9].x'
      - '[0-9].[0-9].x-internal'
  schedule:
    - cron: '30 11 * * 1-5'  # 12:30 PM CET / 6:30 AM
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow_ref }}
  cancel-in-progress: true

jobs:
  build-all:
    name: Build all modules
    if: ${{ github.repository_owner == 'spring-projects' }}
    runs-on: ${{ vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Setup Maven Build-Cache (~/.m2/build-cache)
        if: ${{ github.event_name != 'schedule' }}
        uses: actions/cache@v5
        with:
          path: ~/.m2/build-cache
          # See pr-check.yml for an explanation of the key format
          key: build-cache-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
          restore-keys: |
            build-cache-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}-
            build-cache-${{ runner.os }}-

      - name: Build all modules with unit tests
        env:
          COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
          COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
          COMMERCIAL_SNAPSHOT_REPO_URL: "${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }}"
          COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        run: |
          ./mvnw ${{ vars.COMMERCIAL && '-s commercial-settings.xml -Pcommercial' || '' }} --batch-mode -ntp --update-snapshots clean install

      - name: Upload Spring-AI Built Artifacts
        uses: actions/upload-artifact@v6
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai
          retention-days: 1 # Intent is to share only with downstream jobs in this workflow

      - name: Purge Spring AI Built Artifacts # We don't want the setup-java m2 cache to capture our products, only our deps
        run: rm -fr ~/.m2/repository/org/springframework/ai


  test-ollama:
    name: Test Ollama
    if: ${{ github.repository_owner == 'spring-projects' }}
    runs-on: ${{ vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    needs: build-all
    services:
      ollama:
        image: ollama/ollama:latest
        ports:
          - 11434:11434
    env:
      OLLAMA_WITH_REUSE: true
      OLLAMA_AUTOCONF_TESTS_ENABLED: "true"
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Setup Maven Build-Cache (~/.m2/build-cache)
        uses: actions/cache@v5
        if: ${{ github.event_name != 'schedule' }}
        with:
          path: ~/.m2/build-cache
          key: build-cache-${{ runner.os }}-ollama-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
          restore-keys: |
            build-cache-${{ runner.os }}-ollama-${{ hashFiles('**/pom.xml') }}-
            build-cache-${{ runner.os }}-

      - name: Download Spring-AI Built Artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: echo "testcontainers.reuse.enable=true" > $HOME/.testcontainers.properties

      - name: Test Ollama modules
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
          COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
          COMMERCIAL_SNAPSHOT_REPO_URL: "${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }}"
          COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        run: |
          ./mvnw ${{ vars.COMMERCIAL && '-s commercial-settings.xml -Pcommercial' || '' }} --batch-mode -ntp --no-snapshot-updates \
            -pl models/spring-ai-ollama,auto-configurations/models/spring-ai-autoconfigure-model-ollama \
            -Pci-fast-integration-tests \
            -Dfailsafe.rerunFailingTestsCount=3 \
            verify


  test-openai:
    name: Test OpenAI
    if: ${{ github.repository_owner == 'spring-projects' }}
    runs-on: ${{ vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    needs: build-all
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Setup Maven Build-Cache (~/.m2/build-cache)
        uses: actions/cache@v5
        with:
          path: ~/.m2/build-cache
          key: build-cache-${{ runner.os }}-openai-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
          restore-keys: |
            build-cache-${{ runner.os }}-openai-${{ hashFiles('**/pom.xml') }}-
            build-cache-${{ runner.os }}-

      - name: Download Spring-AI Built Artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: echo "testcontainers.reuse.enable=true" > $HOME/.testcontainers.properties

      - name: Test OpenAI modules
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
          COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
          COMMERCIAL_SNAPSHOT_REPO_URL: "${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }}"
          COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        run: |
          ./mvnw ${{ vars.COMMERCIAL && '-s commercial-settings.xml -Pcommercial' || '' }} --batch-mode -ntp --no-snapshot-updates \
            -pl models/spring-ai-openai,auto-configurations/models/spring-ai-autoconfigure-model-openai \
            -Pci-fast-integration-tests \
            -Dfailsafe.rerunFailingTestsCount=3 \
            verify


  test-remaining:
    name: Test Remaining (MCP, Google GenAI, Vertex AI Embedding, Chroma, PgVector)
    if: ${{ github.repository_owner == 'spring-projects' }}
    runs-on: ${{ vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    needs: build-all
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Setup Maven Build-Cache (~/.m2/build-cache)
        uses: actions/cache@v5
        with:
          path: ~/.m2/build-cache
          key: build-cache-${{ runner.os }}-other-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
          restore-keys: |
            build-cache-${{ runner.os }}-other-${{ hashFiles('**/pom.xml') }}-
            build-cache-${{ runner.os }}-

      - name: Download Spring-AI Built Artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: echo "testcontainers.reuse.enable=true" > $HOME/.testcontainers.properties

      - name: Test remaining modules
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
          COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
          COMMERCIAL_SNAPSHOT_REPO_URL: "${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }}"
          COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        run: |
          ./mvnw ${{ vars.COMMERCIAL && '-s commercial-settings.xml -Pcommercial' || '' }} --batch-mode -ntp --no-snapshot-updates \
            -pl models/spring-ai-google-genai, \
            -pl auto-configurations/models/spring-ai-autoconfigure-model-google-genai, \
            ${{ vars.COMMERCIAL && '-pl models/spring-ai-vertex-ai-embedding,' || '-pl mcp/mcp-annotations,' }} \
            -pl mcp/common, \
            -pl mcp/transport/mcp-spring-webflux, \
            -pl mcp/transport/mcp-spring-webmvc, \
            -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-common, \
            -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-httpclient, \
            -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-client-webflux, \
            -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-common, \
            -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webmvc, \
            -pl auto-configurations/mcp/spring-ai-autoconfigure-mcp-server-webflux, \
            -pl vector-stores/spring-ai-chroma-store, \
            -pl vector-stores/spring-ai-pgvector-store, \
            -pl spring-ai-integration-tests \
            -Pci-fast-integration-tests \
            -Dfailsafe.rerunFailingTestsCount=3 \
            verify


  deploy-artifactory:
    name: Deploy to Artifactory
    if: ${{ github.repository_owner == 'spring-projects' && github.event_name != 'schedule' }}
    runs-on: ${{ vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    needs: [build-all, test-ollama, test-openai, test-remaining]
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Setup Maven Build-Cache (~/.m2/build-cache)
        uses: actions/cache@v5
        with:
          path: ~/.m2/build-cache
          key: build-cache-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
          restore-keys: |
            build-cache-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}-
            build-cache-${{ runner.os }}-

      - name: Deploy to Artifactory
        env:
          ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
          ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
          COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
          COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
          COMMERCIAL_SNAPSHOT_REPO_URL: "${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }}"
          COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        run: |
          ./mvnw ${{ vars.COMMERCIAL && '-s commercial-settings.xml -Pcommercial' || '-s settings.xml' }} --batch-mode -ntp -Dmaven.test.skip \
            ${{ vars.COMMERCIAL && format('-DaltSnapshotDeploymentRepository=spring-enterprise-snapshot::{0}', vars.COMMERCIAL_SNAPSHOT_REPO_URL) || '' }} \
            deploy

---

### .Github/Workflows/Dependency Ci Dashboard.Yml (.github/workflows/dependency-ci-dashboard.yml)

name: Ecosystem CI Dashboard

on:
  schedule:
    - cron: '15 6 * * *'  # 06:15 UTC daily
  workflow_dispatch:

permissions:
  issues: write
  contents: write

jobs:
  update-dashboard:
    name: Update Ecosystem CI Dashboard
    runs-on: ubuntu-latest
    if: ${{ github.repository == 'spring-projects/spring-ai' }}
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Load configuration
        id: config
        run: |
          CONFIG=$(cat src/ecosystem-ci/ci-alert-config.json)
          echo "issue_number=$(echo "$CONFIG" | jq -r '.issue_number')" >> $GITHUB_OUTPUT
          echo "tracked_branch=$(echo "$CONFIG" | jq -r '.tracked_branch')" >> $GITHUB_OUTPUT
          echo "alert_after_days=$(echo "$CONFIG" | jq -r '.alert_after_days')" >> $GITHUB_OUTPUT
          echo "heartbeat_days=$(echo "$CONFIG" | jq -r '.heartbeat_days')" >> $GITHUB_OUTPUT
          echo "dependencies<<EOF" >> $GITHUB_OUTPUT
          echo "$CONFIG" | jq -c '.dependencies' >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Query CI status for all dependencies
        id: query-status
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          DEPENDENCIES: ${{ steps.config.outputs.dependencies }}
          TRACKED_BRANCH: ${{ steps.config.outputs.tracked_branch }}
        run: |
          RESULTS="[]"

          for row in $(echo "$DEPENDENCIES" | jq -r '.[] | @base64'); do
            _jq() {
              echo ${row} | base64 --decode | jq -r ${1}
            }

            OWNER=$(_jq '.owner')
            REPO=$(_jq '.repo')

            echo "Querying status for $OWNER/$REPO..."

            # Query workflow runs for the branch (most reliable for GitHub Actions)
            RUNS_RESPONSE=$(curl -s -H "Authorization: token $GH_TOKEN" \
              -H "Accept: application/vnd.github+json" \
              "https://api.github.com/repos/$OWNER/$REPO/actions/runs?branch=$TRACKED_BRANCH&per_page=10")

            # Find the most recent completed workflow run
            LATEST_RUN=$(echo "$RUNS_RESPONSE" | jq '[.workflow_runs[] | select(.status == "completed")] | .[0]')

            if [ "$LATEST_RUN" != "null" ] && [ -n "$LATEST_RUN" ]; then
              CONCLUSION=$(echo "$LATEST_RUN" | jq -r '.conclusion // "unknown"')
              COMMIT_SHA=$(echo "$LATEST_RUN" | jq -r '.head_sha // "unknown"' | head -c 7)
              COMMIT_DATE=$(echo "$LATEST_RUN" | jq -r '.created_at // ""')

              # Map conclusion to state
              case "$CONCLUSION" in
                "success") STATE="success" ;;
                "failure"|"timed_out"|"cancelled") STATE="failure" ;;
                *) STATE="unknown" ;;
              esac
            else
              # Check if there are any in-progress runs
              IN_PROGRESS=$(echo "$RUNS_RESPONSE" | jq '[.workflow_runs[] | select(.status == "in_progress" or .status == "queued")] | length')
              if [ "$IN_PROGRESS" -gt 0 ]; then
                STATE="pending"
                # Get commit from in-progress run
                COMMIT_SHA=$(echo "$RUNS_RESPONSE" | jq -r '.workflow_runs[0].head_sha // "unknown"' | head -c 7)
                COMMIT_DATE=$(echo "$RUNS_RESPONSE" | jq -r '.workflow_runs[0].created_at // ""')
              else
                STATE="unknown"
                # Fall back to HEAD commit info
                COMMIT_RESPONSE=$(curl -s -H "Authorization: token $GH_TOKEN" \
                  -H "Accept: application/vnd.github+json" \
                  "https://api.github.com/repos/$OWNER/$REPO/commits/$TRACKED_BRANCH")
                COMMIT_SHA=$(echo "$COMMIT_RESPONSE" | jq -r '.sha // "unknown"' | head -c 7)
                COMMIT_DATE=$(echo "$COMMIT_RESPONSE" | jq -r '.commit.committer.date // ""')
              fi
            fi

            RESULT=$(jq -n \
              --arg owner "$OWNER" \
              --arg repo "$REPO" \
              --arg state "$STATE" \
              --arg sha "$COMMIT_SHA" \
              --arg date "$COMMIT_DATE" \
              '{owner: $owner, repo: $repo, state: $state, sha: $sha, commit_date: $date}')

            RESULTS=$(echo "$RESULTS" | jq --argjson result "$RESULT" '. + [$result]')
          done

          echo "results<<EOF" >> $GITHUB_OUTPUT
          echo "$RESULTS" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Update dashboard and check alerts
        uses: actions/github-script@v7
        env:
          RESULTS: ${{ steps.query-status.outputs.results }}
          ISSUE_NUMBER: ${{ steps.config.outputs.issue_number }}
          ALERT_AFTER_DAYS: ${{ steps.config.outputs.alert_after_days }}
          HEARTBEAT_DAYS: ${{ steps.config.outputs.heartbeat_days }}
          TRACKED_BRANCH: ${{ steps.config.outputs.tracked_branch }}
        with:
          script: |
            const results = JSON.parse(process.env.RESULTS);
            const issueNumber = parseInt(process.env.ISSUE_NUMBER);
            const alertAfterDays = parseInt(process.env.ALERT_AFTER_DAYS);
            const heartbeatDays = parseInt(process.env.HEARTBEAT_DAYS);
            const trackedBranch = process.env.TRACKED_BRANCH;
            const now = new Date();
            const timestamp = now.toISOString();

            // Status emoji mapping
            const statusEmoji = {
              'success': ':white_check_mark:',
              'failure': ':x:',
              'pending': ':yellow_circle:',
              'unknown': ':grey_question:'
            };

            // Find dashboard comment (contains hidden state marker)
            const STATE_MARKER = '';

            const comments = await github.paginate(github.rest.issues.listComments, {
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issueNumber
            });

            let dashboardComment = comments.find(c => c.body.includes(DASHBOARD_MARKER));

            // Parse previous state from comment
            let previousState = {};
            if (dashboardComment) {
              const stateMatch = dashboardComment.body.match(//s);
              if (stateMatch) {
                try {
                  previousState = JSON.parse(stateMatch[1]);
                } catch (e) {
                  console.log('Failed to parse previous state:', e);
                }
              }
            }

            // Update state with current results
            const newState = {};
            const alertsNeeded = [];

            for (const result of results) {
              const key = `${result.owner}/${result.repo}`;
              const prevEntry = previousState[key] || {};

              if (result.state === 'failure') {
                // Track when it first failed
                const failedSince = prevEntry.failedSince || timestamp;
                const failedDays = Math.floor((now - new Date(failedSince)) / (1000 * 60 * 60 * 24));
                const lastAlerted = prevEntry.lastAlerted;

                newState[key] = {
                  state: result.state,
                  failedSince: failedSince,
                  failedDays: failedDays,
                  lastAlerted: lastAlerted
                };

                // Check if we need to alert
                if (failedDays >= alertAfterDays) {
                  // Only alert if we haven't alerted in the last heartbeat period
                  const shouldAlert = !lastAlerted ||
                    (now - new Date(lastAlerted)) >= (heartbeatDays * 24 * 60 * 60 * 1000);

                  if (shouldAlert) {
                    alertsNeeded.push({
                      owner: result.owner,
                      repo: result.repo,
                      failedDays: failedDays,
                      sha: result.sha
                    });
                    newState[key].lastAlerted = timestamp;
                  }
                }
              } else {
                // Not failing - clear failure tracking
                newState[key] = {
                  state: result.state
                };
              }
            }

            // Build dashboard table
            let dashboardTable = `| Repository | Status | Branch | Latest Commit | Last Run |\n`;
            dashboardTable += `|------------|--------|--------|---------------|----------|\n`;

            for (const result of results) {
              const key = `${result.owner}/${result.repo}`;
              const emoji = statusEmoji[result.state] || statusEmoji['unknown'];
              const stateEntry = newState[key];

              let statusText = emoji;
              if (result.state === 'failure' && stateEntry.failedDays > 0) {
                statusText += ` (${stateEntry.failedDays}d)`;
              }

              const repoLink = `[${result.owner}/${result.repo}](https://github.com/${result.owner}/${result.repo})`;
              const commitLink = result.sha !== 'unknown'
                ? `[\`${result.sha}\`](https://github.com/${result.owner}/${result.repo}/commit/${result.sha})`
                : 'N/A';
              const actionsLink = `[${trackedBranch}](https://github.com/${result.owner}/${result.repo}/actions?query=branch%3A${trackedBranch})`;

              // Format date as YYYY-MM-DD
              const lastRun = result.commit_date
                ? new Date(result.commit_date).toISOString().split('T')[0]
                : 'N/A';

              dashboardTable += `| ${repoLink} | ${statusText} | ${actionsLink} | ${commitLink} | ${lastRun} |\n`;
            }

            // Build dashboard comment body
            const stateJson = JSON.stringify(newState);
            const dashboardBody = `${DASHBOARD_MARKER}

            ## Ecosystem CI Dashboard

            **Last updated:** ${timestamp}

            ${dashboardTable}

            ### Legend
            - :white_check_mark: All checks passing
            - :x: CI failing (days in parentheses)
            - :yellow_circle: Checks in progress
            - :grey_question: Status unknown

            ### Alert Policy
            - Alerts are posted when a dependency has been failing for **${alertAfterDays}+ days**
            - Subscribe to this issue to receive CI failure notifications

            ${STATE_MARKER}${stateJson}-->
            `.split('\n').map(line => line.trim()).join('\n');

            // Update or create dashboard comment
            if (dashboardComment) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: dashboardComment.id,
                body: dashboardBody
              });
              console.log('Updated dashboard comment');
            } else {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: issueNumber,
                body: dashboardBody
              });
              console.log('Created dashboard comment');
            }

            // Post alert comments if needed
            for (const alert of alertsNeeded) {
              const alertBody = `:rotating_light: **CI Alert**: [${alert.owner}/${alert.repo}](https://github.com/${alert.owner}/${alert.repo}) has been failing for **${alert.failedDays} days**

            - **Branch:** ${trackedBranch}
            - **Latest commit:** [\`${alert.sha}\`](https://github.com/${alert.owner}/${alert.repo}/commit/${alert.sha})
            - **CI Status:** [View Actions](https://github.com/${alert.owner}/${alert.repo}/actions?query=branch%3A${trackedBranch})

            Please investigate and fix the CI failure.`;

              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: issueNumber,
                body: alertBody
              });
              console.log(`Posted alert for ${alert.owner}/${alert.repo}`);
            }

            // Set outputs for wiki update
            core.setOutput('dashboard_table', dashboardTable);
            core.setOutput('timestamp', timestamp);
            core.setOutput('alert_after_days', alertAfterDays);

      - name: Update Wiki Dashboard
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          RESULTS: ${{ steps.query-status.outputs.results }}
          TRACKED_BRANCH: ${{ steps.config.outputs.tracked_branch }}
          ALERT_AFTER_DAYS: ${{ steps.config.outputs.alert_after_days }}
        run: |
          # Configure git
          git config --global user.name "github-actions[bot]"
          git config --global user.email "github-actions[bot]@users.noreply.github.com"

          # Clone wiki repo
          WIKI_DIR=$(mktemp -d)
          git clone "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.wiki.git" "$WIKI_DIR"

          # Generate wiki page content
          TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

          # Status emoji mapping for wiki (GitHub wiki renders these)
          cat > "$WIKI_DIR/Ecosystem-CI-Dashboard.md" << 'WIKI_HEADER'
          # Ecosystem CI Dashboard

          This dashboard monitors the CI health of Spring AI ecosystem dependencies.

          WIKI_HEADER

          echo "**Last updated:** $TIMESTAMP" >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md"
          echo "" >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md"

          # Build table
          echo "| Repository | Status | Branch | Latest Commit | Last Run |" >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md"
          echo "|------------|--------|--------|---------------|----------|" >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md"

          echo "$RESULTS" | jq -r '.[] | @base64' | while read row; do
            OWNER=$(echo "$row" | base64 --decode | jq -r '.owner')
            REPO=$(echo "$row" | base64 --decode | jq -r '.repo')
            STATE=$(echo "$row" | base64 --decode | jq -r '.state')
            SHA=$(echo "$row" | base64 --decode | jq -r '.sha')
            COMMIT_DATE=$(echo "$row" | base64 --decode | jq -r '.commit_date')

            case "$STATE" in
              "success") EMOJI=":white_check_mark:" ;;
              "failure") EMOJI=":x:" ;;
              "pending") EMOJI=":yellow_circle:" ;;
              *) EMOJI=":grey_question:" ;;
            esac

            REPO_LINK="[$OWNER/$REPO](https://github.com/$OWNER/$REPO)"
            COMMIT_LINK="[\`$SHA\`](https://github.com/$OWNER/$REPO/commit/$SHA)"
            ACTIONS_LINK="[$TRACKED_BRANCH](https://github.com/$OWNER/$REPO/actions?query=branch%3A$TRACKED_BRANCH)"

            # Format date as YYYY-MM-DD
            if [ -n "$COMMIT_DATE" ] && [ "$COMMIT_DATE" != "null" ]; then
              LAST_RUN=$(echo "$COMMIT_DATE" | cut -d'T' -f1)
            else
              LAST_RUN="N/A"
            fi

            echo "| $REPO_LINK | $EMOJI | $ACTIONS_LINK | $COMMIT_LINK | $LAST_RUN |" >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md"
          done

          cat >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md" << WIKI_FOOTER

          ## Legend

          - :white_check_mark: All checks passing
          - :x: CI failing
          - :yellow_circle: Checks in progress
          - :grey_question: Status unknown

          ## Alert Policy

          Alerts are posted to [Issue #${{ steps.config.outputs.issue_number }}](https://github.com/${{ github.repository }}/issues/${{ steps.config.outputs.issue_number }}) when a dependency has been failing for **${ALERT_AFTER_DAYS}+ days**.

          Subscribe to that issue to receive CI failure notifications.

          ## Monitored Repositories

          The following repositories are monitored as part of the Spring AI ecosystem:

          WIKI_FOOTER

          echo "$RESULTS" | jq -r '.[] | "- [`\(.owner)/\(.repo)`](https://github.com/\(.owner)/\(.repo))"' >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md"

          cat >> "$WIKI_DIR/Ecosystem-CI-Dashboard.md" << 'WIKI_END'

          ---

          *This page is automatically updated by the [Ecosystem CI Dashboard workflow](https://github.com/spring-projects/spring-ai/actions/workflows/dependency-ci-dashboard.yml).*
          WIKI_END

          # Commit and push wiki changes
          cd "$WIKI_DIR"
          git add Ecosystem-CI-Dashboard.md

          if git diff --staged --quiet; then
            echo "No changes to wiki"
          else
            git commit -m "Update Ecosystem CI Dashboard - $TIMESTAMP"
            git push
            echo "Wiki updated successfully"
          fi

---

### .Github/Workflows/Deploy Docs.Yml (.github/workflows/deploy-docs.yml)

name: Deploy Docs
run-name: ${{ github.event_name == 'workflow_dispatch' && 'Deploy Docs (Build)' || 'Deploy Docs (Dispatcher)' }}
on:
  workflow_dispatch:
permissions:
  actions: write
jobs:
  build:
    runs-on: ${{ vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    if: ${{ github.repository_owner == 'spring-projects' }}
    steps:
      - name: Dispatch (full build)
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh workflow run deploy-docs.yml -r docs-build --repo ${{ github.repository }}

---

### .Github/Workflows/Deploy Javadoc.Yml (.github/workflows/deploy-javadoc.yml)

name: Deploy Javadoc
on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
permissions:
  contents: read
jobs:
  deploy-javadoc:
    name: Deploy Javadoc
    if: ${{ github.repository_owner == 'spring-projects' }}
    runs-on: ${{ vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    steps:
      - name: Check Out
        uses: actions/checkout@v4

      - name: Set Up Java
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'liberica'

      - name: Generate Javadoc (commercial)
        if: ${{ vars.COMMERCIAL }}
        shell: bash
        env:
          COMMERCIAL_RELEASE_REPO_URL: ${{ vars.COMMERCIAL_RELEASE_REPO_URL }}
          COMMERCIAL_ARTIFACTORY_PASSWORD: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}
          COMMERCIAL_ARTIFACTORY_USERNAME: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}
          COMMERCIAL_SNAPSHOT_REPO_URL: ${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }}
          USW1_USERNAME: ${{ secrets.COMMERCIAL_ARTIFACTORY_RO_USERNAME }}
          USW1_PASSWORD: ${{ secrets.COMMERCIAL_ARTIFACTORY_RO_PASSWORD }}
        run: ./mvnw -s commercial-settings.xml --batch-mode -ntp javadoc:aggregate-jar

      - name: Generate Javadoc (OSS)
        if: ${{ !vars.COMMERCIAL }}
        run: ./mvnw --batch-mode -ntp javadoc:aggregate-jar

      - name: Capture project version
        run: echo PROJECT_VERSION=$(./mvnw ${{ vars.COMMERCIAL && '-s commercial-settings.xml' || '' }} help:evaluate -Dexpression=project.version --quiet -DforceStdout) >> $GITHUB_ENV

      - name: Extract Javadoc
        if: ${{ vars.COMMERCIAL }}
        run: |
          mkdir -p target/javadoc-site/${PROJECT_VERSION}/api
          unzip target/spring-ai-parent-${PROJECT_VERSION}-javadoc.jar -d target/javadoc-site/${PROJECT_VERSION}/api

      - name: Authenticate to GCP
        if: ${{ vars.COMMERCIAL }}
        uses: google-github-actions/auth@v2.1.0
        with:
          credentials_json: ${{ secrets.COMMERCIAL_DOCS_GCP_BUCKET_JSON }}

      - name: Upload Javadoc to GCP (commercial)
        if: ${{ vars.COMMERCIAL }}
        uses: google-github-actions/upload-cloud-storage@v2.1.0
        with:
          path: target/javadoc-site
          destination: ${{ secrets.COMMERCIAL_DOCS_HOST }}/spring-ai/docs/
          parent: false

      - name: Setup SSH key (OSS)
        if: ${{ !vars.COMMERCIAL }}
        run: |
          mkdir "$HOME/.ssh"
          echo "${{ secrets.DOCS_SSH_KEY }}" > "$HOME/.ssh/key"
          chmod 600 "$HOME/.ssh/key"
          echo "${{ secrets.DOCS_SSH_HOST_KEY }}" > "$HOME/.ssh/known_hosts"

      - name: Deploy Javadoc via SSH (OSS)
        if: ${{ !vars.COMMERCIAL }}
        run: |
          ssh -i $HOME/.ssh/key ${{ secrets.DOCS_USERNAME }}@${{ secrets.DOCS_HOST }} "cd ${{ secrets.DOCS_PATH }} && rm -fr $PROJECT_VERSION && mkdir -p $PROJECT_VERSION"
          scp -i $HOME/.ssh/key target/spring-ai-parent-${PROJECT_VERSION}-javadoc.jar ${{ secrets.DOCS_USERNAME }}@${{ secrets.DOCS_HOST }}:${{ secrets.DOCS_PATH }}/$PROJECT_VERSION
          ssh -i $HOME/.ssh/key ${{ secrets.DOCS_USERNAME }}@${{ secrets.DOCS_HOST }} "cd ${{ secrets.DOCS_PATH }}/${PROJECT_VERSION} && unzip spring-ai-parent-${PROJECT_VERSION}-javadoc.jar -d api && rm spring-ai-parent-${PROJECT_VERSION}-javadoc.jar"

---

### .Github/Workflows/Github Release.Yml (.github/workflows/github-release.yml)

name: GitHub Release
run-name: "GitHub Release (${{ inputs.version }})"
on:
  workflow_dispatch:
    inputs:
      version:
        description: "Enter the release version (e.g., 1.2.3)."
        required: true
      latest:
        description: "Whether to mark the release as the latest one."
        type: boolean
        required: false
        default: false
      draft:
        description: "Whether to create the release as a draft."
        type: boolean
        required: false
        default: false
permissions:
  contents: read
concurrency:
  group: ${{ github.workflow }}-${{ inputs.version }}
jobs:
  create-github-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    steps:
      - name: Check Out Code
        uses: actions/checkout@v6
      - name: Create GitHub Release
        uses: ./.github/actions/create-github-release
        with:
          commercial: ${{ vars.COMMERCIAL }}
          draft: ${{ inputs.draft }}
          latest: ${{ inputs.latest }}
          milestone: ${{ inputs.version }}
          pre-release: ${{ contains(inputs.version, '-') }}
          token: ${{ secrets.GH_ACTIONS_REPO_TOKEN }}

---

### .Github/Workflows/Mcp Integration Tests.Yml (.github/workflows/mcp-integration-tests.yml)

name: MCP Integration Tests

on:
  pull_request:
  push:
    branches:
      - 'main'
      - '[0-9].[0-9].x'
  workflow_dispatch:
    inputs:
      runner:
        description: 'Runner label to use (e.g. UBUNTU_SMALL, ubuntu-latest). Leave empty to use the default.'
        required: false
        default: ''
        type: string

jobs:
  mcp-it:
    name: MCP integration tests
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Setup Maven Build-Cache (~/.m2/build-cache)
        if: ${{ false }} # Disable until test flakiness has been resolved
        uses: actions/cache@v4
        with:
          path: ~/.m2/build-cache
          # See pr-check.yml for an explanation of the key format
          key: build-cache-${{ runner.os }}-mcp-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
          restore-keys: |
            build-cache-${{ runner.os }}-mcp-${{ hashFiles('**/pom.xml') }}-
            build-cache-${{ runner.os }}-

      - name: Build with Maven and run integration tests
        run: |
          ./mvnw --batch-mode -ntp verify -Pintegration-tests -am -pl "mcp/transport/mcp-spring-webflux,mcp/transport/mcp-spring-webmvc"

---

### .Github/Workflows/Pr Check.Yml (.github/workflows/pr-check.yml)

name: PR Check

on:
  pull_request:

jobs:
  build:
    name: Build branch
    runs-on: ubuntu-latest
    if: ${{ github.repository_owner == 'spring-projects' }}
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Setup Maven Build-Cache (~/.m2/build-cache)
        uses: actions/cache@v5
        with:
          path: ~/.m2/build-cache
          # See https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
          # We need to incrementally save the contents of the build-cache directory, even if there was a hit prior to the build
          # Cached restored from restore-keys are restored using the latest one first, so this is a good compromise
          key: build-cache-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}-${{ github.run_id }}
          restore-keys: |
            build-cache-${{ runner.os }}-${{ hashFiles('**/pom.xml') }}-
            build-cache-${{ runner.os }}-

      - name: Run tests
        run: |
          ./mvnw -ntp -B -U package

---

### .Github/Workflows/Release Train Build.Yml (.github/workflows/release-train-build.yml)

# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit.
# To update it, modify .github/workflow-generator.yml as needed and re-run the generator.

name: "Release Train – Build"
run-name: "${{ inputs.callback-ref }} – Build"
"on":
  workflow_dispatch:
    inputs:
      callback:
        description: "Repository to which a callback should be made upon completion"
        required: true
        type: "string"
      callback-ref:
        description: "Ref in the callback repository to which a callback should be made upon completion"
        required: true
        type: "string"
      release-train-maven-repository-url:
        description: "URL of a Maven repository to be used to resolve artifacts of projects earlier in the train"
        required: true
        type: "string"
permissions:
  contents: "read"
concurrency:
  group: "${{ github.workflow }}-${{ github.ref }}"
jobs:
  build-release:
    name: "Build Release"
    runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    steps:
    - name: "Prevent Re-runs"
      id: "prevent-re-runs"
      run: |-
        if [ "$GITHUB_RUN_ATTEMPT" -gt 1 ]; then
          echo "Re-runs are prohibited. Use the 'Release Train – Retry' workflow to retry build failures"
          exit 1
        fi
    - name: "Set up Java"
      id: "set-up-java"
      uses: "actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95" # v5.6.0
      with:
        distribution: "liberica"
        java-version: "17"
    - name: "Check Out Code"
      id: "check-out-code"
      uses: "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" # v7.0.0
    - name: "Build Release"
      id: "build-release"
      uses: "./.github/actions/release-train-build"
      env:
        COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
        COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
        COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        RELEASE_TRAIN_MAVEN_REPOSITORY_PASSWORD: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_PASSWORD }}"
        RELEASE_TRAIN_MAVEN_REPOSITORY_URL: "${{ inputs.release-train-maven-repository-url }}"
        RELEASE_TRAIN_MAVEN_REPOSITORY_USERNAME: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_USERNAME }}"
    - name: "Upload Deployment Repository"
      id: "upload-deployment-repository"
      uses: "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" # v7.0.1
      with:
        name: "deployment-repository"
        path: "deployment-repository/**"
    - name: "Upload Deployment Spec"
      id: "upload-deployment-spec"
      uses: "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" # v7.0.1
      with:
        archive: "false"
        if-no-files-found: "ignore"
        name: "deployment-spec"
        path: ".github/actions/release-train-build/deployment-spec.yml"
    - name: "Save Build System Caches"
      id: "save-build-system-caches"
      uses: "actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9" # v6.1.0
      with:
        key: "release-train-${{ inputs.callback-ref }}-${{ github.ref_name }}"
        path: "~/.m2/repository"
    - name: "Send Callback"
      id: "send-callback"
      if: "${{ !cancelled() }}"
      env:
        GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}"
      run: |-
        gh workflow run callback \
        --repo ${{ inputs.callback }} \
        --ref ${{ inputs.callback-ref }} \
        --field commit-hash=${{ steps.check-out-code.outputs.commit }} \
        --field deployment-repository-artifact-identifier=${{ steps.upload-deployment-repository.outputs.artifact-id }} \
        --field deployment-spec-artifact-identifier=${{ steps.upload-deployment-spec.outputs.artifact-id }} \
        --field release-branch=${{ github.ref_name }} \
        --field release-repository=${{ github.repository }} \
        --field result=${{ job.status == 'success' && 'built' || 'build-failed' }} \
        --field workflow-run-url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

---

### .Github/Workflows/Release Train Join.Yml (.github/workflows/release-train-join.yml)

# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit.
# To update it, modify .github/workflow-generator.yml as needed and re-run the generator.

name: "Release Train – Join"
run-name: "${{ inputs.release-train }} – Join"
"on":
  workflow_dispatch:
    inputs:
      deployment-destination:
        description: "Destination to which the release should be deployed"
        options:
        - "Maven Central"
        - "Spring Enterprise"
        required: true
        type: "choice"
      release-train:
        description: "Release train"
        required: true
        type: "string"
      release-train-repository:
        default: "spring-io/release-train"
        description: "Release train repository"
        required: true
        type: "string"
permissions:
  contents: "none"
jobs:
  join-release-train:
    name: "Join Release Train"
    runs-on: "ubuntu-latest"
    steps:
    - name: "Join Release Train"
      id: "join-release-train"
      env:
        GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}"
      run: |-
        run_url=$(
          gh workflow run join \
          --repo ${{ inputs.release-train-repository }} \
          --ref ${{ inputs.release-train }} \
          --field commit-hash=${{ github.sha }} \
          --field deployment-destination=${{ inputs.deployment-destination == 'Maven Central' && 'maven-central' || 'spring-enterprise' }} \
          --field release-branch=${{ github.ref_name }} \
          --field release-repository=${{ github.repository }}
        )
        echo "Dispatched workflow run. Waiting for $run_url to complete."
        run_id=${run_url##*/}
        watch_exit_code=0
        gh run watch $run_id --repo ${{ inputs.release-train-repository }} --exit-status --interval=3 > /dev/null 2>&1 || watch_exit_code=$?
        if [[ $watch_exit_code -eq 0 ]]; then
          echo "Workflow run succeeded."
        else
          echo "Workflow run failed."
        fi
        exit $watch_exit_code

---

### .Github/Workflows/Release Train Leave.Yml (.github/workflows/release-train-leave.yml)

# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit.
# To update it, modify .github/workflow-generator.yml as needed and re-run the generator.

name: "Release Train – Leave"
run-name: "${{ inputs.release-train }} – Leave"
"on":
  workflow_dispatch:
    inputs:
      release-train:
        description: "Release train"
        required: true
        type: "string"
      release-train-repository:
        default: "spring-io/release-train"
        description: "Release train repository"
        required: true
        type: "string"
permissions:
  contents: "none"
jobs:
  leave:
    name: "Leave"
    runs-on: "ubuntu-latest"
    steps:
    - name: "Leave"
      id: "leave"
      env:
        GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}"
      run: |-
        run_url=$(
          gh workflow run leave \
          --repo ${{ inputs.release-train-repository }} \
          --ref ${{ inputs.release-train }} \
          --field release-branch=${{ github.ref_name }} \
          --field release-repository=${{ github.repository }}
        )
        echo "Dispatched workflow run. Waiting for $run_url to complete."
        run_id=${run_url##*/}
        watch_exit_code=0
        gh run watch $run_id --repo ${{ inputs.release-train-repository }} --exit-status --interval=3 > /dev/null 2>&1 || watch_exit_code=$?
        if [[ $watch_exit_code -eq 0 ]]; then
          echo "Workflow run succeeded."
        else
          echo "Workflow run failed."
        fi
        exit $watch_exit_code

---

### .Github/Workflows/Release Train Ready.Yml (.github/workflows/release-train-ready.yml)

# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit.
# To update it, modify .github/workflow-generator.yml as needed and re-run the generator.

name: "Release Train – Ready"
run-name: "${{ inputs.release-train }} – Ready"
"on":
  workflow_dispatch:
    inputs:
      release-train:
        description: "Release train"
        required: true
        type: "string"
      release-train-repository:
        default: "spring-io/release-train"
        description: "Release train repository"
        required: true
        type: "string"
permissions:
  contents: "none"
jobs:
  ready:
    name: "Ready"
    runs-on: "ubuntu-latest"
    steps:
    - name: "Ready"
      id: "ready"
      env:
        GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}"
      run: |-
        run_url=$(
          gh workflow run ready \
          --repo ${{ inputs.release-train-repository }} \
          --ref ${{ inputs.release-train }} \
          --field commit-hash=${{ github.sha }} \
          --field release-branch=${{ github.ref_name }} \
          --field release-repository=${{ github.repository }}
        )
        echo "Dispatched workflow run. Waiting for $run_url to complete."
        run_id=${run_url##*/}
        watch_exit_code=0
        gh run watch $run_id --repo ${{ inputs.release-train-repository }} --exit-status --interval=3 > /dev/null 2>&1 || watch_exit_code=$?
        if [[ $watch_exit_code -eq 0 ]]; then
          echo "Workflow run succeeded."
        else
          echo "Workflow run failed."
        fi
        exit $watch_exit_code

---

### .Github/Workflows/Release Train Retry.Yml (.github/workflows/release-train-retry.yml)

# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit.
# To update it, modify .github/workflow-generator.yml as needed and re-run the generator.

name: "Release Train – Retry"
run-name: "${{ inputs.release-train }} – Retry"
"on":
  workflow_dispatch:
    inputs:
      release-train:
        description: "Release train"
        required: true
        type: "string"
      release-train-repository:
        default: "spring-io/release-train"
        description: "Release train repository"
        required: true
        type: "string"
permissions:
  contents: "none"
jobs:
  trigger-retry:
    name: "Trigger Retry"
    runs-on: "ubuntu-latest"
    steps:
    - name: "Trigger Retry"
      id: "trigger-retry"
      env:
        GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}"
      run: |-
        gh workflow run retry \
        --repo ${{ inputs.release-train-repository }} \
        --ref ${{ inputs.release-train }} \
        --field release-branch=${{ github.ref_name }} \
        --field release-repository=${{ github.repository }}

---

### .Github/Workflows/Release Train Test.Yml (.github/workflows/release-train-test.yml)

# This file was auto-generated by github-actions-workflow-generator 0.0.6. Do not edit.
# To update it, modify .github/workflow-generator.yml as needed and re-run the generator.

name: "Release Train – Test"
run-name: "${{ inputs.callback-ref }} – Test"
"on":
  workflow_dispatch:
    inputs:
      callback:
        description: "Repository to which a callback should be made upon completion"
        required: true
        type: "string"
      callback-ref:
        description: "Ref in the callback repository to which a callback should be made upon completion"
        required: true
        type: "string"
      release-train-maven-repository-url:
        description: "URL of a Maven repository to be used to resolve artifacts of projects earlier in the train"
        required: true
        type: "string"
permissions:
  contents: "read"
concurrency:
  group: "${{ github.workflow }}-${{ github.ref }}"
jobs:
  test-release:
    name: "Test Release"
    runs-on: ${{ vars.UBUNTU_SMALL || 'ubuntu-latest' }}
    steps:
    - name: "Prevent Re-runs"
      id: "prevent-re-runs"
      run: |-
        if [ "$GITHUB_RUN_ATTEMPT" -gt 1 ]; then
          echo "Re-runs are prohibited. Use the 'Release Train – Retry' workflow to retry test failures"
          exit 1
        fi
    - name: "Set up Java"
      id: "set-up-java"
      uses: "actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95" # v5.6.0
      with:
        distribution: "liberica"
        java-version: "17"
    - name: "Check Out Code"
      id: "check-out-code"
      uses: "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" # v7.0.0
    - name: "Restore Build System Caches"
      id: "restore-build-system-caches"
      uses: "actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9" # v6.1.0
      with:
        key: "release-train-${{ inputs.callback-ref }}-${{ github.ref_name }}"
        path: "~/.m2/repository"
    - name: "Test Release"
      id: "test-release"
      uses: "./.github/actions/release-train-test"
      env:
        COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
        COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
        COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        RELEASE_TRAIN_MAVEN_REPOSITORY_PASSWORD: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_PASSWORD }}"
        RELEASE_TRAIN_MAVEN_REPOSITORY_URL: "${{ inputs.release-train-maven-repository-url }}"
        RELEASE_TRAIN_MAVEN_REPOSITORY_USERNAME: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_MAVEN_REPOSITORY_USERNAME }}"
    - name: "Send Callback"
      id: "send-callback"
      if: "${{ !cancelled() }}"
      env:
        GH_TOKEN: "${{ secrets.RELEASE_TRAIN_PARTICIPANT_GITHUB_TOKEN }}"
      run: |-
        gh workflow run callback \
        --repo ${{ inputs.callback }} \
        --ref ${{ inputs.callback-ref }} \
        --field commit-hash=${{ steps.check-out-code.outputs.commit }} \
        --field release-branch=${{ github.ref_name }} \
        --field release-repository=${{ github.repository }} \
        --field result=${{ job.status == 'success' && 'tested' || 'test-failed' }} \
        --field workflow-run-url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
    - name: "Upload Build System Reports"
      id: "upload-build-system-reports"
      if: "${{ failure() }}"
      uses: "actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" # v7.0.1
      with:
        name: "build-system-reports"
        path: |-
          **/target/surefire-reports
          **/target/failsafe-reports

---

### .Github/Workflows/Spring Ai Dependency Updates.Yml (.github/workflows/spring-ai-dependency-updates.yml)

name: Dependency Updates

on:
  schedule:
    - cron: '0 7 * * 1'  # 07:00 UTC every Monday
  workflow_dispatch:

jobs:
  dependency-updates:
    name: List dependency updates
    runs-on: ubuntu-latest
    if: ${{ github.repository_owner == 'spring-projects' }}
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Check for dependency updates
        run: |
          ./mvnw --batch-mode -ntp \
            versions:display-dependency-updates \
            -DprocessDependencyManagementTransitive=false \
            -DallowSnapshots=false \
            -Dversions.outputFile=$(pwd)/dependency-updates.txt \
            -Dversions.logOutput=false

      - name: Publish job summary
        run: |
          # Parse the versions-maven-plugin output into artifact|current|latest rows.
          # Lines come in two formats:
          #   single-line:  "  groupId:artifact ..... current -> latest"
          #   wrapped:      "  groupId:artifact ..."   (artifact too long)
          #                 "                   current -> latest"
          awk '
            /->/ {
              split($0, parts, " -> ")
              latest = parts[2]
              gsub(/^[ \t]+|[ \t\r\n]+$/, "", latest)
              n = split(parts[1], words, " ")
              current = words[n]
              if (pending != "") {
                print pending "|" current "|" latest
                pending = ""
              } else {
                artifact = words[1]
                if (index(artifact, ":") > 0) print artifact "|" current "|" latest
              }
              next
            }
            /^\s+[a-z].*:.*\.\.\.$/ {
              split($0, words, " ")
              pending = words[1]
              next
            }
            { pending = "" }
          ' dependency-updates.txt \
            | grep -v '^org\.springframework\.ai:' \
            | grep -v '|\${project\.version}|' \
            | grep -v '|\${.*}|' \
            | grep -v '^ch\.qos\.logback:' \
            | grep -v '^co\.elastic\.clients:' \
            | grep -v '^com\.couchbase\.client:' \
            | grep -v '^com\.fasterxml\.jackson\.' \
            | grep -v '^com\.google\.code\.gson:' \
            | grep -v '^com\.microsoft\.onnxruntime:' \
            | grep -v '^com\.zaxxer:HikariCP' \
            | grep -v '^io\.grpc:' \
            | grep -v '^io\.rest-assured:json-path' \
            | grep -v '^io\.rest-assured:rest-assured\b' \
            | grep -v '^jakarta\.servlet:' \
            | grep -v '^jakarta\.validation:' \
            | grep -v '^net\.bytebuddy:' \
            | grep -v '^org\.apache\.httpcomponents\.client5:httpclient5' \
            | grep -v '^org\.apache\.tomcat\.embed:' \
            | grep -v '^org\.assertj:' \
            | grep -v '^org\.hsqldb:' \
            | grep -v '^org\.jetbrains\.kotlin:' \
            | grep -v '^org\.junit\.jupiter:' \
            | grep -v '^org\.mariadb\.jdbc:' \
            | grep -v '^org\.neo4j\.driver:neo4j-java-driver' \
            | grep -v '^org\.postgresql:' \
            | grep -v '^org\.skyscreamer:' \
            | grep -v '^redis\.clients:' \
            | grep -v '^tools\.jackson\.' \
            | sort -u \
            > filtered-updates.txt

          echo "## Dependency Updates Available" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "> Versions already managed by imported BOMs (Spring Boot, DJL, MCP, REST Assured) are excluded from the report." >> $GITHUB_STEP_SUMMARY
          echo "> All updates require manual verification and integration testing before adoption." >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY

          if [ ! -s filtered-updates.txt ]; then
            echo "All dependencies are up to date." >> $GITHUB_STEP_SUMMARY
          else
            echo "| Dependency | Current | Latest |" >> $GITHUB_STEP_SUMMARY
            echo "|-----------|---------|--------|" >> $GITHUB_STEP_SUMMARY
            while IFS='|' read -r artifact current latest; do
              echo "| \`$artifact\` | $current | **$latest** |" >> $GITHUB_STEP_SUMMARY
            done < filtered-updates.txt
          fi

      - name: Upload full dependency update report
        if: always()
        uses: actions/upload-artifact@v6
        with:
          name: dependency-updates-report
          path: dependency-updates.txt
          retention-days: 1

---

### .Github/Workflows/Spring Ai Integration Tests.Yml (.github/workflows/spring-ai-integration-tests.yml)

name: Spring AI Integration Tests
run-name: Spring AI Integration Tests

on:
  workflow_dispatch:
    inputs:
      test_suites:
        description: 'Test suites to run (comma-separated: ollama, anthropic, azure-openai, mistral-ai, elevenlabs, bedrock, deepseek, google-genai, vectorstores, autoconfigure, spring-ai-integration, docker-compose, testcontainers). Leave empty to run all.'
        required: false
        default: ''
        type: string
      exclude_test_suites:
        description: 'Test suites to exclude (comma-separated). Takes precedence over test_suites.'
        required: false
        default: ''
        type: string
      springBootVersion:
        description: 'Spring Boot version to test against (leave empty to use the project default)'
        required: false
        default: ''
        type: string
      runner:
        description: 'Runner label to use for all jobs (e.g. UBUNTU_SMALL, ubuntu-latest, ubuntu24-2-8-OSS). Leave empty to use the default.'
        required: false
        default: ''
        type: string
  schedule:
    - cron: '0 4 * * 1,3,5'  # Mon, Wed, Fri at 4 AM UTC

jobs:

  build-all:
    name: Build all modules
    if: ${{ github.repository_owner == 'spring-projects' }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Build all modules
        env:
          COMMERCIAL_ARTIFACTORY_USERNAME: "${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}"
          COMMERCIAL_ARTIFACTORY_PASSWORD: "${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}"
          COMMERCIAL_SNAPSHOT_REPO_URL: "${{ vars.COMMERCIAL_SNAPSHOT_REPO_URL }}"
          COMMERCIAL_RELEASE_REPO_URL: "${{ vars.COMMERCIAL_RELEASE_REPO_URL }}"
        run: |
          ./mvnw ${{ vars.COMMERCIAL && '-s commercial-settings.xml -Pcommercial' || '' }} --batch-mode -ntp --update-snapshots clean install -DskipTests \
            ${{ inputs.springBootVersion != '' && format('-Dspring-boot.version={0}', inputs.springBootVersion) || '' }}

      - name: Upload Spring AI built artifacts
        uses: actions/upload-artifact@v6
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai
          retention-days: 1

      - name: Purge Spring AI built artifacts
        run: rm -fr ~/.m2/repository/org/springframework/ai

  test-ollama:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'ollama')) && !contains(inputs.exclude_test_suites || '', 'ollama') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_MEDIUM || 'ubuntu-latest') }}
    services:
      ollama:
        image: ollama/ollama:latest
        ports:
          - 11434:11434
    env:
      OLLAMA_WITH_REUSE: true
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: |
          mkdir -p $HOME
          echo "testcontainers.reuse.enable = true" >> $HOME/.testcontainers.properties

      - name: Integration Test
        uses: ./.github/actions/do-integration-test
        with:
          model-name: ollama
          maven-properties: "-Dskip.model.ollama=false"
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-anthropic:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'anthropic')) && !contains(inputs.exclude_test_suites || '', 'anthropic') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
    steps:
      - name: Check secret
        id: secret_check
        if: ${{ env.ANTHROPIC_API_KEY != '' }}
        run: echo "Secret exists"

      - name: Checkout source code
        if: steps.secret_check.conclusion == 'success'
        uses: actions/checkout@v6

      - name: Set up JDK
        if: steps.secret_check.conclusion == 'success'
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        if: steps.secret_check.conclusion == 'success'
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Integration Test
        if: steps.secret_check.conclusion == 'success'
        uses: ./.github/actions/do-integration-test
        with:
          model-name: anthropic
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-azure-openai:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'azure-openai')) && !contains(inputs.exclude_test_suites || '', 'azure-openai') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
      AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
      AZURE_OPENAI_TRANSCRIPTION_API_KEY: ${{ secrets.AZURE_OPENAI_TRANSCRIPTION_API_KEY }}
      AZURE_OPENAI_TRANSCRIPTION_ENDPOINT: ${{ secrets.AZURE_OPENAI_TRANSCRIPTION_ENDPOINT }}
      AZURE_OPENAI_IMAGE_API_KEY: ${{ secrets.AZURE_OPENAI_IMAGE_API_KEY }}
      AZURE_OPENAI_IMAGE_ENDPOINT: ${{ secrets.AZURE_OPENAI_IMAGE_ENDPOINT }}
    steps:
      - name: Check secrets
        id: secret_check
        if: ${{ env.AZURE_OPENAI_API_KEY != '' && env.AZURE_OPENAI_ENDPOINT != '' && env.AZURE_OPENAI_TRANSCRIPTION_API_KEY != '' && env.AZURE_OPENAI_TRANSCRIPTION_ENDPOINT != '' && env.AZURE_OPENAI_IMAGE_API_KEY != '' && env.AZURE_OPENAI_IMAGE_ENDPOINT != '' }}
        run: echo "Secrets exist"

      - name: Checkout source code
        if: steps.secret_check.conclusion == 'success'
        uses: actions/checkout@v6

      - name: Set up JDK
        if: steps.secret_check.conclusion == 'success'
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        if: steps.secret_check.conclusion == 'success'
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Integration Test
        if: steps.secret_check.conclusion == 'success'
        uses: ./.github/actions/do-integration-test
        with:
          model-name: azure-openai
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-mistral-ai:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'mistral-ai')) && !contains(inputs.exclude_test_suites || '', 'mistral-ai') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      MISTRAL_AI_API_KEY: ${{ secrets.MISTRAL_AI_API_KEY }}
    steps:
      - name: Check secrets
        id: secret_check
        if: ${{ env.MISTRAL_AI_API_KEY != '' }}
        run: echo "Secrets exist"

      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Integration Test
        uses: ./.github/actions/do-integration-test
        with:
          model-name: mistral-ai
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-elevenlabs:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'elevenlabs')) && !contains(inputs.exclude_test_suites || '', 'elevenlabs') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      ELEVEN_LABS_API_KEY: ${{ secrets.ELEVEN_LABS_API_KEY }}
    steps:
      - name: Check secrets
        id: secret_check
        if: ${{ env.ELEVEN_LABS_API_KEY != '' }}
        run: echo "Secrets exist"

      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Integration Test
        uses: ./.github/actions/do-integration-test
        with:
          model-name: elevenlabs
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-bedrock:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'bedrock')) && !contains(inputs.exclude_test_suites || '', 'bedrock') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    steps:
      - name: Check secrets
        id: secret_check
        if: ${{ env.AWS_ACCESS_KEY_ID != '' && env.AWS_SECRET_ACCESS_KEY != '' }}
        run: echo "Secrets exist"

      - name: Checkout source code
        if: steps.secret_check.conclusion == 'success'
        uses: actions/checkout@v6

      - name: Set up JDK
        if: steps.secret_check.conclusion == 'success'
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        if: steps.secret_check.conclusion == 'success'
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Integration Test
        if: steps.secret_check.conclusion == 'success'
        uses: ./.github/actions/do-multi-module-test
        with:
          modules: models/spring-ai-bedrock,models/spring-ai-bedrock-converse
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-deepseek:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'deepseek')) && !contains(inputs.exclude_test_suites || '', 'deepseek') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
    steps:
      - name: Check secret
        id: secret_check
        if: ${{ env.DEEPSEEK_API_KEY != '' }}
        run: echo "Secret exists"

      - name: Checkout source code
        if: steps.secret_check.conclusion == 'success'
        uses: actions/checkout@v6

      - name: Set up JDK
        if: steps.secret_check.conclusion == 'success'
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        if: steps.secret_check.conclusion == 'success'
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Integration Test
        if: steps.secret_check.conclusion == 'success'
        uses: ./.github/actions/do-integration-test
        with:
          model-name: deepseek
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-google-genai:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'google-genai')) && !contains(inputs.exclude_test_suites || '', 'google-genai') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
    steps:
      - name: Check secret
        id: secret_check
        if: ${{ env.GOOGLE_API_KEY != '' }}
        run: echo "Secret exists"

      - name: Checkout source code
        if: steps.secret_check.conclusion == 'success'
        uses: actions/checkout@v6

      - name: Set up JDK
        if: steps.secret_check.conclusion == 'success'
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        if: steps.secret_check.conclusion == 'success'
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Integration Test
        if: steps.secret_check.conclusion == 'success'
        uses: ./.github/actions/do-integration-test
        with:
          model-name: google-genai
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-vectorstores:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'vectorstores')) && !contains(inputs.exclude_test_suites || '', 'vectorstores') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_MEDIUM || 'ubuntu-latest') }}
    services:
      ollama:
        image: ollama/ollama:latest
        ports:
          - 11434:11434
    env:
      DOCKER_QUIET: 1              # Suppresses Docker CLI progress output
      TESTCONTAINERS_QUIET: true   # Additional quieting for testcontainers
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      MISTRAL_AI_API_KEY: ${{ secrets.MISTRAL_AI_API_KEY }}
      OLLAMA_TESTS_ENABLED: true
    steps:
      - name: Check secrets
        id: secret_check
        if: ${{ env.OPENAI_API_KEY != '' && env.MISTRAL_AI_API_KEY != '' }}
        run: echo "Secrets exist"

      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: |
          mkdir -p $HOME
          echo "testcontainers.reuse.enable = true" >> $HOME/.testcontainers.properties

      - name: Integration Test
        uses: ./.github/actions/do-multi-module-test
        with:
          modules: vector-stores/spring-ai-azure-store,vector-stores/spring-ai-bedrock-knowledgebase-store,vector-stores/spring-ai-cassandra-store,vector-stores/spring-ai-chroma-store,vector-stores/spring-ai-coherence-store,vector-stores/spring-ai-couchbase-store,vector-stores/spring-ai-elasticsearch-store,vector-stores/spring-ai-gemfire-store,vector-stores/spring-ai-mariadb-store,vector-stores/spring-ai-milvus-store,vector-stores/spring-ai-mongodb-atlas-store,vector-stores/spring-ai-neo4j-store,vector-stores/spring-ai-opensearch-store,vector-stores/spring-ai-oracle-store,vector-stores/spring-ai-pgvector-store,vector-stores/spring-ai-pinecone-store,vector-stores/spring-ai-qdrant-store,vector-stores/spring-ai-redis-semantic-cache,vector-stores/spring-ai-redis-store,${{ vars.COMMERCIAL && 'vector-stores/spring-ai-s3-vector-store,' || '' }}vector-stores/spring-ai-typesense-store,vector-stores/spring-ai-weaviate-store
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-autoconfigure:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'autoconfigure')) && !contains(inputs.exclude_test_suites || '', 'autoconfigure') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_MEDIUM || 'ubuntu-latest') }}
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
      AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
      ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Autoconfigure Test
        uses: ./.github/actions/do-autoconfigure-test
        with:
          spring-ai-branch: ${{ github.ref_name }}
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-spring-ai-integration:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'spring-ai-integration')) && !contains(inputs.exclude_test_suites || '', 'spring-ai-integration') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      DOCKER_QUIET: 1              # Suppresses Docker CLI progress output
      TESTCONTAINERS_QUIET: true   # Additional quieting for testcontainers
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
    steps:
      - name: Check secrets
        id: secret_check
        if: ${{ env.OPENAI_API_KEY != '' }}
        run: echo "Secrets exist"

      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: |
          mkdir -p $HOME
          echo "testcontainers.reuse.enable = true" >> $HOME/.testcontainers.properties

      - name: Integration Test
        uses: ./.github/actions/do-multi-module-test
        with:
          modules: spring-ai-integration-tests
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-docker-compose:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'docker-compose')) && !contains(inputs.exclude_test_suites || '', 'docker-compose') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_SMALL || 'ubuntu-latest') }}
    env:
      DOCKER_QUIET: 1              # Suppresses Docker CLI progress output
      TESTCONTAINERS_QUIET: true   # Additional quieting for testcontainers
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: |
          mkdir -p $HOME
          echo "testcontainers.reuse.enable = true" >> $HOME/.testcontainers.properties

      - name: Integration Test
        uses: ./.github/actions/do-multi-module-test
        with:
          modules: spring-ai-spring-boot-docker-compose
          spring-boot-version: ${{ inputs.springBootVersion }}

  test-testcontainers:
    needs: build-all
    if: ${{ (github.event_name == 'schedule' || inputs.test_suites == '' || contains(inputs.test_suites, 'testcontainers')) && !contains(inputs.exclude_test_suites || '', 'testcontainers') }}
    runs-on: ${{ inputs.runner != '' && inputs.runner || (vars.COMMERCIAL && vars.UBUNTU_MEDIUM || 'ubuntu24-2-8-OSS') }}
    env:
      DOCKER_QUIET: 1              # Suppresses Docker CLI progress output
      TESTCONTAINERS_QUIET: true   # Additional quieting for testcontainers
    steps:
      - name: Checkout source code
        uses: actions/checkout@v6

      - name: Set up JDK
        uses: actions/setup-java@v5
        with:
          java-version: '17'
          distribution: 'liberica'
          cache: 'maven'

      - name: Download Spring AI built artifacts
        uses: actions/download-artifact@v7
        with:
          name: build-artifacts
          path: ~/.m2/repository/org/springframework/ai

      - name: Configure Testcontainers
        run: |
          mkdir -p $HOME
          echo "testcontainers.reuse.enable = true" >> $HOME/.testcontainers.properties

      - name: Integration Test
        uses: ./.github/actions/do-multi-module-test
        with:
          modules: spring-ai-spring-boot-testcontainers
          spring-boot-version: ${{ inputs.springBootVersion }}

---