Compare commits
2 Commits
master
...
7312c59e26
Author | SHA1 | Date | |
---|---|---|---|
7312c59e26 | |||
adf8f087f2 |
127
.github/workflows/docker-build.yaml
vendored
@ -8,12 +8,18 @@ on:
|
|||||||
types: [published]
|
types: [published]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-amd64:
|
build-and-push:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
service: [backend, app]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
with:
|
with:
|
||||||
@ -30,109 +36,38 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build and push AMD64 Docker image
|
- name: Build and push Docker image for ${{ matrix.service }}
|
||||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||||
run: |
|
run: |
|
||||||
DOCKERFILE=app.dockerfile
|
docker buildx create --use
|
||||||
IMAGE_NAME=perplexica
|
if [[ "${{ matrix.service }}" == "backend" ]]; then \
|
||||||
docker buildx build --platform linux/amd64 \
|
DOCKERFILE=backend.dockerfile; \
|
||||||
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:amd64 \
|
IMAGE_NAME=perplexica-backend; \
|
||||||
|
else \
|
||||||
|
DOCKERFILE=app.dockerfile; \
|
||||||
|
IMAGE_NAME=perplexica-frontend; \
|
||||||
|
fi
|
||||||
|
docker buildx build --platform linux/amd64,linux/arm64 \
|
||||||
|
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:main \
|
||||||
--cache-to=type=inline \
|
--cache-to=type=inline \
|
||||||
--provenance false \
|
|
||||||
-f $DOCKERFILE \
|
-f $DOCKERFILE \
|
||||||
-t itzcrazykns1337/${IMAGE_NAME}:amd64 \
|
-t itzcrazykns1337/${IMAGE_NAME}:main \
|
||||||
--push .
|
--push .
|
||||||
|
|
||||||
- name: Build and push AMD64 release Docker image
|
- name: Build and push release Docker image for ${{ matrix.service }}
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
run: |
|
run: |
|
||||||
DOCKERFILE=app.dockerfile
|
docker buildx create --use
|
||||||
IMAGE_NAME=perplexica
|
if [[ "${{ matrix.service }}" == "backend" ]]; then \
|
||||||
docker buildx build --platform linux/amd64 \
|
DOCKERFILE=backend.dockerfile; \
|
||||||
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-amd64 \
|
IMAGE_NAME=perplexica-backend; \
|
||||||
|
else \
|
||||||
|
DOCKERFILE=app.dockerfile; \
|
||||||
|
IMAGE_NAME=perplexica-frontend; \
|
||||||
|
fi
|
||||||
|
docker buildx build --platform linux/amd64,linux/arm64 \
|
||||||
|
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }} \
|
||||||
--cache-to=type=inline \
|
--cache-to=type=inline \
|
||||||
--provenance false \
|
|
||||||
-f $DOCKERFILE \
|
-f $DOCKERFILE \
|
||||||
-t itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-amd64 \
|
-t itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }} \
|
||||||
--push .
|
--push .
|
||||||
|
|
||||||
build-arm64:
|
|
||||||
runs-on: ubuntu-24.04-arm
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
with:
|
|
||||||
install: true
|
|
||||||
|
|
||||||
- name: Log in to DockerHub
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Extract version from release tag
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
id: version
|
|
||||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Build and push ARM64 Docker image
|
|
||||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
|
||||||
run: |
|
|
||||||
DOCKERFILE=app.dockerfile
|
|
||||||
IMAGE_NAME=perplexica
|
|
||||||
docker buildx build --platform linux/arm64 \
|
|
||||||
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:arm64 \
|
|
||||||
--cache-to=type=inline \
|
|
||||||
--provenance false \
|
|
||||||
-f $DOCKERFILE \
|
|
||||||
-t itzcrazykns1337/${IMAGE_NAME}:arm64 \
|
|
||||||
--push .
|
|
||||||
|
|
||||||
- name: Build and push ARM64 release Docker image
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
run: |
|
|
||||||
DOCKERFILE=app.dockerfile
|
|
||||||
IMAGE_NAME=perplexica
|
|
||||||
docker buildx build --platform linux/arm64 \
|
|
||||||
--cache-from=type=registry,ref=itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-arm64 \
|
|
||||||
--cache-to=type=inline \
|
|
||||||
--provenance false \
|
|
||||||
-f $DOCKERFILE \
|
|
||||||
-t itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-arm64 \
|
|
||||||
--push .
|
|
||||||
|
|
||||||
manifest:
|
|
||||||
needs: [build-amd64, build-arm64]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Log in to DockerHub
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Extract version from release tag
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
id: version
|
|
||||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Create and push multi-arch manifest for main
|
|
||||||
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
|
||||||
run: |
|
|
||||||
IMAGE_NAME=perplexica
|
|
||||||
docker manifest create itzcrazykns1337/${IMAGE_NAME}:main \
|
|
||||||
--amend itzcrazykns1337/${IMAGE_NAME}:amd64 \
|
|
||||||
--amend itzcrazykns1337/${IMAGE_NAME}:arm64
|
|
||||||
docker manifest push itzcrazykns1337/${IMAGE_NAME}:main
|
|
||||||
|
|
||||||
- name: Create and push multi-arch manifest for releases
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
run: |
|
|
||||||
IMAGE_NAME=perplexica
|
|
||||||
docker manifest create itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }} \
|
|
||||||
--amend itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-amd64 \
|
|
||||||
--amend itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}-arm64
|
|
||||||
docker manifest push itzcrazykns1337/${IMAGE_NAME}:${{ env.RELEASE_VERSION }}
|
|
||||||
|
6
.gitignore
vendored
@ -4,9 +4,9 @@ npm-debug.log
|
|||||||
yarn-error.log
|
yarn-error.log
|
||||||
|
|
||||||
# Build output
|
# Build output
|
||||||
.next/
|
/.next/
|
||||||
out/
|
/out/
|
||||||
dist/
|
/dist/
|
||||||
|
|
||||||
# IDE/Editor specific
|
# IDE/Editor specific
|
||||||
.vscode/
|
.vscode/
|
||||||
|
@ -6,6 +6,7 @@ const config = {
|
|||||||
endOfLine: 'auto',
|
endOfLine: 'auto',
|
||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
tabWidth: 2,
|
tabWidth: 2,
|
||||||
|
semi: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
@ -1,43 +1,32 @@
|
|||||||
# How to Contribute to Perplexica
|
# How to Contribute to Perplexica
|
||||||
|
|
||||||
Thanks for your interest in contributing to Perplexica! Your help makes this project better. This guide explains how to contribute effectively.
|
Hey there, thanks for deciding to contribute to Perplexica. Anything you help with will support the development of Perplexica and will make it better. Let's walk you through the key aspects to ensure your contributions are effective and in harmony with the project's setup.
|
||||||
|
|
||||||
Perplexica is a modern AI chat application with advanced search capabilities.
|
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
Perplexica's codebase is organized as follows:
|
Perplexica's design consists of two main domains:
|
||||||
|
|
||||||
- **UI Components and Pages**:
|
- **Frontend (`ui` directory)**: This is a Next.js application holding all user interface components. It's a self-contained environment that manages everything the user interacts with.
|
||||||
- **Components (`src/components`)**: Reusable UI components.
|
- **Backend (root and `src` directory)**: The backend logic is situated in the `src` folder, but the root directory holds the main `package.json` for backend dependency management.
|
||||||
- **Pages and Routes (`src/app`)**: Next.js app directory structure with page components.
|
- All of the focus modes are created using the Meta Search Agent class present in `src/search/metaSearchAgent.ts`. The main logic behind Perplexica lies there.
|
||||||
- Main app routes include: home (`/`), chat (`/c`), discover (`/discover`), library (`/library`), and settings (`/settings`).
|
|
||||||
- **API Routes (`src/app/api`)**: API endpoints implemented with Next.js API routes.
|
|
||||||
- `/api/chat`: Handles chat interactions.
|
|
||||||
- `/api/search`: Provides direct access to Perplexica's search capabilities.
|
|
||||||
- Other endpoints for models, files, and suggestions.
|
|
||||||
- **Backend Logic (`src/lib`)**: Contains all the backend functionality including search, database, and API logic.
|
|
||||||
- The search functionality is present inside `src/lib/search` directory.
|
|
||||||
- All of the focus modes are implemented using the Meta Search Agent class in `src/lib/search/metaSearchAgent.ts`.
|
|
||||||
- Database functionality is in `src/lib/db`.
|
|
||||||
- Chat model and embedding model providers are managed in `src/lib/providers`.
|
|
||||||
- Prompt templates and LLM chain definitions are in `src/lib/prompts` and `src/lib/chains` respectively.
|
|
||||||
|
|
||||||
## API Documentation
|
|
||||||
|
|
||||||
Perplexica exposes several API endpoints for programmatic access, including:
|
|
||||||
|
|
||||||
- **Search API**: Access Perplexica's advanced search capabilities directly via the `/api/search` endpoint. For detailed documentation, see `docs/api/search.md`.
|
|
||||||
|
|
||||||
## Setting Up Your Environment
|
## Setting Up Your Environment
|
||||||
|
|
||||||
Before diving into coding, setting up your local environment is key. Here's what you need to do:
|
Before diving into coding, setting up your local environment is key. Here's what you need to do:
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
|
||||||
1. In the root directory, locate the `sample.config.toml` file.
|
1. In the root directory, locate the `sample.config.toml` file.
|
||||||
2. Rename it to `config.toml` and fill in the necessary configuration fields.
|
2. Rename it to `config.toml` and fill in the necessary configuration fields specific to the backend.
|
||||||
3. Run `npm install` to install all dependencies.
|
3. Run `npm install` to install dependencies.
|
||||||
4. Run `npm run db:push` to set up the local sqlite database.
|
4. Run `npm run db:push` to set up the local sqlite.
|
||||||
5. Use `npm run dev` to start the application in development mode.
|
5. Use `npm run dev` to start the backend in development mode.
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
|
||||||
|
1. Navigate to the `ui` folder and repeat the process of renaming `.env.example` to `.env`, making sure to provide the frontend-specific variables.
|
||||||
|
2. Execute `npm install` within the `ui` directory to get the frontend dependencies ready.
|
||||||
|
3. Launch the frontend development server with `npm run dev`.
|
||||||
|
|
||||||
**Please note**: Docker configurations are present for setting up production environments, whereas `npm run dev` is used for development purposes.
|
**Please note**: Docker configurations are present for setting up production environments, whereas `npm run dev` is used for development purposes.
|
||||||
|
|
||||||
|
13
README.md
@ -90,7 +90,6 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker.
|
|||||||
- `OLLAMA`: Your Ollama API URL. You should enter it as `http://host.docker.internal:PORT_NUMBER`. If you installed Ollama on port 11434, use `http://host.docker.internal:11434`. For other ports, adjust accordingly. **You need to fill this if you wish to use Ollama's models instead of OpenAI's**.
|
- `OLLAMA`: Your Ollama API URL. You should enter it as `http://host.docker.internal:PORT_NUMBER`. If you installed Ollama on port 11434, use `http://host.docker.internal:11434`. For other ports, adjust accordingly. **You need to fill this if you wish to use Ollama's models instead of OpenAI's**.
|
||||||
- `GROQ`: Your Groq API key. **You only need to fill this if you wish to use Groq's hosted models**.
|
- `GROQ`: Your Groq API key. **You only need to fill this if you wish to use Groq's hosted models**.
|
||||||
- `ANTHROPIC`: Your Anthropic API key. **You only need to fill this if you wish to use Anthropic models**.
|
- `ANTHROPIC`: Your Anthropic API key. **You only need to fill this if you wish to use Anthropic models**.
|
||||||
- `Gemini`: Your Gemini API key. **You only need to fill this if you wish to use Google's models**.
|
|
||||||
|
|
||||||
**Note**: You can change these after starting Perplexica from the settings dialog.
|
**Note**: You can change these after starting Perplexica from the settings dialog.
|
||||||
|
|
||||||
@ -110,13 +109,14 @@ There are mainly 2 ways of installing Perplexica - With Docker, Without Docker.
|
|||||||
|
|
||||||
1. Install SearXNG and allow `JSON` format in the SearXNG settings.
|
1. Install SearXNG and allow `JSON` format in the SearXNG settings.
|
||||||
2. Clone the repository and rename the `sample.config.toml` file to `config.toml` in the root directory. Ensure you complete all required fields in this file.
|
2. Clone the repository and rename the `sample.config.toml` file to `config.toml` in the root directory. Ensure you complete all required fields in this file.
|
||||||
3. After populating the configuration run `npm i`.
|
3. Rename the `.env.example` file to `.env` in the `ui` folder and fill in all necessary fields.
|
||||||
4. Install the dependencies and then execute `npm run build`.
|
4. After populating the configuration and environment files, run `npm i` in both the `ui` folder and the root directory.
|
||||||
5. Finally, start the app by running `npm run start`
|
5. Install the dependencies and then execute `npm run build` in both the `ui` folder and the root directory.
|
||||||
|
6. Finally, start both the frontend and the backend by running `npm run start` in both the `ui` folder and the root directory.
|
||||||
|
|
||||||
**Note**: Using Docker is recommended as it simplifies the setup process, especially for managing environment variables and dependencies.
|
**Note**: Using Docker is recommended as it simplifies the setup process, especially for managing environment variables and dependencies.
|
||||||
|
|
||||||
See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information like updating, etc.
|
See the [installation documentation](https://github.com/ItzCrazyKns/Perplexica/tree/master/docs/installation) for more information like exposing it your network, etc.
|
||||||
|
|
||||||
### Ollama Connection Errors
|
### Ollama Connection Errors
|
||||||
|
|
||||||
@ -154,13 +154,12 @@ For more details, check out the full documentation [here](https://github.com/Itz
|
|||||||
|
|
||||||
## Expose Perplexica to network
|
## Expose Perplexica to network
|
||||||
|
|
||||||
Perplexica runs on Next.js and handles all API requests. It works right away on the same network and stays accessible even with port forwarding.
|
You can access Perplexica over your home network by following our networking guide [here](https://github.com/ItzCrazyKns/Perplexica/blob/master/docs/installation/NETWORKING.md).
|
||||||
|
|
||||||
## One-Click Deployment
|
## One-Click Deployment
|
||||||
|
|
||||||
[](https://usw.sealos.io/?openapp=system-template%3FtemplateName%3Dperplexica)
|
[](https://usw.sealos.io/?openapp=system-template%3FtemplateName%3Dperplexica)
|
||||||
[](https://repocloud.io/details/?app_id=267)
|
[](https://repocloud.io/details/?app_id=267)
|
||||||
[](https://template.run.claw.cloud/?referralCode=U11MRQ8U9RM4&openapp=system-fastdeploy%3FtemplateName%3Dperplexica)
|
|
||||||
|
|
||||||
## Upcoming Features
|
## Upcoming Features
|
||||||
|
|
||||||
|
@ -1,35 +1,15 @@
|
|||||||
FROM node:20.18.0-slim AS builder
|
FROM node:20.18.0-alpine
|
||||||
|
|
||||||
|
ARG NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001
|
||||||
|
ARG NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api
|
||||||
|
ENV NEXT_PUBLIC_WS_URL=${NEXT_PUBLIC_WS_URL}
|
||||||
|
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
|
||||||
|
|
||||||
WORKDIR /home/perplexica
|
WORKDIR /home/perplexica
|
||||||
|
|
||||||
COPY package.json yarn.lock ./
|
COPY ui /home/perplexica/
|
||||||
RUN yarn install --frozen-lockfile --network-timeout 600000
|
|
||||||
|
|
||||||
COPY tsconfig.json next.config.mjs next-env.d.ts postcss.config.js drizzle.config.ts tailwind.config.ts ./
|
RUN yarn install --frozen-lockfile
|
||||||
COPY src ./src
|
|
||||||
COPY public ./public
|
|
||||||
|
|
||||||
RUN mkdir -p /home/perplexica/data
|
|
||||||
RUN yarn build
|
RUN yarn build
|
||||||
|
|
||||||
RUN yarn add --dev @vercel/ncc
|
CMD ["yarn", "start"]
|
||||||
RUN yarn ncc build ./src/lib/db/migrate.ts -o migrator
|
|
||||||
|
|
||||||
FROM node:20.18.0-slim
|
|
||||||
|
|
||||||
WORKDIR /home/perplexica
|
|
||||||
|
|
||||||
COPY --from=builder /home/perplexica/public ./public
|
|
||||||
COPY --from=builder /home/perplexica/.next/static ./public/_next/static
|
|
||||||
|
|
||||||
COPY --from=builder /home/perplexica/.next/standalone ./
|
|
||||||
COPY --from=builder /home/perplexica/data ./data
|
|
||||||
COPY drizzle ./drizzle
|
|
||||||
COPY --from=builder /home/perplexica/migrator/build ./build
|
|
||||||
COPY --from=builder /home/perplexica/migrator/index.js ./migrate.js
|
|
||||||
|
|
||||||
RUN mkdir /home/perplexica/uploads
|
|
||||||
|
|
||||||
COPY entrypoint.sh ./entrypoint.sh
|
|
||||||
RUN chmod +x ./entrypoint.sh
|
|
||||||
CMD ["./entrypoint.sh"]
|
|
17
backend.dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM node:18-slim
|
||||||
|
|
||||||
|
WORKDIR /home/perplexica
|
||||||
|
|
||||||
|
COPY src /home/perplexica/src
|
||||||
|
COPY tsconfig.json /home/perplexica/
|
||||||
|
COPY drizzle.config.ts /home/perplexica/
|
||||||
|
COPY package.json /home/perplexica/
|
||||||
|
COPY yarn.lock /home/perplexica/
|
||||||
|
|
||||||
|
RUN mkdir /home/perplexica/data
|
||||||
|
RUN mkdir /home/perplexica/uploads
|
||||||
|
|
||||||
|
RUN yarn install --frozen-lockfile --network-timeout 600000
|
||||||
|
RUN yarn build
|
||||||
|
|
||||||
|
CMD ["yarn", "start"]
|
@ -9,22 +9,41 @@ services:
|
|||||||
- perplexica-network
|
- perplexica-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
app:
|
perplexica-backend:
|
||||||
image: itzcrazykns1337/perplexica:main
|
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: app.dockerfile
|
dockerfile: backend.dockerfile
|
||||||
|
image: itzcrazykns1337/perplexica-backend:main
|
||||||
environment:
|
environment:
|
||||||
- SEARXNG_API_URL=http://searxng:8080
|
- SEARXNG_API_URL=http://searxng:8080
|
||||||
- DATA_DIR=/home/perplexica
|
depends_on:
|
||||||
|
- searxng
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3001:3001
|
||||||
networks:
|
|
||||||
- perplexica-network
|
|
||||||
volumes:
|
volumes:
|
||||||
- backend-dbstore:/home/perplexica/data
|
- backend-dbstore:/home/perplexica/data
|
||||||
- uploads:/home/perplexica/uploads
|
- uploads:/home/perplexica/uploads
|
||||||
- ./config.toml:/home/perplexica/config.toml
|
- ./config.toml:/home/perplexica/config.toml
|
||||||
|
extra_hosts:
|
||||||
|
- 'host.docker.internal:host-gateway'
|
||||||
|
networks:
|
||||||
|
- perplexica-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
perplexica-frontend:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: app.dockerfile
|
||||||
|
args:
|
||||||
|
- NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api
|
||||||
|
- NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001
|
||||||
|
image: itzcrazykns1337/perplexica-frontend:main
|
||||||
|
depends_on:
|
||||||
|
- perplexica-backend
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
networks:
|
||||||
|
- perplexica-network
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
@ -6,9 +6,9 @@ Perplexica’s Search API makes it easy to use our AI-powered search engine. You
|
|||||||
|
|
||||||
## Endpoint
|
## Endpoint
|
||||||
|
|
||||||
### **POST** `http://localhost:3000/api/search`
|
### **POST** `http://localhost:3001/api/search`
|
||||||
|
|
||||||
**Note**: Replace `3000` with any other port if you've changed the default PORT
|
**Note**: Replace `3001` with any other port if you've changed the default PORT
|
||||||
|
|
||||||
### Request
|
### Request
|
||||||
|
|
||||||
@ -20,11 +20,11 @@ The API accepts a JSON object in the request body, where you define the focus mo
|
|||||||
{
|
{
|
||||||
"chatModel": {
|
"chatModel": {
|
||||||
"provider": "openai",
|
"provider": "openai",
|
||||||
"name": "gpt-4o-mini"
|
"model": "gpt-4o-mini"
|
||||||
},
|
},
|
||||||
"embeddingModel": {
|
"embeddingModel": {
|
||||||
"provider": "openai",
|
"provider": "openai",
|
||||||
"name": "text-embedding-3-large"
|
"model": "text-embedding-3-large"
|
||||||
},
|
},
|
||||||
"optimizationMode": "speed",
|
"optimizationMode": "speed",
|
||||||
"focusMode": "webSearch",
|
"focusMode": "webSearch",
|
||||||
@ -32,26 +32,24 @@ The API accepts a JSON object in the request body, where you define the focus mo
|
|||||||
"history": [
|
"history": [
|
||||||
["human", "Hi, how are you?"],
|
["human", "Hi, how are you?"],
|
||||||
["assistant", "I am doing well, how can I help you today?"]
|
["assistant", "I am doing well, how can I help you today?"]
|
||||||
],
|
]
|
||||||
"systemInstructions": "Focus on providing technical details about Perplexica's architecture.",
|
|
||||||
"stream": false
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Request Parameters
|
### Request Parameters
|
||||||
|
|
||||||
- **`chatModel`** (object, optional): Defines the chat model to be used for the query. For model details you can send a GET request at `http://localhost:3000/api/models`. Make sure to use the key value (For example "gpt-4o-mini" instead of the display name "GPT 4 omni mini").
|
- **`chatModel`** (object, optional): Defines the chat model to be used for the query. For model details you can send a GET request at `http://localhost:3001/api/models`. Make sure to use the key value (For example "gpt-4o-mini" instead of the display name "GPT 4 omni mini").
|
||||||
|
|
||||||
- `provider`: Specifies the provider for the chat model (e.g., `openai`, `ollama`).
|
- `provider`: Specifies the provider for the chat model (e.g., `openai`, `ollama`).
|
||||||
- `name`: The specific model from the chosen provider (e.g., `gpt-4o-mini`).
|
- `model`: The specific model from the chosen provider (e.g., `gpt-4o-mini`).
|
||||||
- Optional fields for custom OpenAI configuration:
|
- Optional fields for custom OpenAI configuration:
|
||||||
- `customOpenAIBaseURL`: If you’re using a custom OpenAI instance, provide the base URL.
|
- `customOpenAIBaseURL`: If you’re using a custom OpenAI instance, provide the base URL.
|
||||||
- `customOpenAIKey`: The API key for a custom OpenAI instance.
|
- `customOpenAIKey`: The API key for a custom OpenAI instance.
|
||||||
|
|
||||||
- **`embeddingModel`** (object, optional): Defines the embedding model for similarity-based searching. For model details you can send a GET request at `http://localhost:3000/api/models`. Make sure to use the key value (For example "text-embedding-3-large" instead of the display name "Text Embedding 3 Large").
|
- **`embeddingModel`** (object, optional): Defines the embedding model for similarity-based searching. For model details you can send a GET request at `http://localhost:3001/api/models`. Make sure to use the key value (For example "text-embedding-3-large" instead of the display name "Text Embedding 3 Large").
|
||||||
|
|
||||||
- `provider`: The provider for the embedding model (e.g., `openai`).
|
- `provider`: The provider for the embedding model (e.g., `openai`).
|
||||||
- `name`: The specific embedding model (e.g., `text-embedding-3-large`).
|
- `model`: The specific embedding model (e.g., `text-embedding-3-large`).
|
||||||
|
|
||||||
- **`focusMode`** (string, required): Specifies which focus mode to use. Available modes:
|
- **`focusMode`** (string, required): Specifies which focus mode to use. Available modes:
|
||||||
|
|
||||||
@ -64,8 +62,6 @@ The API accepts a JSON object in the request body, where you define the focus mo
|
|||||||
|
|
||||||
- **`query`** (string, required): The search query or question.
|
- **`query`** (string, required): The search query or question.
|
||||||
|
|
||||||
- **`systemInstructions`** (string, optional): Custom instructions provided by the user to guide the AI's response. These instructions are treated as user preferences and have lower priority than the system's core instructions. For example, you can specify a particular writing style, format, or focus area.
|
|
||||||
|
|
||||||
- **`history`** (array, optional): An array of message pairs representing the conversation history. Each pair consists of a role (either 'human' or 'assistant') and the message content. This allows the system to use the context of the conversation to refine results. Example:
|
- **`history`** (array, optional): An array of message pairs representing the conversation history. Each pair consists of a role (either 'human' or 'assistant') and the message content. This allows the system to use the context of the conversation to refine results. Example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@ -75,13 +71,11 @@ The API accepts a JSON object in the request body, where you define the focus mo
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`stream`** (boolean, optional): When set to `true`, enables streaming responses. Default is `false`.
|
|
||||||
|
|
||||||
### Response
|
### Response
|
||||||
|
|
||||||
The response from the API includes both the final message and the sources used to generate that message.
|
The response from the API includes both the final message and the sources used to generate that message.
|
||||||
|
|
||||||
#### Standard Response (stream: false)
|
#### Example Response
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -106,28 +100,6 @@ The response from the API includes both the final message and the sources used t
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Streaming Response (stream: true)
|
|
||||||
|
|
||||||
When streaming is enabled, the API returns a stream of newline-delimited JSON objects. Each line contains a complete, valid JSON object. The response has Content-Type: application/json.
|
|
||||||
|
|
||||||
Example of streamed response objects:
|
|
||||||
|
|
||||||
```
|
|
||||||
{"type":"init","data":"Stream connected"}
|
|
||||||
{"type":"sources","data":[{"pageContent":"...","metadata":{"title":"...","url":"..."}},...]}
|
|
||||||
{"type":"response","data":"Perplexica is an "}
|
|
||||||
{"type":"response","data":"innovative, open-source "}
|
|
||||||
{"type":"response","data":"AI-powered search engine..."}
|
|
||||||
{"type":"done"}
|
|
||||||
```
|
|
||||||
|
|
||||||
Clients should process each line as a separate JSON object. The different message types include:
|
|
||||||
|
|
||||||
- **`init`**: Initial connection message
|
|
||||||
- **`sources`**: All sources used for the response
|
|
||||||
- **`response`**: Chunks of the generated answer text
|
|
||||||
- **`done`**: Indicates the stream is complete
|
|
||||||
|
|
||||||
### Fields in the Response
|
### Fields in the Response
|
||||||
|
|
||||||
- **`message`** (string): The search result, generated based on the query and focus mode.
|
- **`message`** (string): The search result, generated based on the query and focus mode.
|
||||||
|
@ -4,7 +4,7 @@ Curious about how Perplexica works? Don't worry, we'll cover it here. Before we
|
|||||||
|
|
||||||
We'll understand how Perplexica works by taking an example of a scenario where a user asks: "How does an A.C. work?". We'll break down the process into steps to make it easier to understand. The steps are as follows:
|
We'll understand how Perplexica works by taking an example of a scenario where a user asks: "How does an A.C. work?". We'll break down the process into steps to make it easier to understand. The steps are as follows:
|
||||||
|
|
||||||
1. The message is sent to the `/api/chat` route where it invokes the chain. The chain will depend on your focus mode. For this example, let's assume we use the "webSearch" focus mode.
|
1. The message is sent via WS to the backend server where it invokes the chain. The chain will depend on your focus mode. For this example, let's assume we use the "webSearch" focus mode.
|
||||||
2. The chain is now invoked; first, the message is passed to another chain where it first predicts (using the chat history and the question) whether there is a need for sources and searching the web. If there is, it will generate a query (in accordance with the chat history) for searching the web that we'll take up later. If not, the chain will end there, and then the answer generator chain, also known as the response generator, will be started.
|
2. The chain is now invoked; first, the message is passed to another chain where it first predicts (using the chat history and the question) whether there is a need for sources and searching the web. If there is, it will generate a query (in accordance with the chat history) for searching the web that we'll take up later. If not, the chain will end there, and then the answer generator chain, also known as the response generator, will be started.
|
||||||
3. The query returned by the first chain is passed to SearXNG to search the web for information.
|
3. The query returned by the first chain is passed to SearXNG to search the web for information.
|
||||||
4. After the information is retrieved, it is based on keyword-based search. We then convert the information into embeddings and the query as well, then we perform a similarity search to find the most relevant sources to answer the query.
|
4. After the information is retrieved, it is based on keyword-based search. We then convert the information into embeddings and the query as well, then we perform a similarity search to find the most relevant sources to answer the query.
|
||||||
|
109
docs/installation/NETWORKING.md
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# Expose Perplexica to a network
|
||||||
|
|
||||||
|
This guide will show you how to make Perplexica available over a network. Follow these steps to allow computers on the same network to interact with Perplexica. Choose the instructions that match the operating system you are using.
|
||||||
|
|
||||||
|
## Windows
|
||||||
|
|
||||||
|
1. Open PowerShell as Administrator
|
||||||
|
|
||||||
|
2. Navigate to the directory containing the `docker-compose.yaml` file
|
||||||
|
|
||||||
|
3. Stop and remove the existing Perplexica containers and images:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down --rmi all
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Open the `docker-compose.yaml` file in a text editor like Notepad++
|
||||||
|
|
||||||
|
5. Replace `127.0.0.1` with the IP address of the server Perplexica is running on in these two lines:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
args:
|
||||||
|
- NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api
|
||||||
|
- NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Save and close the `docker-compose.yaml` file
|
||||||
|
|
||||||
|
7. Rebuild and restart the Perplexica container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
## macOS
|
||||||
|
|
||||||
|
1. Open the Terminal application
|
||||||
|
|
||||||
|
2. Navigate to the directory with the `docker-compose.yaml` file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Stop and remove existing containers and images:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down --rmi all
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Open `docker-compose.yaml` in a text editor like Sublime Text:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Replace `127.0.0.1` with the server IP in these lines:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
args:
|
||||||
|
- NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api
|
||||||
|
- NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Save and exit the editor
|
||||||
|
|
||||||
|
7. Rebuild and restart Perplexica:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Linux
|
||||||
|
|
||||||
|
1. Open the terminal
|
||||||
|
|
||||||
|
2. Navigate to the `docker-compose.yaml` directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /path/to/docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Stop and remove containers and images:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose down --rmi all
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Edit `docker-compose.yaml`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano docker-compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Replace `127.0.0.1` with the server IP:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
args:
|
||||||
|
- NEXT_PUBLIC_API_URL=http://127.0.0.1:3001/api
|
||||||
|
- NEXT_PUBLIC_WS_URL=ws://127.0.0.1:3001
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Save and exit the editor
|
||||||
|
|
||||||
|
7. Rebuild and restart Perplexica:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
@ -39,8 +39,11 @@ To update Perplexica to the latest version, follow these steps:
|
|||||||
2. Navigate to the project directory.
|
2. Navigate to the project directory.
|
||||||
|
|
||||||
3. Check for changes in the configuration files. If the `sample.config.toml` file contains new fields, delete your existing `config.toml` file, rename `sample.config.toml` to `config.toml`, and update the configuration accordingly.
|
3. Check for changes in the configuration files. If the `sample.config.toml` file contains new fields, delete your existing `config.toml` file, rename `sample.config.toml` to `config.toml`, and update the configuration accordingly.
|
||||||
4. After populating the configuration run `npm i`.
|
|
||||||
5. Install the dependencies and then execute `npm run build`.
|
4. Execute `npm i` in both the `ui` folder and the root directory.
|
||||||
6. Finally, start the app by running `npm run start`
|
|
||||||
|
5. Once the packages are updated, execute `npm run build` in both the `ui` folder and the root directory.
|
||||||
|
|
||||||
|
6. Finally, start both the frontend and the backend by running `npm run start` in both the `ui` folder and the root directory.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { defineConfig } from 'drizzle-kit';
|
import { defineConfig } from 'drizzle-kit';
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
dialect: 'sqlite',
|
dialect: 'sqlite',
|
||||||
schema: './src/lib/db/schema.ts',
|
schema: './src/db/schema.ts',
|
||||||
out: './drizzle',
|
out: './drizzle',
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: path.join(process.cwd(), 'data', 'db.sqlite'),
|
url: './data/db.sqlite',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
CREATE TABLE IF NOT EXISTS `chats` (
|
|
||||||
`id` text PRIMARY KEY NOT NULL,
|
|
||||||
`title` text NOT NULL,
|
|
||||||
`createdAt` text NOT NULL,
|
|
||||||
`focusMode` text NOT NULL,
|
|
||||||
`files` text DEFAULT '[]'
|
|
||||||
);
|
|
||||||
--> statement-breakpoint
|
|
||||||
CREATE TABLE IF NOT EXISTS `messages` (
|
|
||||||
`id` integer PRIMARY KEY NOT NULL,
|
|
||||||
`content` text NOT NULL,
|
|
||||||
`chatId` text NOT NULL,
|
|
||||||
`messageId` text NOT NULL,
|
|
||||||
`type` text,
|
|
||||||
`metadata` text
|
|
||||||
);
|
|
@ -1,116 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "6",
|
|
||||||
"dialect": "sqlite",
|
|
||||||
"id": "ef3a044b-0f34-40b5-babb-2bb3a909ba27",
|
|
||||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
|
||||||
"tables": {
|
|
||||||
"chats": {
|
|
||||||
"name": "chats",
|
|
||||||
"columns": {
|
|
||||||
"id": {
|
|
||||||
"name": "id",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": true,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"name": "title",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"createdAt": {
|
|
||||||
"name": "createdAt",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"focusMode": {
|
|
||||||
"name": "focusMode",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"files": {
|
|
||||||
"name": "files",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"default": "'[]'"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {},
|
|
||||||
"checkConstraints": {}
|
|
||||||
},
|
|
||||||
"messages": {
|
|
||||||
"name": "messages",
|
|
||||||
"columns": {
|
|
||||||
"id": {
|
|
||||||
"name": "id",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": true,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"content": {
|
|
||||||
"name": "content",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"chatId": {
|
|
||||||
"name": "chatId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"messageId": {
|
|
||||||
"name": "messageId",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"name": "type",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false
|
|
||||||
},
|
|
||||||
"metadata": {
|
|
||||||
"name": "metadata",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {},
|
|
||||||
"checkConstraints": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"views": {},
|
|
||||||
"enums": {},
|
|
||||||
"_meta": {
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {},
|
|
||||||
"columns": {}
|
|
||||||
},
|
|
||||||
"internal": {
|
|
||||||
"indexes": {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "7",
|
|
||||||
"dialect": "sqlite",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"idx": 0,
|
|
||||||
"version": "6",
|
|
||||||
"when": 1748405503809,
|
|
||||||
"tag": "0000_fuzzy_randall",
|
|
||||||
"breakpoints": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
node migrate.js
|
|
||||||
|
|
||||||
exec node server.js
|
|
5
next-env.d.ts
vendored
@ -1,5 +0,0 @@
|
|||||||
/// <reference types="next" />
|
|
||||||
/// <reference types="next/image-types/global" />
|
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
|
||||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
|
99
package.json
@ -1,68 +1,53 @@
|
|||||||
{
|
{
|
||||||
"name": "perplexica-frontend",
|
"name": "perplexica-backend",
|
||||||
"version": "1.11.0-rc1",
|
"version": "1.10.0-rc3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "ItzCrazyKns",
|
"author": "ItzCrazyKns",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"start": "npm run db:push && node dist/app.js",
|
||||||
"build": "npm run db:push && next build",
|
"build": "tsc",
|
||||||
"start": "next start",
|
"dev": "nodemon --ignore uploads/ src/app.ts ",
|
||||||
"lint": "next lint",
|
"db:push": "drizzle-kit push sqlite",
|
||||||
"format:write": "prettier . --write",
|
"format": "prettier . --check",
|
||||||
"db:push": "drizzle-kit push"
|
"format:write": "prettier . --write"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@headlessui/react": "^2.2.0",
|
|
||||||
"@iarna/toml": "^2.2.5",
|
|
||||||
"@icons-pack/react-simple-icons": "^12.3.0",
|
|
||||||
"@langchain/anthropic": "^0.3.15",
|
|
||||||
"@langchain/community": "^0.3.36",
|
|
||||||
"@langchain/core": "^0.3.42",
|
|
||||||
"@langchain/google-genai": "^0.1.12",
|
|
||||||
"@langchain/openai": "^0.0.25",
|
|
||||||
"@langchain/textsplitters": "^0.1.0",
|
|
||||||
"@tailwindcss/typography": "^0.5.12",
|
|
||||||
"@xenova/transformers": "^2.17.2",
|
|
||||||
"axios": "^1.8.3",
|
|
||||||
"better-sqlite3": "^11.9.1",
|
|
||||||
"clsx": "^2.1.0",
|
|
||||||
"compute-cosine-similarity": "^1.1.0",
|
|
||||||
"compute-dot": "^1.1.0",
|
|
||||||
"drizzle-orm": "^0.40.1",
|
|
||||||
"html-to-text": "^9.0.5",
|
|
||||||
"jspdf": "^3.0.1",
|
|
||||||
"langchain": "^0.1.30",
|
|
||||||
"lucide-react": "^0.363.0",
|
|
||||||
"mammoth": "^1.9.1",
|
|
||||||
"markdown-to-jsx": "^7.7.2",
|
|
||||||
"next": "^15.2.2",
|
|
||||||
"next-themes": "^0.3.0",
|
|
||||||
"pdf-parse": "^1.1.1",
|
|
||||||
"react": "^18",
|
|
||||||
"react-dom": "^18",
|
|
||||||
"react-text-to-speech": "^0.14.5",
|
|
||||||
"react-textarea-autosize": "^8.5.3",
|
|
||||||
"sonner": "^1.4.41",
|
|
||||||
"tailwind-merge": "^2.2.2",
|
|
||||||
"winston": "^3.17.0",
|
|
||||||
"yet-another-react-lightbox": "^3.17.2",
|
|
||||||
"zod": "^3.22.4"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/better-sqlite3": "^7.6.12",
|
"@types/better-sqlite3": "^7.6.10",
|
||||||
|
"@types/cors": "^2.8.17",
|
||||||
|
"@types/express": "^4.17.21",
|
||||||
"@types/html-to-text": "^9.0.4",
|
"@types/html-to-text": "^9.0.4",
|
||||||
"@types/jspdf": "^2.0.0",
|
"@types/multer": "^1.4.12",
|
||||||
"@types/node": "^20",
|
|
||||||
"@types/pdf-parse": "^1.1.4",
|
"@types/pdf-parse": "^1.1.4",
|
||||||
"@types/react": "^18",
|
"@types/readable-stream": "^4.0.11",
|
||||||
"@types/react-dom": "^18",
|
"@types/ws": "^8.5.12",
|
||||||
"autoprefixer": "^10.0.1",
|
"drizzle-kit": "^0.22.7",
|
||||||
"drizzle-kit": "^0.30.5",
|
"nodemon": "^3.1.0",
|
||||||
"eslint": "^8",
|
|
||||||
"eslint-config-next": "14.1.4",
|
|
||||||
"postcss": "^8",
|
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"tailwindcss": "^3.3.0",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5"
|
"typescript": "^5.4.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@iarna/toml": "^2.2.5",
|
||||||
|
"@langchain/anthropic": "^0.2.3",
|
||||||
|
"@langchain/community": "^0.2.16",
|
||||||
|
"@langchain/openai": "^0.0.25",
|
||||||
|
"@langchain/google-genai": "^0.0.23",
|
||||||
|
"@xenova/transformers": "^2.17.1",
|
||||||
|
"axios": "^1.6.8",
|
||||||
|
"better-sqlite3": "^11.0.0",
|
||||||
|
"compute-cosine-similarity": "^1.1.0",
|
||||||
|
"compute-dot": "^1.1.0",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"drizzle-orm": "^0.31.2",
|
||||||
|
"express": "^4.19.2",
|
||||||
|
"html-to-text": "^9.0.5",
|
||||||
|
"langchain": "^0.1.30",
|
||||||
|
"mammoth": "^1.8.0",
|
||||||
|
"multer": "^1.4.5-lts.1",
|
||||||
|
"pdf-parse": "^1.1.1",
|
||||||
|
"winston": "^3.13.0",
|
||||||
|
"ws": "^8.17.1",
|
||||||
|
"zod": "^3.22.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,131 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.34167" y="-.34167" width="1.6833" height="1.85">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-sun-shiny {
|
|
||||||
0% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
stroke-dasharray: 0.1px 10px;
|
|
||||||
stroke-dashoffset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun-shiny line {
|
|
||||||
-webkit-animation-name: am-weather-sun-shiny;
|
|
||||||
-moz-animation-name: am-weather-sun-shiny;
|
|
||||||
-ms-animation-name: am-weather-sun-shiny;
|
|
||||||
animation-name: am-weather-sun-shiny;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.9 KiB |
@ -1,159 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.3038" y="-.3318" width="1.6076" height="1.894">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g id="night" transform="translate(-4,-18)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .78534 36 20.022)" stroke-width="1.2616">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 2.7 5.2 3.3 4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5" fill="#ffa500" stroke-miterlimit="10"
|
|
||||||
stroke-width="1.4105" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 2.7 5.2 3.3 4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" stroke-width="1.4105" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2.5232" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 6.7 KiB |
@ -1,178 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.28472" width="1.403" height="1.6944">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-sun-shiny {
|
|
||||||
0% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
stroke-dasharray: 0.1px 10px;
|
|
||||||
stroke-dashoffset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun-shiny line {
|
|
||||||
-webkit-animation-name: am-weather-sun-shiny;
|
|
||||||
-moz-animation-name: am-weather-sun-shiny;
|
|
||||||
-ms-animation-name: am-weather-sun-shiny;
|
|
||||||
animation-name: am-weather-sun-shiny;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-2"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#c6deff" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 6.8 KiB |
@ -1,206 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.19471" y="-.26087" width="1.3744" height="1.6884">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3 4 4 3.3 5.2 2.7 4" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3 4 4 3.3 5.2 2.7 4"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-2"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#c6deff" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 8.6 KiB |
@ -1,244 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.21122" width="1.403" height="1.4997">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** FOG
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-fog-1 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translate(7px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-1 {
|
|
||||||
-webkit-animation-name: am-weather-fog-1;
|
|
||||||
-moz-animation-name: am-weather-fog-1;
|
|
||||||
-ms-animation-name: am-weather-fog-1;
|
|
||||||
animation-name: am-weather-fog-1;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-fog-2 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
21.05% {
|
|
||||||
transform: translate(-6px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
78.95% {
|
|
||||||
transform: translate(9px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-2 {
|
|
||||||
-webkit-animation-name: am-weather-fog-2;
|
|
||||||
-moz-animation-name: am-weather-fog-2;
|
|
||||||
-ms-animation-name: am-weather-fog-2;
|
|
||||||
animation-name: am-weather-fog-2;
|
|
||||||
-webkit-animation-duration: 20s;
|
|
||||||
-moz-animation-duration: 20s;
|
|
||||||
-ms-animation-duration: 20s;
|
|
||||||
animation-duration: 20s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-fog-3 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
25% {
|
|
||||||
transform: translate(4px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
75% {
|
|
||||||
transform: translate(-4px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-3 {
|
|
||||||
-webkit-animation-name: am-weather-fog-3;
|
|
||||||
-moz-animation-name: am-weather-fog-3;
|
|
||||||
-ms-animation-name: am-weather-fog-3;
|
|
||||||
animation-name: am-weather-fog-3;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-fog-4 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translate(-4px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-4 {
|
|
||||||
-webkit-animation-name: am-weather-fog-4;
|
|
||||||
-moz-animation-name: am-weather-fog-4;
|
|
||||||
-ms-animation-name: am-weather-fog-4;
|
|
||||||
animation-name: am-weather-fog-4;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun" transform="translate(0,16)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />F
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffc04a" stroke="#ffc04a" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-fog" transform="translate(-10,20)" fill="none" stroke="#c6deff" stroke-linecap="round"
|
|
||||||
stroke-width="2">
|
|
||||||
<line class="am-weather-fog-1" y1="0" y2="0" x1="1" x2="37" stroke-dasharray="3, 5, 17, 5, 7" />
|
|
||||||
<line class="am-weather-fog-2" y1="5" y2="5" x1="9" x2="33" stroke-dasharray="11, 7, 15" />
|
|
||||||
<line class="am-weather-fog-3" y1="10" y2="10" x1="5" x2="40" stroke-dasharray="11, 7, 3, 5, 9" />
|
|
||||||
<line class="am-weather-fog-4" y1="15" y2="15" x1="7" x2="42" stroke-dasharray="13, 5, 9, 5, 3" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 8.0 KiB |
@ -1,309 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.21122" width="1.403" height="1.4997">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** FOG
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-fog-1 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translate(7px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-1 {
|
|
||||||
-webkit-animation-name: am-weather-fog-1;
|
|
||||||
-moz-animation-name: am-weather-fog-1;
|
|
||||||
-ms-animation-name: am-weather-fog-1;
|
|
||||||
animation-name: am-weather-fog-1;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-fog-2 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
21.05% {
|
|
||||||
transform: translate(-6px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
78.95% {
|
|
||||||
transform: translate(9px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-2 {
|
|
||||||
-webkit-animation-name: am-weather-fog-2;
|
|
||||||
-moz-animation-name: am-weather-fog-2;
|
|
||||||
-ms-animation-name: am-weather-fog-2;
|
|
||||||
animation-name: am-weather-fog-2;
|
|
||||||
-webkit-animation-duration: 20s;
|
|
||||||
-moz-animation-duration: 20s;
|
|
||||||
-ms-animation-duration: 20s;
|
|
||||||
animation-duration: 20s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-fog-3 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
25% {
|
|
||||||
transform: translate(4px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
75% {
|
|
||||||
transform: translate(-4px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-3 {
|
|
||||||
-webkit-animation-name: am-weather-fog-3;
|
|
||||||
-moz-animation-name: am-weather-fog-3;
|
|
||||||
-ms-animation-name: am-weather-fog-3;
|
|
||||||
animation-name: am-weather-fog-3;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-fog-4 {
|
|
||||||
0% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translate(-4px, 0px)
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate(0px, 0px)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-fog-4 {
|
|
||||||
-webkit-animation-name: am-weather-fog-4;
|
|
||||||
-moz-animation-name: am-weather-fog-4;
|
|
||||||
-ms-animation-name: am-weather-fog-4;
|
|
||||||
animation-name: am-weather-fog-4;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffc04a"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffc04a" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffc04a" stroke="#ffc04a" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-fog" transform="translate(-10,20)" fill="none" stroke="#c6deff" stroke-linecap="round"
|
|
||||||
stroke-width="2">
|
|
||||||
<line class="am-weather-fog-1" y1="0" y2="0" x1="1" x2="37" stroke-dasharray="3, 5, 17, 5, 7" />
|
|
||||||
<line class="am-weather-fog-2" y1="5" y2="5" x1="9" x2="33" stroke-dasharray="11, 7, 15" />
|
|
||||||
<line class="am-weather-fog-3" y1="10" y2="10" x1="5" x2="40" stroke-dasharray="11, 7, 3, 5, 9" />
|
|
||||||
<line class="am-weather-fog-4" y1="15" y2="15" x1="7" x2="42" stroke-dasharray="13, 5, 9, 5, 3" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 11 KiB |
@ -1,204 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.21122" width="1.403" height="1.4997">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** FROST
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-frost {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
1% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
3% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
5% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
7% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
9% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
11% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
13% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
15% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
16% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-frost {
|
|
||||||
-webkit-animation-name: am-weather-frost;
|
|
||||||
-moz-animation-name: am-weather-frost;
|
|
||||||
animation-name: am-weather-frost;
|
|
||||||
-webkit-animation-duration: 1.11s;
|
|
||||||
-moz-animation-duration: 1.11s;
|
|
||||||
animation-duration: 1.11s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun" transform="translate(0,16)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />F
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffc04a" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffc04a" stroke="#ffc04a" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g transform="translate(-16,4)">
|
|
||||||
<g class="am-weather-frost" stroke="#57a0ee" transform="translate(0,2)" fill="none" stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
style="-moz-animation-duration:1.11s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-frost;-moz-animation-timing-function:linear;-webkit-animation-duration:1.11s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-frost;-webkit-animation-timing-function:linear">
|
|
||||||
<path d="M11,32H45" />
|
|
||||||
<path d="M15.5,37H40.5" />
|
|
||||||
<path d="M22.5,42H33.5" />
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path stroke="#57a0ee" transform="translate(0,0)" fill="none" stroke-width="2" stroke-linecap="round"
|
|
||||||
d="M28,31V9M28,22l11,-3.67M34,20l2,-4M34,20l4,2M28,22l-11,-3.67M22,20l-2,-4M22,20l-4,2M28,14.27l3.01,-3.02M28,14.27l-3.01,-3.02" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 7.3 KiB |
@ -1,269 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.21122" width="1.403" height="1.4997">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** FROST
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-frost {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
1% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
3% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
5% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
7% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
9% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
11% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
13% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
15% {
|
|
||||||
-webkit-transform: translate(-0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(-0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(-0.3px, 0.0px);
|
|
||||||
transform: translate(-0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
16% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-frost {
|
|
||||||
-webkit-animation-name: am-weather-frost;
|
|
||||||
-moz-animation-name: am-weather-frost;
|
|
||||||
animation-name: am-weather-frost;
|
|
||||||
-webkit-animation-duration: 1.11s;
|
|
||||||
-moz-animation-duration: 1.11s;
|
|
||||||
animation-duration: 1.11s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffc04a"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffc04a" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffc04a" stroke="#ffc04a" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g transform="translate(-16,4)">
|
|
||||||
<g class="am-weather-frost" stroke="#57a0ee" transform="translate(0,2)" fill="none" stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
style="-moz-animation-duration:1.11s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-frost;-moz-animation-timing-function:linear;-webkit-animation-duration:1.11s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-frost;-webkit-animation-timing-function:linear">
|
|
||||||
<path d="M11,32H45" />
|
|
||||||
<path d="M15.5,37H40.5" />
|
|
||||||
<path d="M22.5,42H33.5" />
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path stroke="#57a0ee" transform="translate(0,0)" fill="none" stroke-width="2" stroke-linecap="round"
|
|
||||||
d="M28,31V9M28,22l11,-3.67M34,20l2,-4M34,20l4,2M28,22l-11,-3.67M22,20l-2,-4M22,20l-4,2M28,14.27l3.01,-3.02M28,14.27l-3.01,-3.02" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 11 KiB |
@ -1,141 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<!-- Mix of Rain and Sleet | Contributed by hsoJ95 on GitHub: https://github.com/hsoj95 -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.24684" y="-.22776" width="1.4937" height="1.5756">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** RAIN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-rain {
|
|
||||||
0% {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dashoffset: -100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-1 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-2 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-delay: 0.25s;
|
|
||||||
-moz-animation-delay: 0.25s;
|
|
||||||
-ms-animation-delay: 0.25s;
|
|
||||||
animation-delay: 0.25s;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-3 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-3 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-3;
|
|
||||||
-moz-animation-name: am-weather-cloud-3;
|
|
||||||
animation-name: am-weather-cloud-3;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-3;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-3;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-sleet-2" transform="translate(-20,-10) rotate(10,-247.39,200.17)" fill="none" stroke="#91c0f8"
|
|
||||||
stroke-linecap="round">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-5,1)" y2="8" stroke-dasharray="0.1, 7" stroke-width="2"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-1" transform="translate(5)" y2="8" stroke-dasharray="0.1, 7" stroke-width="2"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-rain-3" transform="translate(-20,-10) rotate(10,-245.89,217.31)" fill="none" stroke="#91c0f8"
|
|
||||||
stroke-dasharray="4, 7" stroke-linecap="round" stroke-width="2">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-13,1)" y2="8"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-3,2)" y2="8"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-2" transform="translate(7,-1)" y2="8"
|
|
||||||
style="-moz-animation-delay:0.25s;-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-delay:0.25s;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-delay:0.25s;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 7.6 KiB |
@ -1,179 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.21122" width="1.403" height="1.4997">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RAIN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-rain {
|
|
||||||
0% {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dashoffset: -100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-1 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-rain-1" transform="translate(-20,-10) rotate(10,-238.68,233.96)">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-6,1)" y2="8" fill="none" stroke="#91c0f8"
|
|
||||||
stroke-dasharray="4, 7" stroke-linecap="round" stroke-width="2"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 7.4 KiB |
@ -1,243 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.21122" width="1.403" height="1.4997">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RAIN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-rain {
|
|
||||||
0% {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dashoffset: -100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-1 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weaher-rain-1" transform="translate(-20,-10) rotate(10,-238.68,233.96)">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-6,1)" y2="8" fill="none" stroke="#91c0f8"
|
|
||||||
stroke-dasharray="4, 7" stroke-linecap="round" stroke-width="2"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 10 KiB |
@ -1,204 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.20592" width="1.403" height="1.4872">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RAIN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-rain {
|
|
||||||
0% {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dashoffset: -100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-1 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-2 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-delay: 0.25s;
|
|
||||||
-moz-animation-delay: 0.25s;
|
|
||||||
-ms-animation-delay: 0.25s;
|
|
||||||
animation-delay: 0.25s;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" stroke="#ffa500" stroke-linecap="round" stroke-width="2" fifll="none" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g transform="translate(-20,-10) rotate(10,-245.89,217.31)" fill="none" stroke="#91c0f8" stroke-dasharray="4, 7" stroke-linecap="round"
|
|
||||||
stroke-width="2">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-6,1)" y2="8"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-2" transform="translate(0,-1)" y2="8"
|
|
||||||
style="-moz-animation-delay:0.25s;-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-delay:0.25s;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-delay:0.25s;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 8.8 KiB |
@ -1,256 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RAIN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-rain {
|
|
||||||
0% {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dashoffset: -100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-1 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-2 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-delay: 0.25s;
|
|
||||||
-moz-animation-delay: 0.25s;
|
|
||||||
-ms-animation-delay: 0.25s;
|
|
||||||
animation-delay: 0.25s;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g class="layer" transform="translate(16,-2)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-rain-2" transform="translate(-20,-10) rotate(10,34,46)" fill="none" stroke="#91c0f8"
|
|
||||||
stroke-dasharray="4, 7" stroke-linecap="round" stroke-width="2">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-6,1)" x1="34" x2="34" y1="46" y2="54"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-2" transform="translate(0,-1)" x1="34" x2="34" y1="46" y2="54"
|
|
||||||
style="-moz-animation-delay:0.25s;-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-delay:0.25s;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-delay:0.25s;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 11 KiB |
@ -1,206 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.24684" y="-.22892" width="1.4937" height="1.5576">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RAIN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-rain {
|
|
||||||
0% {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dashoffset: -100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-1 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-2 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-delay: 0.25s;
|
|
||||||
-moz-animation-delay: 0.25s;
|
|
||||||
-ms-animation-delay: 0.25s;
|
|
||||||
animation-delay: 0.25s;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" stroke="#ffa500" stroke-linecap="round" stroke-width="2" fifll="none" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g transform="translate(-20,-10) rotate(10,-247.39,200.17)" fill="none" stroke="#91c0f8" stroke-dasharray="4, 4"
|
|
||||||
stroke-linecap="round" stroke-width="2">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-4,1)" y2="8"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-2" transform="translate(0,-1)" y2="8"
|
|
||||||
style="-moz-animation-delay:0.25s;-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-delay:0.25s;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-delay:0.25s;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-1" transform="translate(4)" y2="8"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 9.3 KiB |
@ -1,270 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.24684" y="-.22892" width="1.4937" height="1.5576">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** RAIN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-rain {
|
|
||||||
0% {
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dashoffset: -100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-1 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-rain-2 {
|
|
||||||
-webkit-animation-name: am-weather-rain;
|
|
||||||
-moz-animation-name: am-weather-rain;
|
|
||||||
-ms-animation-name: am-weather-rain;
|
|
||||||
animation-name: am-weather-rain;
|
|
||||||
-webkit-animation-delay: 0.25s;
|
|
||||||
-moz-animation-delay: 0.25s;
|
|
||||||
-ms-animation-delay: 0.25s;
|
|
||||||
animation-delay: 0.25s;
|
|
||||||
-webkit-animation-duration: 8s;
|
|
||||||
-moz-animation-duration: 8s;
|
|
||||||
-ms-animation-duration: 8s;
|
|
||||||
animation-duration: 8s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g transform="translate(-20,-10) rotate(10,-247.39,200.17)" fill="none" stroke="#91c0f8" stroke-dasharray="4, 4"
|
|
||||||
stroke-linecap="round" stroke-width="2">
|
|
||||||
<line class="am-weather-rain-1" transform="translate(-4,1)" y2="8"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-2" transform="translate(0,-1)" y2="8"
|
|
||||||
style="-moz-animation-delay:0.25s;-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-delay:0.25s;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-delay:0.25s;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
<line class="am-weather-rain-1" transform="translate(4)" y2="8"
|
|
||||||
style="-moz-animation-duration:8s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-rain;-moz-animation-timing-function:linear;-ms-animation-duration:8s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-rain;-ms-animation-timing-function:linear;-webkit-animation-duration:8s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-rain;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 12 KiB |
@ -1,374 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<!-- Scattered Thunderstorms | Contributed by hsoJ95 on GitHub: https://github.com/hsoj95 -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.1975" width="1.403" height="1.4766">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-3 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(-5px, 0px);
|
|
||||||
-moz-transform: translate(-5px, 0px);
|
|
||||||
-ms-transform: translate(-5px, 0px);
|
|
||||||
transform: translate(-5px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(10px, 0px);
|
|
||||||
-moz-transform: translate(10px, 0px);
|
|
||||||
-ms-transform: translate(10px, 0px);
|
|
||||||
transform: translate(10px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(-5px, 0px);
|
|
||||||
-moz-transform: translate(-5px, 0px);
|
|
||||||
-ms-transform: translate(-5px, 0px);
|
|
||||||
transform: translate(-5px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-3 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-3;
|
|
||||||
-moz-animation-name: am-weather-cloud-3;
|
|
||||||
animation-name: am-weather-cloud-3;
|
|
||||||
-webkit-animation-duration: 7s;
|
|
||||||
-moz-animation-duration: 7s;
|
|
||||||
animation-duration: 7s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-sun-shiny {
|
|
||||||
0% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
stroke-dasharray: 0.1px 10px;
|
|
||||||
stroke-dashoffset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun-shiny line {
|
|
||||||
-webkit-animation-name: am-weather-sun-shiny;
|
|
||||||
-moz-animation-name: am-weather-sun-shiny;
|
|
||||||
-ms-animation-name: am-weather-sun-shiny;
|
|
||||||
animation-name: am-weather-sun-shiny;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** STROKE
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-stroke {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
2% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
4% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
6% {
|
|
||||||
-webkit-transform: translate(0.5px, 0.4px);
|
|
||||||
-moz-transform: translate(0.5px, 0.4px);
|
|
||||||
-ms-transform: translate(0.5px, 0.4px);
|
|
||||||
transform: translate(0.5px, 0.4px);
|
|
||||||
}
|
|
||||||
|
|
||||||
8% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
10% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
12% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
14% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
16% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
18% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
20% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
22% {
|
|
||||||
-webkit-transform: translate(1px, 0.0px);
|
|
||||||
-moz-transform: translate(1px, 0.0px);
|
|
||||||
-ms-transform: translate(1px, 0.0px);
|
|
||||||
transform: translate(1px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
24% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
26% {
|
|
||||||
-webkit-transform: translate(-1px, 0.0px);
|
|
||||||
-moz-transform: translate(-1px, 0.0px);
|
|
||||||
-ms-transform: translate(-1px, 0.0px);
|
|
||||||
transform: translate(-1px, 0.0px);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
28% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
40% {
|
|
||||||
fill: orange;
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
65% {
|
|
||||||
fill: white;
|
|
||||||
-webkit-transform: translate(-1px, 5.0px);
|
|
||||||
-moz-transform: translate(-1px, 5.0px);
|
|
||||||
-ms-transform: translate(-1px, 5.0px);
|
|
||||||
transform: translate(-1px, 5.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
61% {
|
|
||||||
fill: orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-stroke {
|
|
||||||
-webkit-animation-name: am-weather-stroke;
|
|
||||||
-moz-animation-name: am-weather-stroke;
|
|
||||||
animation-name: am-weather-stroke;
|
|
||||||
-webkit-animation-duration: 1.11s;
|
|
||||||
-moz-animation-duration: 1.11s;
|
|
||||||
animation-duration: 1.11s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g id="thunder" transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-lightning" transform="matrix(1.2,0,0,1.2,-4,28)">
|
|
||||||
<polygon class="am-weather-stroke" points="11.1 6.9 14.3 -2.9 20.5 -2.9 16.4 4.3 20.3 4.3 11.5 14.6 14.9 6.9"
|
|
||||||
fill="#ffa500" stroke="#fff"
|
|
||||||
style="-moz-animation-duration:1.11s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-stroke;-moz-animation-timing-function:linear;-webkit-animation-duration:1.11s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-stroke;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 13 KiB |
@ -1,283 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<!-- Scattered Thunderstorms | Contributed by hsoJ95 on GitHub: https://github.com/hsoj95 -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.1975" width="1.403" height="1.4766">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-3 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(-5px, 0px);
|
|
||||||
-moz-transform: translate(-5px, 0px);
|
|
||||||
-ms-transform: translate(-5px, 0px);
|
|
||||||
transform: translate(-5px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(10px, 0px);
|
|
||||||
-moz-transform: translate(10px, 0px);
|
|
||||||
-ms-transform: translate(10px, 0px);
|
|
||||||
transform: translate(10px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(-5px, 0px);
|
|
||||||
-moz-transform: translate(-5px, 0px);
|
|
||||||
-ms-transform: translate(-5px, 0px);
|
|
||||||
transform: translate(-5px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-3 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-3;
|
|
||||||
-moz-animation-name: am-weather-cloud-3;
|
|
||||||
animation-name: am-weather-cloud-3;
|
|
||||||
-webkit-animation-duration: 7s;
|
|
||||||
-moz-animation-duration: 7s;
|
|
||||||
animation-duration: 7s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** STROKE
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-stroke {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
2% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
4% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
6% {
|
|
||||||
-webkit-transform: translate(0.5px, 0.4px);
|
|
||||||
-moz-transform: translate(0.5px, 0.4px);
|
|
||||||
-ms-transform: translate(0.5px, 0.4px);
|
|
||||||
transform: translate(0.5px, 0.4px);
|
|
||||||
}
|
|
||||||
|
|
||||||
8% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
10% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
12% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
14% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
16% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
18% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
20% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
22% {
|
|
||||||
-webkit-transform: translate(1px, 0.0px);
|
|
||||||
-moz-transform: translate(1px, 0.0px);
|
|
||||||
-ms-transform: translate(1px, 0.0px);
|
|
||||||
transform: translate(1px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
24% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
26% {
|
|
||||||
-webkit-transform: translate(-1px, 0.0px);
|
|
||||||
-moz-transform: translate(-1px, 0.0px);
|
|
||||||
-ms-transform: translate(-1px, 0.0px);
|
|
||||||
transform: translate(-1px, 0.0px);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
28% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
40% {
|
|
||||||
fill: orange;
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
65% {
|
|
||||||
fill: white;
|
|
||||||
-webkit-transform: translate(-1px, 5.0px);
|
|
||||||
-moz-transform: translate(-1px, 5.0px);
|
|
||||||
-ms-transform: translate(-1px, 5.0px);
|
|
||||||
transform: translate(-1px, 5.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
61% {
|
|
||||||
fill: orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-stroke {
|
|
||||||
-webkit-animation-name: am-weather-stroke;
|
|
||||||
-moz-animation-name: am-weather-stroke;
|
|
||||||
animation-name: am-weather-stroke;
|
|
||||||
-webkit-animation-duration: 1.11s;
|
|
||||||
-moz-animation-duration: 1.11s;
|
|
||||||
animation-duration: 1.11s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g id="thunder" transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="3.3 1.5 4 2.7 5.2 3.3 4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="3.3 1.5 4 2.7 5.2 3.3 4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-lightning" transform="matrix(1.2,0,0,1.2,-4,28)">
|
|
||||||
<polygon class="am-weather-stroke" points="11.1 6.9 14.3 -2.9 20.5 -2.9 16.4 4.3 20.3 4.3 11.5 14.6 14.9 6.9"
|
|
||||||
fill="#ffa500" stroke="#fff"
|
|
||||||
style="-moz-animation-duration:1.11s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-stroke;-moz-animation-timing-function:linear;-webkit-animation-duration:1.11s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-stroke;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 11 KiB |
@ -1,307 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<!-- Severe Thunderstorm | Contributed by hsoJ95 on GitHub: https://github.com/hsoj95 -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.17571" y="-.19575" width="1.3379" height="1.4959">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-3 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(-5px, 0px);
|
|
||||||
-moz-transform: translate(-5px, 0px);
|
|
||||||
-ms-transform: translate(-5px, 0px);
|
|
||||||
transform: translate(-5px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(10px, 0px);
|
|
||||||
-moz-transform: translate(10px, 0px);
|
|
||||||
-ms-transform: translate(10px, 0px);
|
|
||||||
transform: translate(10px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(-5px, 0px);
|
|
||||||
-moz-transform: translate(-5px, 0px);
|
|
||||||
-ms-transform: translate(-5px, 0px);
|
|
||||||
transform: translate(-5px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-3 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-3;
|
|
||||||
-moz-animation-name: am-weather-cloud-3;
|
|
||||||
animation-name: am-weather-cloud-3;
|
|
||||||
-webkit-animation-duration: 7s;
|
|
||||||
-moz-animation-duration: 7s;
|
|
||||||
animation-duration: 7s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-cloud-1 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-1 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-1;
|
|
||||||
-moz-animation-name: am-weather-cloud-1;
|
|
||||||
animation-name: am-weather-cloud-1;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** STROKE
|
|
||||||
*/
|
|
||||||
|
|
||||||
@keyframes am-weather-stroke {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
2% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
4% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
6% {
|
|
||||||
-webkit-transform: translate(0.5px, 0.4px);
|
|
||||||
-moz-transform: translate(0.5px, 0.4px);
|
|
||||||
-ms-transform: translate(0.5px, 0.4px);
|
|
||||||
transform: translate(0.5px, 0.4px);
|
|
||||||
}
|
|
||||||
|
|
||||||
8% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
10% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
12% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
14% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
16% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
18% {
|
|
||||||
-webkit-transform: translate(0.3px, 0.0px);
|
|
||||||
-moz-transform: translate(0.3px, 0.0px);
|
|
||||||
-ms-transform: translate(0.3px, 0.0px);
|
|
||||||
transform: translate(0.3px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
20% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
22% {
|
|
||||||
-webkit-transform: translate(1px, 0.0px);
|
|
||||||
-moz-transform: translate(1px, 0.0px);
|
|
||||||
-ms-transform: translate(1px, 0.0px);
|
|
||||||
transform: translate(1px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
24% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
26% {
|
|
||||||
-webkit-transform: translate(-1px, 0.0px);
|
|
||||||
-moz-transform: translate(-1px, 0.0px);
|
|
||||||
-ms-transform: translate(-1px, 0.0px);
|
|
||||||
transform: translate(-1px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
28% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
40% {
|
|
||||||
fill: orange;
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
65% {
|
|
||||||
fill: white;
|
|
||||||
-webkit-transform: translate(-1px, 5.0px);
|
|
||||||
-moz-transform: translate(-1px, 5.0px);
|
|
||||||
-ms-transform: translate(-1px, 5.0px);
|
|
||||||
transform: translate(-1px, 5.0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
61% {
|
|
||||||
fill: orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0.0px, 0.0px);
|
|
||||||
-moz-transform: translate(0.0px, 0.0px);
|
|
||||||
-ms-transform: translate(0.0px, 0.0px);
|
|
||||||
transform: translate(0.0px, 0.0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-stroke {
|
|
||||||
-webkit-animation-name: am-weather-stroke;
|
|
||||||
-moz-animation-name: am-weather-stroke;
|
|
||||||
animation-name: am-weather-stroke;
|
|
||||||
-webkit-animation-duration: 1.11s;
|
|
||||||
-moz-animation-duration: 1.11s;
|
|
||||||
animation-duration: 1.11s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes error {
|
|
||||||
0% {
|
|
||||||
fill: #cc0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
fill: #ff0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
fill: #cc0000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#Shape {
|
|
||||||
-webkit-animation-name: error;
|
|
||||||
-moz-animation-name: error;
|
|
||||||
animation-name: error;
|
|
||||||
-webkit-animation-duration: 1s;
|
|
||||||
-moz-animation-duration: 1s;
|
|
||||||
animation-duration: 1s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g class="am-weather-cloud-1"
|
|
||||||
style="-moz-animation-duration:7s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-1;-moz-animation-timing-function:linear;-webkit-animation-duration:7s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-1;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="matrix(.6 0 0 .6 -10 -6)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#666" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#333" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g transform="matrix(1.2,0,0,1.2,-4,28)">
|
|
||||||
<polygon class="am-weather-stroke"
|
|
||||||
points="11.1 6.9 14.3 -2.9 20.5 -2.9 16.4 4.3 20.3 4.3 11.5 14.6 14.9 6.9" fill="#ffa500" stroke="#fff"
|
|
||||||
style="-moz-animation-duration:1.11s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-stroke;-moz-animation-timing-function:linear;-webkit-animation-duration:1.11s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-stroke;-webkit-animation-timing-function:linear" />
|
|
||||||
</g>
|
|
||||||
<g class="warning" transform="translate(20,30)">
|
|
||||||
<path
|
|
||||||
d="m7.7791 2.906-5.9912 10.117c-0.56283 0.95042-0.24862 2.1772 0.7018 2.74 0.30853 0.18271 0.66051 0.27911 1.0191 0.27911h11.982c1.1046 0 2-0.89543 2-2 0-0.35857-0.0964-0.71056-0.27911-1.0191l-5.9912-10.117c-0.56283-0.95042-1.7896-1.2646-2.74-0.7018-0.28918 0.17125-0.53055 0.41262-0.7018 0.7018z"
|
|
||||||
fill="#c00" />
|
|
||||||
<path d="m9.5 10.5v-5" stroke="#fff" stroke-linecap="round" stroke-width="1.5" />
|
|
||||||
<circle cx="9.5" cy="13" r="1" fill="#fff" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 13 KiB |
@ -1,241 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.23099" width="1.403" height="1.5634">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-sun-shiny {
|
|
||||||
0% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
stroke-dasharray: 0.1px 10px;
|
|
||||||
stroke-dashoffset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun-shiny line {
|
|
||||||
-webkit-animation-name: am-weather-sun-shiny;
|
|
||||||
-moz-animation-name: am-weather-sun-shiny;
|
|
||||||
-ms-animation-name: am-weather-sun-shiny;
|
|
||||||
animation-name: am-weather-sun-shiny;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SNOW
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-snow {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
transform: translateX(-1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(1.4px) translateY(4px);
|
|
||||||
transform: translateX(1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
transform: translateX(-1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-1 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun" transform="translate(0,16)"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-1"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(12,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 9.6 KiB |
@ -1,269 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.23099" width="1.403" height="1.5634">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SNOW
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-snow {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
transform: translateX(-1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(1.4px) translateY(4px);
|
|
||||||
transform: translateX(1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
transform: translateX(-1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-1 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-1"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(12,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 11 KiB |
@ -1,273 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.23099" width="1.403" height="1.5634">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-sun-shiny {
|
|
||||||
0% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
stroke-dasharray: 0.1px 10px;
|
|
||||||
stroke-dashoffset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun-shiny line {
|
|
||||||
-webkit-animation-name: am-weather-sun-shiny;
|
|
||||||
-moz-animation-name: am-weather-sun-shiny;
|
|
||||||
-ms-animation-name: am-weather-sun-shiny;
|
|
||||||
animation-name: am-weather-sun-shiny;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SNOW
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-snow {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
transform: translateX(-1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(1.4px) translateY(4px);
|
|
||||||
transform: translateX(1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
transform: translateX(-1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-1 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-2 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-delay: 1.2s;
|
|
||||||
-moz-animation-delay: 1.2s;
|
|
||||||
-ms-animation-delay: 1.2s;
|
|
||||||
animation-delay: 1.2s;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round" stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-1"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(7,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-2"
|
|
||||||
style="-moz-animation-delay:1.2s;-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-delay:1.2s;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-delay:1.2s;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(16,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 11 KiB |
@ -1,301 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.20655" y="-.23099" width="1.403" height="1.5634">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SNOW
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-snow {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
transform: translateX(-1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(1.4px) translateY(4px);
|
|
||||||
transform: translateX(1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
transform: translateX(-1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-1 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-2 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-delay: 1.2s;
|
|
||||||
-moz-animation-delay: 1.2s;
|
|
||||||
-ms-animation-delay: 1.2s;
|
|
||||||
animation-delay: 1.2s;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-3"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-1"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(7,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-2"
|
|
||||||
style="-moz-animation-delay:1.2s;-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-delay:1.2s;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-delay:1.2s;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(16,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 13 KiB |
@ -1,334 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.24684" y="-.26897" width="1.4937" height="1.6759">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SUN
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-sun {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
-moz-transform: rotate(360deg);
|
|
||||||
-ms-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun {
|
|
||||||
-webkit-animation-name: am-weather-sun;
|
|
||||||
-moz-animation-name: am-weather-sun;
|
|
||||||
-ms-animation-name: am-weather-sun;
|
|
||||||
animation-name: am-weather-sun;
|
|
||||||
-webkit-animation-duration: 9s;
|
|
||||||
-moz-animation-duration: 9s;
|
|
||||||
-ms-animation-duration: 9s;
|
|
||||||
animation-duration: 9s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-sun-shiny {
|
|
||||||
0% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
stroke-dasharray: 0.1px 10px;
|
|
||||||
stroke-dashoffset: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
stroke-dasharray: 3px 10px;
|
|
||||||
stroke-dashoffset: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-sun-shiny line {
|
|
||||||
-webkit-animation-name: am-weather-sun-shiny;
|
|
||||||
-moz-animation-name: am-weather-sun-shiny;
|
|
||||||
-ms-animation-name: am-weather-sun-shiny;
|
|
||||||
animation-name: am-weather-sun-shiny;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SNOW
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-snow {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
transform: translateX(-1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(1.4px) translateY(4px);
|
|
||||||
transform: translateX(1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
transform: translateX(-1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-snow-reverse {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(1.2px) translateY(2px);
|
|
||||||
transform: translateX(1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(-1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(-1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(-1.4px) translateY(4px);
|
|
||||||
transform: translateX(-1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(1.6px) translateY(6px);
|
|
||||||
transform: translateX(1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-1 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-2 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-delay: 1.2s;
|
|
||||||
-moz-animation-delay: 1.2s;
|
|
||||||
-ms-animation-delay: 1.2s;
|
|
||||||
animation-delay: 1.2s;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-3 {
|
|
||||||
-webkit-animation-name: am-weather-snow-reverse;
|
|
||||||
-moz-animation-name: am-weather-snow-reverse;
|
|
||||||
-ms-animation-name: am-weather-snow-reverse;
|
|
||||||
animation-name: am-weather-snow-reverse;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="translate(0,16)">
|
|
||||||
<g class="am-weather-sun"
|
|
||||||
style="-moz-animation-duration:9s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-sun;-moz-animation-timing-function:linear;-ms-animation-duration:9s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-sun;-ms-animation-timing-function:linear;-webkit-animation-duration:9s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-sun;-webkit-animation-timing-function:linear">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
<g transform="rotate(45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(135)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="scale(-1)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(225)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-90)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g transform="rotate(-45)">
|
|
||||||
<line transform="translate(0,9)" y2="3" fill="none" stroke="#ffa500" stroke-linecap="round"
|
|
||||||
stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<circle r="5" fill="#ffa500" stroke="#ffa500" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-2"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-1"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(3,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-2"
|
|
||||||
style="-moz-animation-delay:1.2s;-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-delay:1.2s;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-delay:1.2s;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(11,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-3"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow-reverse;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow-reverse;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow-reverse;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(20,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 15 KiB |
@ -1,361 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- (c) ammap.com | SVG weather icons -->
|
|
||||||
<svg width="56" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<defs>
|
|
||||||
<filter id="blur" x="-.24684" y="-.26897" width="1.4937" height="1.6759">
|
|
||||||
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
|
|
||||||
<feOffset dx="0" dy="4" result="offsetblur" />
|
|
||||||
<feComponentTransfer>
|
|
||||||
<feFuncA slope="0.05" type="linear" />
|
|
||||||
</feComponentTransfer>
|
|
||||||
<feMerge>
|
|
||||||
<feMergeNode />
|
|
||||||
<feMergeNode in="SourceGraphic" />
|
|
||||||
</feMerge>
|
|
||||||
</filter>
|
|
||||||
<style type="text/css">
|
|
||||||
<![CDATA[
|
|
||||||
/*
|
|
||||||
** CLOUDS
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-cloud-2 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: translate(2px, 0px);
|
|
||||||
-moz-transform: translate(2px, 0px);
|
|
||||||
-ms-transform: translate(2px, 0px);
|
|
||||||
transform: translate(2px, 0px);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translate(0px, 0px);
|
|
||||||
-moz-transform: translate(0px, 0px);
|
|
||||||
-ms-transform: translate(0px, 0px);
|
|
||||||
transform: translate(0px, 0px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-cloud-2 {
|
|
||||||
-webkit-animation-name: am-weather-cloud-2;
|
|
||||||
-moz-animation-name: am-weather-cloud-2;
|
|
||||||
animation-name: am-weather-cloud-2;
|
|
||||||
-webkit-animation-duration: 3s;
|
|
||||||
-moz-animation-duration: 3s;
|
|
||||||
animation-duration: 3s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** MOON
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-moon {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
-webkit-transform: rotate(15deg);
|
|
||||||
-moz-transform: rotate(15deg);
|
|
||||||
-ms-transform: rotate(15deg);
|
|
||||||
transform: rotate(15deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
-ms-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon {
|
|
||||||
-webkit-animation-name: am-weather-moon;
|
|
||||||
-moz-animation-name: am-weather-moon;
|
|
||||||
-ms-animation-name: am-weather-moon;
|
|
||||||
animation-name: am-weather-moon;
|
|
||||||
-webkit-animation-duration: 6s;
|
|
||||||
-moz-animation-duration: 6s;
|
|
||||||
-ms-animation-duration: 6s;
|
|
||||||
animation-duration: 6s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
-webkit-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-moz-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
-ms-transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
transform-origin: 12.5px 15.15px 0;
|
|
||||||
/* TODO FF CENTER ISSUE */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-1 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-1 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-1;
|
|
||||||
-moz-animation-name: am-weather-moon-star-1;
|
|
||||||
-ms-animation-name: am-weather-moon-star-1;
|
|
||||||
animation-name: am-weather-moon-star-1;
|
|
||||||
-webkit-animation-delay: 3s;
|
|
||||||
-moz-animation-delay: 3s;
|
|
||||||
-ms-animation-delay: 3s;
|
|
||||||
animation-delay: 3s;
|
|
||||||
-webkit-animation-duration: 5s;
|
|
||||||
-moz-animation-duration: 5s;
|
|
||||||
-ms-animation-duration: 5s;
|
|
||||||
animation-duration: 5s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-moon-star-2 {
|
|
||||||
0% {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-moon-star-2 {
|
|
||||||
-webkit-animation-name: am-weather-moon-star-2;
|
|
||||||
-moz-animation-name: am-weather-moon-star-2;
|
|
||||||
-ms-animation-name: am-weather-moon-star-2;
|
|
||||||
animation-name: am-weather-moon-star-2;
|
|
||||||
-webkit-animation-delay: 5s;
|
|
||||||
-moz-animation-delay: 5s;
|
|
||||||
-ms-animation-delay: 5s;
|
|
||||||
animation-delay: 5s;
|
|
||||||
-webkit-animation-duration: 4s;
|
|
||||||
-moz-animation-duration: 4s;
|
|
||||||
-ms-animation-duration: 4s;
|
|
||||||
animation-duration: 4s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: 1;
|
|
||||||
-moz-animation-iteration-count: 1;
|
|
||||||
-ms-animation-iteration-count: 1;
|
|
||||||
animation-iteration-count: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** SNOW
|
|
||||||
*/
|
|
||||||
@keyframes am-weather-snow {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(-1.2px) translateY(2px);
|
|
||||||
transform: translateX(-1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(1.4px) translateY(4px);
|
|
||||||
transform: translateX(1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(-1.6px) translateY(6px);
|
|
||||||
transform: translateX(-1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes am-weather-snow-reverse {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: translateX(0) translateY(0);
|
|
||||||
-moz-transform: translateX(0) translateY(0);
|
|
||||||
-ms-transform: translateX(0) translateY(0);
|
|
||||||
transform: translateX(0) translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
33.33% {
|
|
||||||
-webkit-transform: translateX(1.2px) translateY(2px);
|
|
||||||
-moz-transform: translateX(1.2px) translateY(2px);
|
|
||||||
-ms-transform: translateX(1.2px) translateY(2px);
|
|
||||||
transform: translateX(1.2px) translateY(2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
66.66% {
|
|
||||||
-webkit-transform: translateX(-1.4px) translateY(4px);
|
|
||||||
-moz-transform: translateX(-1.4px) translateY(4px);
|
|
||||||
-ms-transform: translateX(-1.4px) translateY(4px);
|
|
||||||
transform: translateX(-1.4px) translateY(4px);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: translateX(1.6px) translateY(6px);
|
|
||||||
-moz-transform: translateX(1.6px) translateY(6px);
|
|
||||||
-ms-transform: translateX(1.6px) translateY(6px);
|
|
||||||
transform: translateX(1.6px) translateY(6px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-1 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-2 {
|
|
||||||
-webkit-animation-name: am-weather-snow;
|
|
||||||
-moz-animation-name: am-weather-snow;
|
|
||||||
-ms-animation-name: am-weather-snow;
|
|
||||||
animation-name: am-weather-snow;
|
|
||||||
-webkit-animation-delay: 1.2s;
|
|
||||||
-moz-animation-delay: 1.2s;
|
|
||||||
-ms-animation-delay: 1.2s;
|
|
||||||
animation-delay: 1.2s;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.am-weather-snow-3 {
|
|
||||||
-webkit-animation-name: am-weather-snow-reverse;
|
|
||||||
-moz-animation-name: am-weather-snow-reverse;
|
|
||||||
-ms-animation-name: am-weather-snow-reverse;
|
|
||||||
animation-name: am-weather-snow-reverse;
|
|
||||||
-webkit-animation-duration: 2s;
|
|
||||||
-moz-animation-duration: 2s;
|
|
||||||
-ms-animation-duration: 2s;
|
|
||||||
animation-duration: 2s;
|
|
||||||
-webkit-animation-timing-function: linear;
|
|
||||||
-moz-animation-timing-function: linear;
|
|
||||||
-ms-animation-timing-function: linear;
|
|
||||||
animation-timing-function: linear;
|
|
||||||
-webkit-animation-iteration-count: infinite;
|
|
||||||
-moz-animation-iteration-count: infinite;
|
|
||||||
-ms-animation-iteration-count: infinite;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g transform="translate(16,-2)" filter="url(#blur)">
|
|
||||||
<g transform="matrix(.8 0 0 .8 16 4)">
|
|
||||||
<g class="am-weather-moon-star-1"
|
|
||||||
style="-moz-animation-delay:3s;-moz-animation-duration:5s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-1;-moz-animation-timing-function:linear;-ms-animation-delay:3s;-ms-animation-duration:5s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-1;-ms-animation-timing-function:linear;-webkit-animation-delay:3s;-webkit-animation-duration:5s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-1;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3" fill="#ffa500"
|
|
||||||
stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon-star-2"
|
|
||||||
style="-moz-animation-delay:5s;-moz-animation-duration:4s;-moz-animation-iteration-count:1;-moz-animation-name:am-weather-moon-star-2;-moz-animation-timing-function:linear;-ms-animation-delay:5s;-ms-animation-duration:4s;-ms-animation-iteration-count:1;-ms-animation-name:am-weather-moon-star-2;-ms-animation-timing-function:linear;-webkit-animation-delay:5s;-webkit-animation-duration:4s;-webkit-animation-iteration-count:1;-webkit-animation-name:am-weather-moon-star-2;-webkit-animation-timing-function:linear">
|
|
||||||
<polygon transform="translate(20,10)" points="4 4 3.3 5.2 2.7 4 1.5 3.3 2.7 2.7 3.3 1.5 4 2.7 5.2 3.3"
|
|
||||||
fill="#ffa500" stroke-miterlimit="10" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-moon"
|
|
||||||
style="-moz-animation-duration:6s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-moon;-moz-animation-timing-function:linear;-moz-transform-origin:12.5px 15.15px 0;-ms-animation-duration:6s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-moon;-ms-animation-timing-function:linear;-ms-transform-origin:12.5px 15.15px 0;-webkit-animation-duration:6s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-moon;-webkit-animation-timing-function:linear;-webkit-transform-origin:12.5px 15.15px 0">
|
|
||||||
<path
|
|
||||||
d="m14.5 13.2c0-3.7 2-6.9 5-8.7-1.5-0.9-3.2-1.3-5-1.3-5.5 0-10 4.5-10 10s4.5 10 10 10c1.8 0 3.5-0.5 5-1.3-3-1.7-5-5-5-8.7z"
|
|
||||||
fill="#ffa500" stroke="#ffa500" stroke-linejoin="round" stroke-width="2" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-cloud-2"
|
|
||||||
style="-moz-animation-duration:3s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-cloud-2;-moz-animation-timing-function:linear;-webkit-animation-duration:3s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-cloud-2;-webkit-animation-timing-function:linear">
|
|
||||||
<path transform="translate(-20,-11)"
|
|
||||||
d="m47.7 35.4c0-4.6-3.7-8.2-8.2-8.2-1 0-1.9 0.2-2.8 0.5-0.3-3.4-3.1-6.2-6.6-6.2-3.7 0-6.7 3-6.7 6.7 0 0.8 0.2 1.6 0.4 2.3-0.3-0.1-0.7-0.1-1-0.1-3.7 0-6.7 3-6.7 6.7 0 3.6 2.9 6.6 6.5 6.7h17.2c4.4-0.5 7.9-4 7.9-8.4z"
|
|
||||||
fill="#57a0ee" stroke="#fff" stroke-linejoin="round" stroke-width="1.2" />
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-1"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(3,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-2"
|
|
||||||
style="-moz-animation-delay:1.2s;-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow;-moz-animation-timing-function:linear;-ms-animation-delay:1.2s;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow;-ms-animation-timing-function:linear;-webkit-animation-delay:1.2s;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(11,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g class="am-weather-snow-3"
|
|
||||||
style="-moz-animation-duration:2s;-moz-animation-iteration-count:infinite;-moz-animation-name:am-weather-snow-reverse;-moz-animation-timing-function:linear;-ms-animation-duration:2s;-ms-animation-iteration-count:infinite;-ms-animation-name:am-weather-snow-reverse;-ms-animation-timing-function:linear;-webkit-animation-duration:2s;-webkit-animation-iteration-count:infinite;-webkit-animation-name:am-weather-snow-reverse;-webkit-animation-timing-function:linear">
|
|
||||||
<g transform="translate(20,28)" fill="none" stroke="#57a0ee" stroke-linecap="round">
|
|
||||||
<line transform="translate(0,9)" y1="-2.5" y2="2.5" stroke-width="1.2" />
|
|
||||||
<line transform="rotate(45,-10.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(90,-4.5,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
<line transform="rotate(135,-1.864,4.5)" y1="-2.5" y2="2.5" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 17 KiB |
@ -1,4 +1,5 @@
|
|||||||
[GENERAL]
|
[GENERAL]
|
||||||
|
PORT = 3001 # Port to run the server on
|
||||||
SIMILARITY_MEASURE = "cosine" # "cosine" or "dot"
|
SIMILARITY_MEASURE = "cosine" # "cosine" or "dot"
|
||||||
KEEP_ALIVE = "5m" # How long to keep Ollama models loaded into memory. (Instead of using -1 use "-1m")
|
KEEP_ALIVE = "5m" # How long to keep Ollama models loaded into memory. (Instead of using -1 use "-1m")
|
||||||
|
|
||||||
@ -22,11 +23,5 @@ MODEL_NAME = ""
|
|||||||
[MODELS.OLLAMA]
|
[MODELS.OLLAMA]
|
||||||
API_URL = "" # Ollama API URL - http://host.docker.internal:11434
|
API_URL = "" # Ollama API URL - http://host.docker.internal:11434
|
||||||
|
|
||||||
[MODELS.DEEPSEEK]
|
|
||||||
API_KEY = ""
|
|
||||||
|
|
||||||
[MODELS.LM_STUDIO]
|
|
||||||
API_URL = "" # LM Studio API URL - http://host.docker.internal:1234
|
|
||||||
|
|
||||||
[API_ENDPOINTS]
|
[API_ENDPOINTS]
|
||||||
SEARXNG = "" # SearxNG API URL - http://localhost:32768
|
SEARXNG = "http://localhost:32768" # SearxNG API URL
|
38
src/app.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { startWebSocketServer } from './websocket';
|
||||||
|
import express from 'express';
|
||||||
|
import cors from 'cors';
|
||||||
|
import http from 'http';
|
||||||
|
import routes from './routes';
|
||||||
|
import { getPort } from './config';
|
||||||
|
import logger from './utils/logger';
|
||||||
|
|
||||||
|
const port = getPort();
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const server = http.createServer(app);
|
||||||
|
|
||||||
|
const corsOptions = {
|
||||||
|
origin: '*',
|
||||||
|
};
|
||||||
|
|
||||||
|
app.use(cors(corsOptions));
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
app.use('/api', routes);
|
||||||
|
app.get('/api', (_, res) => {
|
||||||
|
res.status(200).json({ status: 'ok' });
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(port, () => {
|
||||||
|
logger.info(`Server is running on port ${port}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
startWebSocketServer(server);
|
||||||
|
|
||||||
|
process.on('uncaughtException', (err, origin) => {
|
||||||
|
logger.error(`Uncaught Exception at ${origin}: ${err}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, promise) => {
|
||||||
|
logger.error(`Unhandled Rejection at: ${promise}, reason: ${reason}`);
|
||||||
|
});
|
@ -1,306 +0,0 @@
|
|||||||
import prompts from '@/lib/prompts';
|
|
||||||
import MetaSearchAgent from '@/lib/search/metaSearchAgent';
|
|
||||||
import crypto from 'crypto';
|
|
||||||
import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
||||||
import { EventEmitter } from 'stream';
|
|
||||||
import {
|
|
||||||
chatModelProviders,
|
|
||||||
embeddingModelProviders,
|
|
||||||
getAvailableChatModelProviders,
|
|
||||||
getAvailableEmbeddingModelProviders,
|
|
||||||
} from '@/lib/providers';
|
|
||||||
import db from '@/lib/db';
|
|
||||||
import { chats, messages as messagesSchema } from '@/lib/db/schema';
|
|
||||||
import { and, eq, gt } from 'drizzle-orm';
|
|
||||||
import { getFileDetails } from '@/lib/utils/files';
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
|
||||||
import {
|
|
||||||
getCustomOpenaiApiKey,
|
|
||||||
getCustomOpenaiApiUrl,
|
|
||||||
getCustomOpenaiModelName,
|
|
||||||
} from '@/lib/config';
|
|
||||||
import { searchHandlers } from '@/lib/search';
|
|
||||||
|
|
||||||
export const runtime = 'nodejs';
|
|
||||||
export const dynamic = 'force-dynamic';
|
|
||||||
|
|
||||||
type Message = {
|
|
||||||
messageId: string;
|
|
||||||
chatId: string;
|
|
||||||
content: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ChatModel = {
|
|
||||||
provider: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type EmbeddingModel = {
|
|
||||||
provider: string;
|
|
||||||
name: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Body = {
|
|
||||||
message: Message;
|
|
||||||
optimizationMode: 'speed' | 'balanced' | 'quality';
|
|
||||||
focusMode: string;
|
|
||||||
history: Array<[string, string]>;
|
|
||||||
files: Array<string>;
|
|
||||||
chatModel: ChatModel;
|
|
||||||
embeddingModel: EmbeddingModel;
|
|
||||||
systemInstructions: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEmitterEvents = async (
|
|
||||||
stream: EventEmitter,
|
|
||||||
writer: WritableStreamDefaultWriter,
|
|
||||||
encoder: TextEncoder,
|
|
||||||
aiMessageId: string,
|
|
||||||
chatId: string,
|
|
||||||
) => {
|
|
||||||
let recievedMessage = '';
|
|
||||||
let sources: any[] = [];
|
|
||||||
|
|
||||||
stream.on('data', (data) => {
|
|
||||||
const parsedData = JSON.parse(data);
|
|
||||||
if (parsedData.type === 'response') {
|
|
||||||
writer.write(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
data: parsedData.data,
|
|
||||||
messageId: aiMessageId,
|
|
||||||
}) + '\n',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
recievedMessage += parsedData.data;
|
|
||||||
} else if (parsedData.type === 'sources') {
|
|
||||||
writer.write(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'sources',
|
|
||||||
data: parsedData.data,
|
|
||||||
messageId: aiMessageId,
|
|
||||||
}) + '\n',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
sources = parsedData.data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stream.on('end', () => {
|
|
||||||
writer.write(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'messageEnd',
|
|
||||||
messageId: aiMessageId,
|
|
||||||
}) + '\n',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
writer.close();
|
|
||||||
|
|
||||||
db.insert(messagesSchema)
|
|
||||||
.values({
|
|
||||||
content: recievedMessage,
|
|
||||||
chatId: chatId,
|
|
||||||
messageId: aiMessageId,
|
|
||||||
role: 'assistant',
|
|
||||||
metadata: JSON.stringify({
|
|
||||||
createdAt: new Date(),
|
|
||||||
...(sources && sources.length > 0 && { sources }),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.execute();
|
|
||||||
});
|
|
||||||
stream.on('error', (data) => {
|
|
||||||
const parsedData = JSON.parse(data);
|
|
||||||
writer.write(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'error',
|
|
||||||
data: parsedData.data,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
writer.close();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleHistorySave = async (
|
|
||||||
message: Message,
|
|
||||||
humanMessageId: string,
|
|
||||||
focusMode: string,
|
|
||||||
files: string[],
|
|
||||||
) => {
|
|
||||||
const chat = await db.query.chats.findFirst({
|
|
||||||
where: eq(chats.id, message.chatId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!chat) {
|
|
||||||
await db
|
|
||||||
.insert(chats)
|
|
||||||
.values({
|
|
||||||
id: message.chatId,
|
|
||||||
title: message.content,
|
|
||||||
createdAt: new Date().toString(),
|
|
||||||
focusMode: focusMode,
|
|
||||||
files: files.map(getFileDetails),
|
|
||||||
})
|
|
||||||
.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
const messageExists = await db.query.messages.findFirst({
|
|
||||||
where: eq(messagesSchema.messageId, humanMessageId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!messageExists) {
|
|
||||||
await db
|
|
||||||
.insert(messagesSchema)
|
|
||||||
.values({
|
|
||||||
content: message.content,
|
|
||||||
chatId: message.chatId,
|
|
||||||
messageId: humanMessageId,
|
|
||||||
role: 'user',
|
|
||||||
metadata: JSON.stringify({
|
|
||||||
createdAt: new Date(),
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.execute();
|
|
||||||
} else {
|
|
||||||
await db
|
|
||||||
.delete(messagesSchema)
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
gt(messagesSchema.id, messageExists.id),
|
|
||||||
eq(messagesSchema.chatId, message.chatId),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.execute();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const POST = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const body = (await req.json()) as Body;
|
|
||||||
const { message } = body;
|
|
||||||
|
|
||||||
if (message.content === '') {
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
message: 'Please provide a message to process',
|
|
||||||
},
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
|
|
||||||
getAvailableChatModelProviders(),
|
|
||||||
getAvailableEmbeddingModelProviders(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const chatModelProvider =
|
|
||||||
chatModelProviders[
|
|
||||||
body.chatModel?.provider || Object.keys(chatModelProviders)[0]
|
|
||||||
];
|
|
||||||
const chatModel =
|
|
||||||
chatModelProvider[
|
|
||||||
body.chatModel?.name || Object.keys(chatModelProvider)[0]
|
|
||||||
];
|
|
||||||
|
|
||||||
const embeddingProvider =
|
|
||||||
embeddingModelProviders[
|
|
||||||
body.embeddingModel?.provider || Object.keys(embeddingModelProviders)[0]
|
|
||||||
];
|
|
||||||
const embeddingModel =
|
|
||||||
embeddingProvider[
|
|
||||||
body.embeddingModel?.name || Object.keys(embeddingProvider)[0]
|
|
||||||
];
|
|
||||||
|
|
||||||
let llm: BaseChatModel | undefined;
|
|
||||||
let embedding = embeddingModel.model;
|
|
||||||
|
|
||||||
if (body.chatModel?.provider === 'custom_openai') {
|
|
||||||
llm = new ChatOpenAI({
|
|
||||||
openAIApiKey: getCustomOpenaiApiKey(),
|
|
||||||
modelName: getCustomOpenaiModelName(),
|
|
||||||
temperature: 0.7,
|
|
||||||
configuration: {
|
|
||||||
baseURL: getCustomOpenaiApiUrl(),
|
|
||||||
},
|
|
||||||
}) as unknown as BaseChatModel;
|
|
||||||
} else if (chatModelProvider && chatModel) {
|
|
||||||
llm = chatModel.model;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!llm) {
|
|
||||||
return Response.json({ error: 'Invalid chat model' }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!embedding) {
|
|
||||||
return Response.json(
|
|
||||||
{ error: 'Invalid embedding model' },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const humanMessageId =
|
|
||||||
message.messageId ?? crypto.randomBytes(7).toString('hex');
|
|
||||||
const aiMessageId = crypto.randomBytes(7).toString('hex');
|
|
||||||
|
|
||||||
const history: BaseMessage[] = body.history.map((msg) => {
|
|
||||||
if (msg[0] === 'human') {
|
|
||||||
return new HumanMessage({
|
|
||||||
content: msg[1],
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return new AIMessage({
|
|
||||||
content: msg[1],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const handler = searchHandlers[body.focusMode];
|
|
||||||
|
|
||||||
if (!handler) {
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
message: 'Invalid focus mode',
|
|
||||||
},
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const stream = await handler.searchAndAnswer(
|
|
||||||
message.content,
|
|
||||||
history,
|
|
||||||
llm,
|
|
||||||
embedding,
|
|
||||||
body.optimizationMode,
|
|
||||||
body.files,
|
|
||||||
body.systemInstructions,
|
|
||||||
);
|
|
||||||
|
|
||||||
const responseStream = new TransformStream();
|
|
||||||
const writer = responseStream.writable.getWriter();
|
|
||||||
const encoder = new TextEncoder();
|
|
||||||
|
|
||||||
handleEmitterEvents(stream, writer, encoder, aiMessageId, message.chatId);
|
|
||||||
handleHistorySave(message, humanMessageId, body.focusMode, body.files);
|
|
||||||
|
|
||||||
return new Response(responseStream.readable, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'text/event-stream',
|
|
||||||
Connection: 'keep-alive',
|
|
||||||
'Cache-Control': 'no-cache, no-transform',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
console.error('An error occurred while processing chat request:', err);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error occurred while processing chat request' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,69 +0,0 @@
|
|||||||
import db from '@/lib/db';
|
|
||||||
import { chats, messages } from '@/lib/db/schema';
|
|
||||||
import { eq } from 'drizzle-orm';
|
|
||||||
|
|
||||||
export const GET = async (
|
|
||||||
req: Request,
|
|
||||||
{ params }: { params: Promise<{ id: string }> },
|
|
||||||
) => {
|
|
||||||
try {
|
|
||||||
const { id } = await params;
|
|
||||||
|
|
||||||
const chatExists = await db.query.chats.findFirst({
|
|
||||||
where: eq(chats.id, id),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!chatExists) {
|
|
||||||
return Response.json({ message: 'Chat not found' }, { status: 404 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const chatMessages = await db.query.messages.findMany({
|
|
||||||
where: eq(messages.chatId, id),
|
|
||||||
});
|
|
||||||
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
chat: chatExists,
|
|
||||||
messages: chatMessages,
|
|
||||||
},
|
|
||||||
{ status: 200 },
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error in getting chat by id: ', err);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error has occurred.' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DELETE = async (
|
|
||||||
req: Request,
|
|
||||||
{ params }: { params: Promise<{ id: string }> },
|
|
||||||
) => {
|
|
||||||
try {
|
|
||||||
const { id } = await params;
|
|
||||||
|
|
||||||
const chatExists = await db.query.chats.findFirst({
|
|
||||||
where: eq(chats.id, id),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!chatExists) {
|
|
||||||
return Response.json({ message: 'Chat not found' }, { status: 404 });
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.delete(chats).where(eq(chats.id, id)).execute();
|
|
||||||
await db.delete(messages).where(eq(messages.chatId, id)).execute();
|
|
||||||
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'Chat deleted successfully' },
|
|
||||||
{ status: 200 },
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error in deleting chat by id: ', err);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error has occurred.' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
import db from '@/lib/db';
|
|
||||||
|
|
||||||
export const GET = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
let chats = await db.query.chats.findMany();
|
|
||||||
chats = chats.reverse();
|
|
||||||
return Response.json({ chats: chats }, { status: 200 });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error in getting chats: ', err);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error has occurred.' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,119 +0,0 @@
|
|||||||
import {
|
|
||||||
getAnthropicApiKey,
|
|
||||||
getCustomOpenaiApiKey,
|
|
||||||
getCustomOpenaiApiUrl,
|
|
||||||
getCustomOpenaiModelName,
|
|
||||||
getGeminiApiKey,
|
|
||||||
getGroqApiKey,
|
|
||||||
getOllamaApiEndpoint,
|
|
||||||
getOpenaiApiKey,
|
|
||||||
getDeepseekApiKey,
|
|
||||||
getLMStudioApiEndpoint,
|
|
||||||
updateConfig,
|
|
||||||
} from '@/lib/config';
|
|
||||||
import {
|
|
||||||
getAvailableChatModelProviders,
|
|
||||||
getAvailableEmbeddingModelProviders,
|
|
||||||
} from '@/lib/providers';
|
|
||||||
|
|
||||||
export const GET = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const config: Record<string, any> = {};
|
|
||||||
|
|
||||||
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
|
|
||||||
getAvailableChatModelProviders(),
|
|
||||||
getAvailableEmbeddingModelProviders(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
config['chatModelProviders'] = {};
|
|
||||||
config['embeddingModelProviders'] = {};
|
|
||||||
|
|
||||||
for (const provider in chatModelProviders) {
|
|
||||||
config['chatModelProviders'][provider] = Object.keys(
|
|
||||||
chatModelProviders[provider],
|
|
||||||
).map((model) => {
|
|
||||||
return {
|
|
||||||
name: model,
|
|
||||||
displayName: chatModelProviders[provider][model].displayName,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const provider in embeddingModelProviders) {
|
|
||||||
config['embeddingModelProviders'][provider] = Object.keys(
|
|
||||||
embeddingModelProviders[provider],
|
|
||||||
).map((model) => {
|
|
||||||
return {
|
|
||||||
name: model,
|
|
||||||
displayName: embeddingModelProviders[provider][model].displayName,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
config['openaiApiKey'] = getOpenaiApiKey();
|
|
||||||
config['ollamaApiUrl'] = getOllamaApiEndpoint();
|
|
||||||
config['lmStudioApiUrl'] = getLMStudioApiEndpoint();
|
|
||||||
config['anthropicApiKey'] = getAnthropicApiKey();
|
|
||||||
config['groqApiKey'] = getGroqApiKey();
|
|
||||||
config['geminiApiKey'] = getGeminiApiKey();
|
|
||||||
config['deepseekApiKey'] = getDeepseekApiKey();
|
|
||||||
config['customOpenaiApiUrl'] = getCustomOpenaiApiUrl();
|
|
||||||
config['customOpenaiApiKey'] = getCustomOpenaiApiKey();
|
|
||||||
config['customOpenaiModelName'] = getCustomOpenaiModelName();
|
|
||||||
|
|
||||||
return Response.json({ ...config }, { status: 200 });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('An error occurred while getting config:', err);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error occurred while getting config' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const POST = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const config = await req.json();
|
|
||||||
|
|
||||||
const updatedConfig = {
|
|
||||||
MODELS: {
|
|
||||||
OPENAI: {
|
|
||||||
API_KEY: config.openaiApiKey,
|
|
||||||
},
|
|
||||||
GROQ: {
|
|
||||||
API_KEY: config.groqApiKey,
|
|
||||||
},
|
|
||||||
ANTHROPIC: {
|
|
||||||
API_KEY: config.anthropicApiKey,
|
|
||||||
},
|
|
||||||
GEMINI: {
|
|
||||||
API_KEY: config.geminiApiKey,
|
|
||||||
},
|
|
||||||
OLLAMA: {
|
|
||||||
API_URL: config.ollamaApiUrl,
|
|
||||||
},
|
|
||||||
DEEPSEEK: {
|
|
||||||
API_KEY: config.deepseekApiKey,
|
|
||||||
},
|
|
||||||
LM_STUDIO: {
|
|
||||||
API_URL: config.lmStudioApiUrl,
|
|
||||||
},
|
|
||||||
CUSTOM_OPENAI: {
|
|
||||||
API_URL: config.customOpenaiApiUrl,
|
|
||||||
API_KEY: config.customOpenaiApiKey,
|
|
||||||
MODEL_NAME: config.customOpenaiModelName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
updateConfig(updatedConfig);
|
|
||||||
|
|
||||||
return Response.json({ message: 'Config updated' }, { status: 200 });
|
|
||||||
} catch (err) {
|
|
||||||
console.error('An error occurred while updating config:', err);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error occurred while updating config' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,76 +0,0 @@
|
|||||||
import { searchSearxng } from '@/lib/searxng';
|
|
||||||
|
|
||||||
const articleWebsites = [
|
|
||||||
'yahoo.com',
|
|
||||||
'www.exchangewire.com',
|
|
||||||
'businessinsider.com',
|
|
||||||
/* 'wired.com',
|
|
||||||
'mashable.com',
|
|
||||||
'theverge.com',
|
|
||||||
'gizmodo.com',
|
|
||||||
'cnet.com',
|
|
||||||
'venturebeat.com', */
|
|
||||||
];
|
|
||||||
|
|
||||||
const topics = ['AI', 'tech']; /* TODO: Add UI to customize this */
|
|
||||||
|
|
||||||
export const GET = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const params = new URL(req.url).searchParams;
|
|
||||||
const mode: 'normal' | 'preview' =
|
|
||||||
(params.get('mode') as 'normal' | 'preview') || 'normal';
|
|
||||||
|
|
||||||
let data = [];
|
|
||||||
|
|
||||||
if (mode === 'normal') {
|
|
||||||
data = (
|
|
||||||
await Promise.all([
|
|
||||||
...new Array(articleWebsites.length * topics.length)
|
|
||||||
.fill(0)
|
|
||||||
.map(async (_, i) => {
|
|
||||||
return (
|
|
||||||
await searchSearxng(
|
|
||||||
`site:${articleWebsites[i % articleWebsites.length]} ${
|
|
||||||
topics[i % topics.length]
|
|
||||||
}`,
|
|
||||||
{
|
|
||||||
engines: ['bing news'],
|
|
||||||
pageno: 1,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
).results;
|
|
||||||
}),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
.map((result) => result)
|
|
||||||
.flat()
|
|
||||||
.sort(() => Math.random() - 0.5);
|
|
||||||
} else {
|
|
||||||
data = (
|
|
||||||
await searchSearxng(
|
|
||||||
`site:${articleWebsites[Math.floor(Math.random() * articleWebsites.length)]} ${topics[Math.floor(Math.random() * topics.length)]}`,
|
|
||||||
{ engines: ['bing news'], pageno: 1 },
|
|
||||||
)
|
|
||||||
).results;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
blogs: data,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
status: 200,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`An error occurred in discover route: ${err}`);
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
message: 'An error has occurred',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
status: 500,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,83 +0,0 @@
|
|||||||
import handleImageSearch from '@/lib/chains/imageSearchAgent';
|
|
||||||
import {
|
|
||||||
getCustomOpenaiApiKey,
|
|
||||||
getCustomOpenaiApiUrl,
|
|
||||||
getCustomOpenaiModelName,
|
|
||||||
} from '@/lib/config';
|
|
||||||
import { getAvailableChatModelProviders } from '@/lib/providers';
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
|
||||||
|
|
||||||
interface ChatModel {
|
|
||||||
provider: string;
|
|
||||||
model: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ImageSearchBody {
|
|
||||||
query: string;
|
|
||||||
chatHistory: any[];
|
|
||||||
chatModel?: ChatModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const POST = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const body: ImageSearchBody = await req.json();
|
|
||||||
|
|
||||||
const chatHistory = body.chatHistory
|
|
||||||
.map((msg: any) => {
|
|
||||||
if (msg.role === 'user') {
|
|
||||||
return new HumanMessage(msg.content);
|
|
||||||
} else if (msg.role === 'assistant') {
|
|
||||||
return new AIMessage(msg.content);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter((msg) => msg !== undefined) as BaseMessage[];
|
|
||||||
|
|
||||||
const chatModelProviders = await getAvailableChatModelProviders();
|
|
||||||
|
|
||||||
const chatModelProvider =
|
|
||||||
chatModelProviders[
|
|
||||||
body.chatModel?.provider || Object.keys(chatModelProviders)[0]
|
|
||||||
];
|
|
||||||
const chatModel =
|
|
||||||
chatModelProvider[
|
|
||||||
body.chatModel?.model || Object.keys(chatModelProvider)[0]
|
|
||||||
];
|
|
||||||
|
|
||||||
let llm: BaseChatModel | undefined;
|
|
||||||
|
|
||||||
if (body.chatModel?.provider === 'custom_openai') {
|
|
||||||
llm = new ChatOpenAI({
|
|
||||||
openAIApiKey: getCustomOpenaiApiKey(),
|
|
||||||
modelName: getCustomOpenaiModelName(),
|
|
||||||
temperature: 0.7,
|
|
||||||
configuration: {
|
|
||||||
baseURL: getCustomOpenaiApiUrl(),
|
|
||||||
},
|
|
||||||
}) as unknown as BaseChatModel;
|
|
||||||
} else if (chatModelProvider && chatModel) {
|
|
||||||
llm = chatModel.model;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!llm) {
|
|
||||||
return Response.json({ error: 'Invalid chat model' }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const images = await handleImageSearch(
|
|
||||||
{
|
|
||||||
chat_history: chatHistory,
|
|
||||||
query: body.query,
|
|
||||||
},
|
|
||||||
llm,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Response.json({ images }, { status: 200 });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`An error occurred while searching images: ${err}`);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error occurred while searching images' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,47 +0,0 @@
|
|||||||
import {
|
|
||||||
getAvailableChatModelProviders,
|
|
||||||
getAvailableEmbeddingModelProviders,
|
|
||||||
} from '@/lib/providers';
|
|
||||||
|
|
||||||
export const GET = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
|
|
||||||
getAvailableChatModelProviders(),
|
|
||||||
getAvailableEmbeddingModelProviders(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
Object.keys(chatModelProviders).forEach((provider) => {
|
|
||||||
Object.keys(chatModelProviders[provider]).forEach((model) => {
|
|
||||||
delete (chatModelProviders[provider][model] as { model?: unknown })
|
|
||||||
.model;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(embeddingModelProviders).forEach((provider) => {
|
|
||||||
Object.keys(embeddingModelProviders[provider]).forEach((model) => {
|
|
||||||
delete (embeddingModelProviders[provider][model] as { model?: unknown })
|
|
||||||
.model;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
chatModelProviders,
|
|
||||||
embeddingModelProviders,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
status: 200,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('An error occurred while fetching models', err);
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
message: 'An error has occurred.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
status: 500,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,270 +0,0 @@
|
|||||||
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import type { Embeddings } from '@langchain/core/embeddings';
|
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
|
||||||
import {
|
|
||||||
getAvailableChatModelProviders,
|
|
||||||
getAvailableEmbeddingModelProviders,
|
|
||||||
} from '@/lib/providers';
|
|
||||||
import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
||||||
import { MetaSearchAgentType } from '@/lib/search/metaSearchAgent';
|
|
||||||
import {
|
|
||||||
getCustomOpenaiApiKey,
|
|
||||||
getCustomOpenaiApiUrl,
|
|
||||||
getCustomOpenaiModelName,
|
|
||||||
} from '@/lib/config';
|
|
||||||
import { searchHandlers } from '@/lib/search';
|
|
||||||
|
|
||||||
interface chatModel {
|
|
||||||
provider: string;
|
|
||||||
name: string;
|
|
||||||
customOpenAIKey?: string;
|
|
||||||
customOpenAIBaseURL?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface embeddingModel {
|
|
||||||
provider: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ChatRequestBody {
|
|
||||||
optimizationMode: 'speed' | 'balanced';
|
|
||||||
focusMode: string;
|
|
||||||
chatModel?: chatModel;
|
|
||||||
embeddingModel?: embeddingModel;
|
|
||||||
query: string;
|
|
||||||
history: Array<[string, string]>;
|
|
||||||
stream?: boolean;
|
|
||||||
systemInstructions?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const POST = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const body: ChatRequestBody = await req.json();
|
|
||||||
|
|
||||||
if (!body.focusMode || !body.query) {
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'Missing focus mode or query' },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
body.history = body.history || [];
|
|
||||||
body.optimizationMode = body.optimizationMode || 'balanced';
|
|
||||||
body.stream = body.stream || false;
|
|
||||||
|
|
||||||
const history: BaseMessage[] = body.history.map((msg) => {
|
|
||||||
return msg[0] === 'human'
|
|
||||||
? new HumanMessage({ content: msg[1] })
|
|
||||||
: new AIMessage({ content: msg[1] });
|
|
||||||
});
|
|
||||||
|
|
||||||
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
|
|
||||||
getAvailableChatModelProviders(),
|
|
||||||
getAvailableEmbeddingModelProviders(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const chatModelProvider =
|
|
||||||
body.chatModel?.provider || Object.keys(chatModelProviders)[0];
|
|
||||||
const chatModel =
|
|
||||||
body.chatModel?.name ||
|
|
||||||
Object.keys(chatModelProviders[chatModelProvider])[0];
|
|
||||||
|
|
||||||
const embeddingModelProvider =
|
|
||||||
body.embeddingModel?.provider || Object.keys(embeddingModelProviders)[0];
|
|
||||||
const embeddingModel =
|
|
||||||
body.embeddingModel?.name ||
|
|
||||||
Object.keys(embeddingModelProviders[embeddingModelProvider])[0];
|
|
||||||
|
|
||||||
let llm: BaseChatModel | undefined;
|
|
||||||
let embeddings: Embeddings | undefined;
|
|
||||||
|
|
||||||
if (body.chatModel?.provider === 'custom_openai') {
|
|
||||||
llm = new ChatOpenAI({
|
|
||||||
modelName: body.chatModel?.name || getCustomOpenaiModelName(),
|
|
||||||
openAIApiKey:
|
|
||||||
body.chatModel?.customOpenAIKey || getCustomOpenaiApiKey(),
|
|
||||||
temperature: 0.7,
|
|
||||||
configuration: {
|
|
||||||
baseURL:
|
|
||||||
body.chatModel?.customOpenAIBaseURL || getCustomOpenaiApiUrl(),
|
|
||||||
},
|
|
||||||
}) as unknown as BaseChatModel;
|
|
||||||
} else if (
|
|
||||||
chatModelProviders[chatModelProvider] &&
|
|
||||||
chatModelProviders[chatModelProvider][chatModel]
|
|
||||||
) {
|
|
||||||
llm = chatModelProviders[chatModelProvider][chatModel]
|
|
||||||
.model as unknown as BaseChatModel | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
embeddingModelProviders[embeddingModelProvider] &&
|
|
||||||
embeddingModelProviders[embeddingModelProvider][embeddingModel]
|
|
||||||
) {
|
|
||||||
embeddings = embeddingModelProviders[embeddingModelProvider][
|
|
||||||
embeddingModel
|
|
||||||
].model as Embeddings | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!llm || !embeddings) {
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'Invalid model selected' },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const searchHandler: MetaSearchAgentType = searchHandlers[body.focusMode];
|
|
||||||
|
|
||||||
if (!searchHandler) {
|
|
||||||
return Response.json({ message: 'Invalid focus mode' }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const emitter = await searchHandler.searchAndAnswer(
|
|
||||||
body.query,
|
|
||||||
history,
|
|
||||||
llm,
|
|
||||||
embeddings,
|
|
||||||
body.optimizationMode,
|
|
||||||
[],
|
|
||||||
body.systemInstructions || '',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!body.stream) {
|
|
||||||
return new Promise(
|
|
||||||
(
|
|
||||||
resolve: (value: Response) => void,
|
|
||||||
reject: (value: Response) => void,
|
|
||||||
) => {
|
|
||||||
let message = '';
|
|
||||||
let sources: any[] = [];
|
|
||||||
|
|
||||||
emitter.on('data', (data: string) => {
|
|
||||||
try {
|
|
||||||
const parsedData = JSON.parse(data);
|
|
||||||
if (parsedData.type === 'response') {
|
|
||||||
message += parsedData.data;
|
|
||||||
} else if (parsedData.type === 'sources') {
|
|
||||||
sources = parsedData.data;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
reject(
|
|
||||||
Response.json(
|
|
||||||
{ message: 'Error parsing data' },
|
|
||||||
{ status: 500 },
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
emitter.on('end', () => {
|
|
||||||
resolve(Response.json({ message, sources }, { status: 200 }));
|
|
||||||
});
|
|
||||||
|
|
||||||
emitter.on('error', (error: any) => {
|
|
||||||
reject(
|
|
||||||
Response.json(
|
|
||||||
{ message: 'Search error', error },
|
|
||||||
{ status: 500 },
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const encoder = new TextEncoder();
|
|
||||||
|
|
||||||
const abortController = new AbortController();
|
|
||||||
const { signal } = abortController;
|
|
||||||
|
|
||||||
const stream = new ReadableStream({
|
|
||||||
start(controller) {
|
|
||||||
let sources: any[] = [];
|
|
||||||
|
|
||||||
controller.enqueue(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'init',
|
|
||||||
data: 'Stream connected',
|
|
||||||
}) + '\n',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
signal.addEventListener('abort', () => {
|
|
||||||
emitter.removeAllListeners();
|
|
||||||
|
|
||||||
try {
|
|
||||||
controller.close();
|
|
||||||
} catch (error) {}
|
|
||||||
});
|
|
||||||
|
|
||||||
emitter.on('data', (data: string) => {
|
|
||||||
if (signal.aborted) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const parsedData = JSON.parse(data);
|
|
||||||
|
|
||||||
if (parsedData.type === 'response') {
|
|
||||||
controller.enqueue(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'response',
|
|
||||||
data: parsedData.data,
|
|
||||||
}) + '\n',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (parsedData.type === 'sources') {
|
|
||||||
sources = parsedData.data;
|
|
||||||
controller.enqueue(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'sources',
|
|
||||||
data: sources,
|
|
||||||
}) + '\n',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
controller.error(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
emitter.on('end', () => {
|
|
||||||
if (signal.aborted) return;
|
|
||||||
|
|
||||||
controller.enqueue(
|
|
||||||
encoder.encode(
|
|
||||||
JSON.stringify({
|
|
||||||
type: 'done',
|
|
||||||
}) + '\n',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
controller.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
emitter.on('error', (error: any) => {
|
|
||||||
if (signal.aborted) return;
|
|
||||||
|
|
||||||
controller.error(error);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
cancel() {
|
|
||||||
abortController.abort();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return new Response(stream, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'text/event-stream',
|
|
||||||
'Cache-Control': 'no-cache, no-transform',
|
|
||||||
Connection: 'keep-alive',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (err: any) {
|
|
||||||
console.error(`Error in getting search results: ${err.message}`);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error has occurred.' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,81 +0,0 @@
|
|||||||
import generateSuggestions from '@/lib/chains/suggestionGeneratorAgent';
|
|
||||||
import {
|
|
||||||
getCustomOpenaiApiKey,
|
|
||||||
getCustomOpenaiApiUrl,
|
|
||||||
getCustomOpenaiModelName,
|
|
||||||
} from '@/lib/config';
|
|
||||||
import { getAvailableChatModelProviders } from '@/lib/providers';
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
|
||||||
|
|
||||||
interface ChatModel {
|
|
||||||
provider: string;
|
|
||||||
model: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SuggestionsGenerationBody {
|
|
||||||
chatHistory: any[];
|
|
||||||
chatModel?: ChatModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const POST = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const body: SuggestionsGenerationBody = await req.json();
|
|
||||||
|
|
||||||
const chatHistory = body.chatHistory
|
|
||||||
.map((msg: any) => {
|
|
||||||
if (msg.role === 'user') {
|
|
||||||
return new HumanMessage(msg.content);
|
|
||||||
} else if (msg.role === 'assistant') {
|
|
||||||
return new AIMessage(msg.content);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter((msg) => msg !== undefined) as BaseMessage[];
|
|
||||||
|
|
||||||
const chatModelProviders = await getAvailableChatModelProviders();
|
|
||||||
|
|
||||||
const chatModelProvider =
|
|
||||||
chatModelProviders[
|
|
||||||
body.chatModel?.provider || Object.keys(chatModelProviders)[0]
|
|
||||||
];
|
|
||||||
const chatModel =
|
|
||||||
chatModelProvider[
|
|
||||||
body.chatModel?.model || Object.keys(chatModelProvider)[0]
|
|
||||||
];
|
|
||||||
|
|
||||||
let llm: BaseChatModel | undefined;
|
|
||||||
|
|
||||||
if (body.chatModel?.provider === 'custom_openai') {
|
|
||||||
llm = new ChatOpenAI({
|
|
||||||
openAIApiKey: getCustomOpenaiApiKey(),
|
|
||||||
modelName: getCustomOpenaiModelName(),
|
|
||||||
temperature: 0.7,
|
|
||||||
configuration: {
|
|
||||||
baseURL: getCustomOpenaiApiUrl(),
|
|
||||||
},
|
|
||||||
}) as unknown as BaseChatModel;
|
|
||||||
} else if (chatModelProvider && chatModel) {
|
|
||||||
llm = chatModel.model;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!llm) {
|
|
||||||
return Response.json({ error: 'Invalid chat model' }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const suggestions = await generateSuggestions(
|
|
||||||
{
|
|
||||||
chat_history: chatHistory,
|
|
||||||
},
|
|
||||||
llm,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Response.json({ suggestions }, { status: 200 });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`An error occurred while generating suggestions: ${err}`);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error occurred while generating suggestions' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,134 +0,0 @@
|
|||||||
import { NextResponse } from 'next/server';
|
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import crypto from 'crypto';
|
|
||||||
import { getAvailableEmbeddingModelProviders } from '@/lib/providers';
|
|
||||||
import { PDFLoader } from '@langchain/community/document_loaders/fs/pdf';
|
|
||||||
import { DocxLoader } from '@langchain/community/document_loaders/fs/docx';
|
|
||||||
import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';
|
|
||||||
import { Document } from 'langchain/document';
|
|
||||||
|
|
||||||
interface FileRes {
|
|
||||||
fileName: string;
|
|
||||||
fileExtension: string;
|
|
||||||
fileId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uploadDir = path.join(process.cwd(), 'uploads');
|
|
||||||
|
|
||||||
if (!fs.existsSync(uploadDir)) {
|
|
||||||
fs.mkdirSync(uploadDir, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const splitter = new RecursiveCharacterTextSplitter({
|
|
||||||
chunkSize: 500,
|
|
||||||
chunkOverlap: 100,
|
|
||||||
});
|
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
|
||||||
try {
|
|
||||||
const formData = await req.formData();
|
|
||||||
|
|
||||||
const files = formData.getAll('files') as File[];
|
|
||||||
const embedding_model = formData.get('embedding_model');
|
|
||||||
const embedding_model_provider = formData.get('embedding_model_provider');
|
|
||||||
|
|
||||||
if (!embedding_model || !embedding_model_provider) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ message: 'Missing embedding model or provider' },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const embeddingModels = await getAvailableEmbeddingModelProviders();
|
|
||||||
const provider =
|
|
||||||
embedding_model_provider ?? Object.keys(embeddingModels)[0];
|
|
||||||
const embeddingModel =
|
|
||||||
embedding_model ?? Object.keys(embeddingModels[provider as string])[0];
|
|
||||||
|
|
||||||
let embeddingsModel =
|
|
||||||
embeddingModels[provider as string]?.[embeddingModel as string]?.model;
|
|
||||||
if (!embeddingsModel) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ message: 'Invalid embedding model selected' },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const processedFiles: FileRes[] = [];
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
files.map(async (file: any) => {
|
|
||||||
const fileExtension = file.name.split('.').pop();
|
|
||||||
if (!['pdf', 'docx', 'txt'].includes(fileExtension!)) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ message: 'File type not supported' },
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uniqueFileName = `${crypto.randomBytes(16).toString('hex')}.${fileExtension}`;
|
|
||||||
const filePath = path.join(uploadDir, uniqueFileName);
|
|
||||||
|
|
||||||
const buffer = Buffer.from(await file.arrayBuffer());
|
|
||||||
fs.writeFileSync(filePath, new Uint8Array(buffer));
|
|
||||||
|
|
||||||
let docs: any[] = [];
|
|
||||||
if (fileExtension === 'pdf') {
|
|
||||||
const loader = new PDFLoader(filePath);
|
|
||||||
docs = await loader.load();
|
|
||||||
} else if (fileExtension === 'docx') {
|
|
||||||
const loader = new DocxLoader(filePath);
|
|
||||||
docs = await loader.load();
|
|
||||||
} else if (fileExtension === 'txt') {
|
|
||||||
const text = fs.readFileSync(filePath, 'utf-8');
|
|
||||||
docs = [
|
|
||||||
new Document({ pageContent: text, metadata: { title: file.name } }),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
const splitted = await splitter.splitDocuments(docs);
|
|
||||||
|
|
||||||
const extractedDataPath = filePath.replace(/\.\w+$/, '-extracted.json');
|
|
||||||
fs.writeFileSync(
|
|
||||||
extractedDataPath,
|
|
||||||
JSON.stringify({
|
|
||||||
title: file.name,
|
|
||||||
contents: splitted.map((doc) => doc.pageContent),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const embeddings = await embeddingsModel.embedDocuments(
|
|
||||||
splitted.map((doc) => doc.pageContent),
|
|
||||||
);
|
|
||||||
const embeddingsDataPath = filePath.replace(
|
|
||||||
/\.\w+$/,
|
|
||||||
'-embeddings.json',
|
|
||||||
);
|
|
||||||
fs.writeFileSync(
|
|
||||||
embeddingsDataPath,
|
|
||||||
JSON.stringify({
|
|
||||||
title: file.name,
|
|
||||||
embeddings,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
processedFiles.push({
|
|
||||||
fileName: file.name,
|
|
||||||
fileExtension: fileExtension,
|
|
||||||
fileId: uniqueFileName.replace(/\.\w+$/, ''),
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return NextResponse.json({
|
|
||||||
files: processedFiles,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error uploading file:', error);
|
|
||||||
return NextResponse.json(
|
|
||||||
{ message: 'An error has occurred.' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
import handleVideoSearch from '@/lib/chains/videoSearchAgent';
|
|
||||||
import {
|
|
||||||
getCustomOpenaiApiKey,
|
|
||||||
getCustomOpenaiApiUrl,
|
|
||||||
getCustomOpenaiModelName,
|
|
||||||
} from '@/lib/config';
|
|
||||||
import { getAvailableChatModelProviders } from '@/lib/providers';
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
|
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
|
||||||
|
|
||||||
interface ChatModel {
|
|
||||||
provider: string;
|
|
||||||
model: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface VideoSearchBody {
|
|
||||||
query: string;
|
|
||||||
chatHistory: any[];
|
|
||||||
chatModel?: ChatModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const POST = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const body: VideoSearchBody = await req.json();
|
|
||||||
|
|
||||||
const chatHistory = body.chatHistory
|
|
||||||
.map((msg: any) => {
|
|
||||||
if (msg.role === 'user') {
|
|
||||||
return new HumanMessage(msg.content);
|
|
||||||
} else if (msg.role === 'assistant') {
|
|
||||||
return new AIMessage(msg.content);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter((msg) => msg !== undefined) as BaseMessage[];
|
|
||||||
|
|
||||||
const chatModelProviders = await getAvailableChatModelProviders();
|
|
||||||
|
|
||||||
const chatModelProvider =
|
|
||||||
chatModelProviders[
|
|
||||||
body.chatModel?.provider || Object.keys(chatModelProviders)[0]
|
|
||||||
];
|
|
||||||
const chatModel =
|
|
||||||
chatModelProvider[
|
|
||||||
body.chatModel?.model || Object.keys(chatModelProvider)[0]
|
|
||||||
];
|
|
||||||
|
|
||||||
let llm: BaseChatModel | undefined;
|
|
||||||
|
|
||||||
if (body.chatModel?.provider === 'custom_openai') {
|
|
||||||
llm = new ChatOpenAI({
|
|
||||||
openAIApiKey: getCustomOpenaiApiKey(),
|
|
||||||
modelName: getCustomOpenaiModelName(),
|
|
||||||
temperature: 0.7,
|
|
||||||
configuration: {
|
|
||||||
baseURL: getCustomOpenaiApiUrl(),
|
|
||||||
},
|
|
||||||
}) as unknown as BaseChatModel;
|
|
||||||
} else if (chatModelProvider && chatModel) {
|
|
||||||
llm = chatModel.model;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!llm) {
|
|
||||||
return Response.json({ error: 'Invalid chat model' }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const videos = await handleVideoSearch(
|
|
||||||
{
|
|
||||||
chat_history: chatHistory,
|
|
||||||
query: body.query,
|
|
||||||
},
|
|
||||||
llm,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Response.json({ videos }, { status: 200 });
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`An error occurred while searching videos: ${err}`);
|
|
||||||
return Response.json(
|
|
||||||
{ message: 'An error occurred while searching videos' },
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,164 +0,0 @@
|
|||||||
export const POST = async (req: Request) => {
|
|
||||||
try {
|
|
||||||
const body: { lat: number; lng: number } = await req.json();
|
|
||||||
|
|
||||||
if (!body.lat || !body.lng) {
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
message: 'Invalid request.',
|
|
||||||
},
|
|
||||||
{ status: 400 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await fetch(
|
|
||||||
`https://api.open-meteo.com/v1/forecast?latitude=${body.lat}&longitude=${body.lng}¤t=weather_code,temperature_2m,is_day,relative_humidity_2m,wind_speed_10m&timezone=auto`,
|
|
||||||
);
|
|
||||||
|
|
||||||
const data = await res.json();
|
|
||||||
|
|
||||||
if (data.error) {
|
|
||||||
console.error(`Error fetching weather data: ${data.reason}`);
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
message: 'An error has occurred.',
|
|
||||||
},
|
|
||||||
{ status: 500 },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const weather: {
|
|
||||||
temperature: number;
|
|
||||||
condition: string;
|
|
||||||
humidity: number;
|
|
||||||
windSpeed: number;
|
|
||||||
icon: string;
|
|
||||||
} = {
|
|
||||||
temperature: data.current.temperature_2m,
|
|
||||||
condition: '',
|
|
||||||
humidity: data.current.relative_humidity_2m,
|
|
||||||
windSpeed: data.current.wind_speed_10m,
|
|
||||||
icon: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
const code = data.current.weather_code;
|
|
||||||
const isDay = data.current.is_day === 1;
|
|
||||||
const dayOrNight = isDay ? 'day' : 'night';
|
|
||||||
|
|
||||||
switch (code) {
|
|
||||||
case 0:
|
|
||||||
weather.icon = `clear-${dayOrNight}`;
|
|
||||||
weather.condition = 'Clear';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
weather.condition = 'Mainly Clear';
|
|
||||||
case 2:
|
|
||||||
weather.condition = 'Partly Cloudy';
|
|
||||||
case 3:
|
|
||||||
weather.icon = `cloudy-1-${dayOrNight}`;
|
|
||||||
weather.condition = 'Cloudy';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 45:
|
|
||||||
weather.condition = 'Fog';
|
|
||||||
case 48:
|
|
||||||
weather.icon = `fog-${dayOrNight}`;
|
|
||||||
weather.condition = 'Fog';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 51:
|
|
||||||
weather.condition = 'Light Drizzle';
|
|
||||||
case 53:
|
|
||||||
weather.condition = 'Moderate Drizzle';
|
|
||||||
case 55:
|
|
||||||
weather.icon = `rainy-1-${dayOrNight}`;
|
|
||||||
weather.condition = 'Dense Drizzle';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 56:
|
|
||||||
weather.condition = 'Light Freezing Drizzle';
|
|
||||||
case 57:
|
|
||||||
weather.icon = `frost-${dayOrNight}`;
|
|
||||||
weather.condition = 'Dense Freezing Drizzle';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 61:
|
|
||||||
weather.condition = 'Slight Rain';
|
|
||||||
case 63:
|
|
||||||
weather.condition = 'Moderate Rain';
|
|
||||||
case 65:
|
|
||||||
weather.condition = 'Heavy Rain';
|
|
||||||
weather.icon = `rainy-2-${dayOrNight}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 66:
|
|
||||||
weather.condition = 'Light Freezing Rain';
|
|
||||||
case 67:
|
|
||||||
weather.condition = 'Heavy Freezing Rain';
|
|
||||||
weather.icon = 'rain-and-sleet-mix';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 71:
|
|
||||||
weather.condition = 'Slight Snow Fall';
|
|
||||||
case 73:
|
|
||||||
weather.condition = 'Moderate Snow Fall';
|
|
||||||
case 75:
|
|
||||||
weather.condition = 'Heavy Snow Fall';
|
|
||||||
weather.icon = `snowy-2-${dayOrNight}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 77:
|
|
||||||
weather.condition = 'Snow';
|
|
||||||
weather.icon = `snowy-1-${dayOrNight}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 80:
|
|
||||||
weather.condition = 'Slight Rain Showers';
|
|
||||||
case 81:
|
|
||||||
weather.condition = 'Moderate Rain Showers';
|
|
||||||
case 82:
|
|
||||||
weather.condition = 'Heavy Rain Showers';
|
|
||||||
weather.icon = `rainy-3-${dayOrNight}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 85:
|
|
||||||
weather.condition = 'Slight Snow Showers';
|
|
||||||
case 86:
|
|
||||||
weather.condition = 'Moderate Snow Showers';
|
|
||||||
case 87:
|
|
||||||
weather.condition = 'Heavy Snow Showers';
|
|
||||||
weather.icon = `snowy-3-${dayOrNight}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 95:
|
|
||||||
weather.condition = 'Thunderstorm';
|
|
||||||
weather.icon = `scattered-thunderstorms-${dayOrNight}`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 96:
|
|
||||||
weather.condition = 'Thunderstorm with Slight Hail';
|
|
||||||
case 99:
|
|
||||||
weather.condition = 'Thunderstorm with Heavy Hail';
|
|
||||||
weather.icon = 'severe-thunderstorm';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
weather.icon = `clear-${dayOrNight}`;
|
|
||||||
weather.condition = 'Clear';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response.json(weather);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('An error occurred while getting home widgets', err);
|
|
||||||
return Response.json(
|
|
||||||
{
|
|
||||||
message: 'An error has occurred.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
status: 500,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,9 +0,0 @@
|
|||||||
import ChatWindow from '@/components/ChatWindow';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
const Page = ({ params }: { params: Promise<{ chatId: string }> }) => {
|
|
||||||
const { chatId } = React.use(params);
|
|
||||||
return <ChatWindow id={chatId} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Page;
|
|
@ -7,7 +7,7 @@ import { PromptTemplate } from '@langchain/core/prompts';
|
|||||||
import formatChatHistoryAsString from '../utils/formatHistory';
|
import formatChatHistoryAsString from '../utils/formatHistory';
|
||||||
import { BaseMessage } from '@langchain/core/messages';
|
import { BaseMessage } from '@langchain/core/messages';
|
||||||
import { StringOutputParser } from '@langchain/core/output_parsers';
|
import { StringOutputParser } from '@langchain/core/output_parsers';
|
||||||
import { searchSearxng } from '../searxng';
|
import { searchSearxng } from '../lib/searxng';
|
||||||
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||||
|
|
||||||
const imageSearchChainPrompt = `
|
const imageSearchChainPrompt = `
|
||||||
@ -36,12 +36,6 @@ type ImageSearchChainInput = {
|
|||||||
query: string;
|
query: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ImageSearchResult {
|
|
||||||
img_src: string;
|
|
||||||
url: string;
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const strParser = new StringOutputParser();
|
const strParser = new StringOutputParser();
|
||||||
|
|
||||||
const createImageSearchChain = (llm: BaseChatModel) => {
|
const createImageSearchChain = (llm: BaseChatModel) => {
|
||||||
@ -58,13 +52,11 @@ const createImageSearchChain = (llm: BaseChatModel) => {
|
|||||||
llm,
|
llm,
|
||||||
strParser,
|
strParser,
|
||||||
RunnableLambda.from(async (input: string) => {
|
RunnableLambda.from(async (input: string) => {
|
||||||
input = input.replace(/<think>.*?<\/think>/g, '');
|
|
||||||
|
|
||||||
const res = await searchSearxng(input, {
|
const res = await searchSearxng(input, {
|
||||||
engines: ['bing images', 'google images'],
|
engines: ['bing images', 'google images'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const images: ImageSearchResult[] = [];
|
const images = [];
|
||||||
|
|
||||||
res.results.forEach((result) => {
|
res.results.forEach((result) => {
|
||||||
if (result.img_src && result.url && result.title) {
|
if (result.img_src && result.url && result.title) {
|
@ -1,5 +1,5 @@
|
|||||||
import { RunnableSequence, RunnableMap } from '@langchain/core/runnables';
|
import { RunnableSequence, RunnableMap } from '@langchain/core/runnables';
|
||||||
import ListLineOutputParser from '../outputParsers/listLineOutputParser';
|
import ListLineOutputParser from '../lib/outputParsers/listLineOutputParser';
|
||||||
import { PromptTemplate } from '@langchain/core/prompts';
|
import { PromptTemplate } from '@langchain/core/prompts';
|
||||||
import formatChatHistoryAsString from '../utils/formatHistory';
|
import formatChatHistoryAsString from '../utils/formatHistory';
|
||||||
import { BaseMessage } from '@langchain/core/messages';
|
import { BaseMessage } from '@langchain/core/messages';
|
@ -7,7 +7,7 @@ import { PromptTemplate } from '@langchain/core/prompts';
|
|||||||
import formatChatHistoryAsString from '../utils/formatHistory';
|
import formatChatHistoryAsString from '../utils/formatHistory';
|
||||||
import { BaseMessage } from '@langchain/core/messages';
|
import { BaseMessage } from '@langchain/core/messages';
|
||||||
import { StringOutputParser } from '@langchain/core/output_parsers';
|
import { StringOutputParser } from '@langchain/core/output_parsers';
|
||||||
import { searchSearxng } from '../searxng';
|
import { searchSearxng } from '../lib/searxng';
|
||||||
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||||
|
|
||||||
const VideoSearchChainPrompt = `
|
const VideoSearchChainPrompt = `
|
||||||
@ -36,13 +36,6 @@ type VideoSearchChainInput = {
|
|||||||
query: string;
|
query: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface VideoSearchResult {
|
|
||||||
img_src: string;
|
|
||||||
url: string;
|
|
||||||
title: string;
|
|
||||||
iframe_src: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const strParser = new StringOutputParser();
|
const strParser = new StringOutputParser();
|
||||||
|
|
||||||
const createVideoSearchChain = (llm: BaseChatModel) => {
|
const createVideoSearchChain = (llm: BaseChatModel) => {
|
||||||
@ -59,13 +52,11 @@ const createVideoSearchChain = (llm: BaseChatModel) => {
|
|||||||
llm,
|
llm,
|
||||||
strParser,
|
strParser,
|
||||||
RunnableLambda.from(async (input: string) => {
|
RunnableLambda.from(async (input: string) => {
|
||||||
input = input.replace(/<think>.*?<\/think>/g, '');
|
|
||||||
|
|
||||||
const res = await searchSearxng(input, {
|
const res = await searchSearxng(input, {
|
||||||
engines: ['youtube'],
|
engines: ['youtube'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const videos: VideoSearchResult[] = [];
|
const videos = [];
|
||||||
|
|
||||||
res.results.forEach((result) => {
|
res.results.forEach((result) => {
|
||||||
if (
|
if (
|
@ -1,66 +0,0 @@
|
|||||||
import { Settings } from 'lucide-react';
|
|
||||||
import EmptyChatMessageInput from './EmptyChatMessageInput';
|
|
||||||
import { File } from './ChatWindow';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import WeatherWidget from './WeatherWidget';
|
|
||||||
import NewsArticleWidget from './NewsArticleWidget';
|
|
||||||
|
|
||||||
const EmptyChat = ({
|
|
||||||
sendMessage,
|
|
||||||
focusMode,
|
|
||||||
setFocusMode,
|
|
||||||
optimizationMode,
|
|
||||||
setOptimizationMode,
|
|
||||||
fileIds,
|
|
||||||
setFileIds,
|
|
||||||
files,
|
|
||||||
setFiles,
|
|
||||||
}: {
|
|
||||||
sendMessage: (message: string) => void;
|
|
||||||
focusMode: string;
|
|
||||||
setFocusMode: (mode: string) => void;
|
|
||||||
optimizationMode: string;
|
|
||||||
setOptimizationMode: (mode: string) => void;
|
|
||||||
fileIds: string[];
|
|
||||||
setFileIds: (fileIds: string[]) => void;
|
|
||||||
files: File[];
|
|
||||||
setFiles: (files: File[]) => void;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div className="relative">
|
|
||||||
<div className="absolute w-full flex flex-row items-center justify-end mr-5 mt-5">
|
|
||||||
<Link href="/settings">
|
|
||||||
<Settings className="cursor-pointer lg:hidden" />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center justify-center min-h-screen max-w-screen-sm mx-auto p-2 space-y-4">
|
|
||||||
<div className="flex flex-col items-center justify-center w-full space-y-8">
|
|
||||||
<h2 className="text-black/70 dark:text-white/70 text-3xl font-medium -mt-8">
|
|
||||||
Research begins here.
|
|
||||||
</h2>
|
|
||||||
<EmptyChatMessageInput
|
|
||||||
sendMessage={sendMessage}
|
|
||||||
focusMode={focusMode}
|
|
||||||
setFocusMode={setFocusMode}
|
|
||||||
optimizationMode={optimizationMode}
|
|
||||||
setOptimizationMode={setOptimizationMode}
|
|
||||||
fileIds={fileIds}
|
|
||||||
setFileIds={setFileIds}
|
|
||||||
files={files}
|
|
||||||
setFiles={setFiles}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col w-full gap-4 mt-2 sm:flex-row sm:justify-center">
|
|
||||||
<div className="flex-1 max-w-xs">
|
|
||||||
<WeatherWidget />
|
|
||||||
</div>
|
|
||||||
<div className="flex-1 max-w-xs">
|
|
||||||
<NewsArticleWidget />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EmptyChat;
|
|
@ -1,215 +0,0 @@
|
|||||||
import { Clock, Edit, Share, Trash, FileText, FileDown } from 'lucide-react';
|
|
||||||
import { Message } from './ChatWindow';
|
|
||||||
import { useEffect, useState, Fragment } from 'react';
|
|
||||||
import { formatTimeDifference } from '@/lib/utils';
|
|
||||||
import DeleteChat from './DeleteChat';
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverButton,
|
|
||||||
PopoverPanel,
|
|
||||||
Transition,
|
|
||||||
} from '@headlessui/react';
|
|
||||||
import jsPDF from 'jspdf';
|
|
||||||
|
|
||||||
const downloadFile = (filename: string, content: string, type: string) => {
|
|
||||||
const blob = new Blob([content], { type });
|
|
||||||
const url = URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
a.download = filename;
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
setTimeout(() => {
|
|
||||||
document.body.removeChild(a);
|
|
||||||
URL.revokeObjectURL(url);
|
|
||||||
}, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
const exportAsMarkdown = (messages: Message[], title: string) => {
|
|
||||||
const date = new Date(messages[0]?.createdAt || Date.now()).toLocaleString();
|
|
||||||
let md = `# 💬 Chat Export: ${title}\n\n`;
|
|
||||||
md += `*Exported on: ${date}*\n\n---\n`;
|
|
||||||
messages.forEach((msg, idx) => {
|
|
||||||
md += `\n---\n`;
|
|
||||||
md += `**${msg.role === 'user' ? '🧑 User' : '🤖 Assistant'}**
|
|
||||||
`;
|
|
||||||
md += `*${new Date(msg.createdAt).toLocaleString()}*\n\n`;
|
|
||||||
md += `> ${msg.content.replace(/\n/g, '\n> ')}\n`;
|
|
||||||
if (msg.sources && msg.sources.length > 0) {
|
|
||||||
md += `\n**Citations:**\n`;
|
|
||||||
msg.sources.forEach((src: any, i: number) => {
|
|
||||||
const url = src.metadata?.url || '';
|
|
||||||
md += `- [${i + 1}] [${url}](${url})\n`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
md += '\n---\n';
|
|
||||||
downloadFile(`${title || 'chat'}.md`, md, 'text/markdown');
|
|
||||||
};
|
|
||||||
|
|
||||||
const exportAsPDF = (messages: Message[], title: string) => {
|
|
||||||
const doc = new jsPDF();
|
|
||||||
const date = new Date(messages[0]?.createdAt || Date.now()).toLocaleString();
|
|
||||||
let y = 15;
|
|
||||||
const pageHeight = doc.internal.pageSize.height;
|
|
||||||
doc.setFontSize(18);
|
|
||||||
doc.text(`Chat Export: ${title}`, 10, y);
|
|
||||||
y += 8;
|
|
||||||
doc.setFontSize(11);
|
|
||||||
doc.setTextColor(100);
|
|
||||||
doc.text(`Exported on: ${date}`, 10, y);
|
|
||||||
y += 8;
|
|
||||||
doc.setDrawColor(200);
|
|
||||||
doc.line(10, y, 200, y);
|
|
||||||
y += 6;
|
|
||||||
doc.setTextColor(30);
|
|
||||||
messages.forEach((msg, idx) => {
|
|
||||||
if (y > pageHeight - 30) {
|
|
||||||
doc.addPage();
|
|
||||||
y = 15;
|
|
||||||
}
|
|
||||||
doc.setFont('helvetica', 'bold');
|
|
||||||
doc.text(`${msg.role === 'user' ? 'User' : 'Assistant'}`, 10, y);
|
|
||||||
doc.setFont('helvetica', 'normal');
|
|
||||||
doc.setFontSize(10);
|
|
||||||
doc.setTextColor(120);
|
|
||||||
doc.text(`${new Date(msg.createdAt).toLocaleString()}`, 40, y);
|
|
||||||
y += 6;
|
|
||||||
doc.setTextColor(30);
|
|
||||||
doc.setFontSize(12);
|
|
||||||
const lines = doc.splitTextToSize(msg.content, 180);
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
if (y > pageHeight - 20) {
|
|
||||||
doc.addPage();
|
|
||||||
y = 15;
|
|
||||||
}
|
|
||||||
doc.text(lines[i], 12, y);
|
|
||||||
y += 6;
|
|
||||||
}
|
|
||||||
if (msg.sources && msg.sources.length > 0) {
|
|
||||||
doc.setFontSize(11);
|
|
||||||
doc.setTextColor(80);
|
|
||||||
if (y > pageHeight - 20) {
|
|
||||||
doc.addPage();
|
|
||||||
y = 15;
|
|
||||||
}
|
|
||||||
doc.text('Citations:', 12, y);
|
|
||||||
y += 5;
|
|
||||||
msg.sources.forEach((src: any, i: number) => {
|
|
||||||
const url = src.metadata?.url || '';
|
|
||||||
if (y > pageHeight - 15) {
|
|
||||||
doc.addPage();
|
|
||||||
y = 15;
|
|
||||||
}
|
|
||||||
doc.text(`- [${i + 1}] ${url}`, 15, y);
|
|
||||||
y += 5;
|
|
||||||
});
|
|
||||||
doc.setTextColor(30);
|
|
||||||
}
|
|
||||||
y += 6;
|
|
||||||
doc.setDrawColor(230);
|
|
||||||
if (y > pageHeight - 10) {
|
|
||||||
doc.addPage();
|
|
||||||
y = 15;
|
|
||||||
}
|
|
||||||
doc.line(10, y, 200, y);
|
|
||||||
y += 4;
|
|
||||||
});
|
|
||||||
doc.save(`${title || 'chat'}.pdf`);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Navbar = ({
|
|
||||||
chatId,
|
|
||||||
messages,
|
|
||||||
}: {
|
|
||||||
messages: Message[];
|
|
||||||
chatId: string;
|
|
||||||
}) => {
|
|
||||||
const [title, setTitle] = useState<string>('');
|
|
||||||
const [timeAgo, setTimeAgo] = useState<string>('');
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (messages.length > 0) {
|
|
||||||
const newTitle =
|
|
||||||
messages[0].content.length > 20
|
|
||||||
? `${messages[0].content.substring(0, 20).trim()}...`
|
|
||||||
: messages[0].content;
|
|
||||||
setTitle(newTitle);
|
|
||||||
const newTimeAgo = formatTimeDifference(
|
|
||||||
new Date(),
|
|
||||||
messages[0].createdAt,
|
|
||||||
);
|
|
||||||
setTimeAgo(newTimeAgo);
|
|
||||||
}
|
|
||||||
}, [messages]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const intervalId = setInterval(() => {
|
|
||||||
if (messages.length > 0) {
|
|
||||||
const newTimeAgo = formatTimeDifference(
|
|
||||||
new Date(),
|
|
||||||
messages[0].createdAt,
|
|
||||||
);
|
|
||||||
setTimeAgo(newTimeAgo);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
return () => clearInterval(intervalId);
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="fixed z-40 top-0 left-0 right-0 px-4 lg:pl-[104px] lg:pr-6 lg:px-8 flex flex-row items-center justify-between w-full py-4 text-sm text-black dark:text-white/70 border-b bg-light-primary dark:bg-dark-primary border-light-100 dark:border-dark-200">
|
|
||||||
<a
|
|
||||||
href="/"
|
|
||||||
className="active:scale-95 transition duration-100 cursor-pointer lg:hidden"
|
|
||||||
>
|
|
||||||
<Edit size={17} />
|
|
||||||
</a>
|
|
||||||
<div className="hidden lg:flex flex-row items-center justify-center space-x-2">
|
|
||||||
<Clock size={17} />
|
|
||||||
<p className="text-xs">{timeAgo} ago</p>
|
|
||||||
</div>
|
|
||||||
<p className="hidden lg:flex">{title}</p>
|
|
||||||
|
|
||||||
<div className="flex flex-row items-center space-x-4">
|
|
||||||
<Popover className="relative">
|
|
||||||
<PopoverButton className="active:scale-95 transition duration-100 cursor-pointer p-2 rounded-full hover:bg-light-secondary dark:hover:bg-dark-secondary">
|
|
||||||
<Share size={17} />
|
|
||||||
</PopoverButton>
|
|
||||||
<Transition
|
|
||||||
as={Fragment}
|
|
||||||
enter="transition ease-out duration-100"
|
|
||||||
enterFrom="opacity-0 translate-y-1"
|
|
||||||
enterTo="opacity-100 translate-y-0"
|
|
||||||
leave="transition ease-in duration-75"
|
|
||||||
leaveFrom="opacity-100 translate-y-0"
|
|
||||||
leaveTo="opacity-0 translate-y-1"
|
|
||||||
>
|
|
||||||
<PopoverPanel className="absolute right-0 mt-2 w-64 rounded-xl shadow-xl bg-light-primary dark:bg-dark-primary border border-light-200 dark:border-dark-200 z-50">
|
|
||||||
<div className="flex flex-col py-3 px-3 gap-2">
|
|
||||||
<button
|
|
||||||
className="flex items-center gap-2 px-4 py-2 text-left hover:bg-light-secondary dark:hover:bg-dark-secondary transition-colors text-black dark:text-white rounded-lg font-medium"
|
|
||||||
onClick={() => exportAsMarkdown(messages, title || '')}
|
|
||||||
>
|
|
||||||
<FileText size={17} className="text-[#24A0ED]" />
|
|
||||||
Export as Markdown
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="flex items-center gap-2 px-4 py-2 text-left hover:bg-light-secondary dark:hover:bg-dark-secondary transition-colors text-black dark:text-white rounded-lg font-medium"
|
|
||||||
onClick={() => exportAsPDF(messages, title || '')}
|
|
||||||
>
|
|
||||||
<FileDown size={17} className="text-[#24A0ED]" />
|
|
||||||
Export as PDF
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</PopoverPanel>
|
|
||||||
</Transition>
|
|
||||||
</Popover>
|
|
||||||
<DeleteChat redirect chatId={chatId} chats={[]} setChats={() => {}} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Navbar;
|
|
@ -1,71 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
interface Article {
|
|
||||||
title: string;
|
|
||||||
content: string;
|
|
||||||
url: string;
|
|
||||||
thumbnail: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const NewsArticleWidget = () => {
|
|
||||||
const [article, setArticle] = useState<Article | null>(null);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [error, setError] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetch('/api/discover?mode=preview')
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => {
|
|
||||||
const articles = (data.blogs || []).filter((a: Article) => a.thumbnail);
|
|
||||||
setArticle(articles[Math.floor(Math.random() * articles.length)]);
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setError(true);
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="bg-light-secondary dark:bg-dark-secondary rounded-xl border border-light-200 dark:border-dark-200 shadow-sm flex flex-row items-center w-full h-24 min-h-[96px] max-h-[96px] px-3 py-2 gap-3 overflow-hidden">
|
|
||||||
{loading ? (
|
|
||||||
<>
|
|
||||||
<div className="animate-pulse flex flex-row items-center w-full h-full">
|
|
||||||
<div className="rounded-lg w-16 min-w-16 max-w-16 h-16 min-h-16 max-h-16 bg-light-200 dark:bg-dark-200 mr-3" />
|
|
||||||
<div className="flex flex-col justify-center flex-1 h-full w-0 gap-2">
|
|
||||||
<div className="h-4 w-3/4 rounded bg-light-200 dark:bg-dark-200" />
|
|
||||||
<div className="h-3 w-1/2 rounded bg-light-200 dark:bg-dark-200" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : error ? (
|
|
||||||
<div className="w-full text-xs text-red-400">Could not load news.</div>
|
|
||||||
) : article ? (
|
|
||||||
<a
|
|
||||||
href={`/?q=Summary: ${article.url}`}
|
|
||||||
className="flex flex-row items-center w-full h-full group"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
className="object-cover rounded-lg w-16 min-w-16 max-w-16 h-16 min-h-16 max-h-16 border border-light-200 dark:border-dark-200 bg-light-200 dark:bg-dark-200 group-hover:opacity-90 transition"
|
|
||||||
src={
|
|
||||||
new URL(article.thumbnail).origin +
|
|
||||||
new URL(article.thumbnail).pathname +
|
|
||||||
`?id=${new URL(article.thumbnail).searchParams.get('id')}`
|
|
||||||
}
|
|
||||||
alt={article.title}
|
|
||||||
/>
|
|
||||||
<div className="flex flex-col justify-center flex-1 h-full pl-3 w-0">
|
|
||||||
<div className="font-bold text-xs text-black dark:text-white leading-tight truncate overflow-hidden whitespace-nowrap">
|
|
||||||
{article.title}
|
|
||||||
</div>
|
|
||||||
<p className="text-black/70 dark:text-white/70 text-xs leading-snug truncate overflow-hidden whitespace-nowrap">
|
|
||||||
{article.content}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default NewsArticleWidget;
|
|
@ -1,43 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import { ChevronDown, ChevronUp, BrainCircuit } from 'lucide-react';
|
|
||||||
|
|
||||||
interface ThinkBoxProps {
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ThinkBox = ({ content }: ThinkBoxProps) => {
|
|
||||||
const [isExpanded, setIsExpanded] = useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="my-4 bg-light-secondary/50 dark:bg-dark-secondary/50 rounded-xl border border-light-200 dark:border-dark-200 overflow-hidden">
|
|
||||||
<button
|
|
||||||
onClick={() => setIsExpanded(!isExpanded)}
|
|
||||||
className="w-full flex items-center justify-between px-4 py-1 text-black/90 dark:text-white/90 hover:bg-light-200 dark:hover:bg-dark-200 transition duration-200"
|
|
||||||
>
|
|
||||||
<div className="flex items-center space-x-2">
|
|
||||||
<BrainCircuit
|
|
||||||
size={20}
|
|
||||||
className="text-[#9C27B0] dark:text-[#CE93D8]"
|
|
||||||
/>
|
|
||||||
<p className="font-medium text-sm">Thinking Process</p>
|
|
||||||
</div>
|
|
||||||
{isExpanded ? (
|
|
||||||
<ChevronUp size={18} className="text-black/70 dark:text-white/70" />
|
|
||||||
) : (
|
|
||||||
<ChevronDown size={18} className="text-black/70 dark:text-white/70" />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{isExpanded && (
|
|
||||||
<div className="px-4 py-3 text-black/80 dark:text-white/80 text-sm border-t border-light-200 dark:border-dark-200 bg-light-100/50 dark:bg-dark-100/50 whitespace-pre-wrap">
|
|
||||||
{content}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ThinkBox;
|
|
@ -1,145 +0,0 @@
|
|||||||
import { Cloud, Sun, CloudRain, CloudSnow, Wind } from 'lucide-react';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
const WeatherWidget = () => {
|
|
||||||
const [data, setData] = useState({
|
|
||||||
temperature: 0,
|
|
||||||
condition: '',
|
|
||||||
location: '',
|
|
||||||
humidity: 0,
|
|
||||||
windSpeed: 0,
|
|
||||||
icon: '',
|
|
||||||
});
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const getApproxLocation = async () => {
|
|
||||||
const res = await fetch('https://ipwhois.app/json/');
|
|
||||||
const data = await res.json();
|
|
||||||
|
|
||||||
return {
|
|
||||||
latitude: data.latitude,
|
|
||||||
longitude: data.longitude,
|
|
||||||
city: data.city,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const getLocation = async (
|
|
||||||
callback: (location: {
|
|
||||||
latitude: number;
|
|
||||||
longitude: number;
|
|
||||||
city: string;
|
|
||||||
}) => void,
|
|
||||||
) => {
|
|
||||||
/*
|
|
||||||
// Geolocation doesn't give city so we'll country using ipapi for now
|
|
||||||
if (navigator.geolocation) {
|
|
||||||
const result = await navigator.permissions.query({
|
|
||||||
name: 'geolocation',
|
|
||||||
})
|
|
||||||
|
|
||||||
if (result.state === 'granted') {
|
|
||||||
navigator.geolocation.getCurrentPosition(position => {
|
|
||||||
callback({
|
|
||||||
latitude: position.coords.latitude,
|
|
||||||
longitude: position.coords.longitude,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else if (result.state === 'prompt') {
|
|
||||||
callback(await getApproxLocation())
|
|
||||||
navigator.geolocation.getCurrentPosition(position => {})
|
|
||||||
} else if (result.state === 'denied') {
|
|
||||||
callback(await getApproxLocation())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(await getApproxLocation())
|
|
||||||
} */
|
|
||||||
callback(await getApproxLocation());
|
|
||||||
};
|
|
||||||
|
|
||||||
getLocation(async (location) => {
|
|
||||||
const res = await fetch(`/api/weather`, {
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify({
|
|
||||||
lat: location.latitude,
|
|
||||||
lng: location.longitude,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await res.json();
|
|
||||||
|
|
||||||
if (res.status !== 200) {
|
|
||||||
console.error('Error fetching weather data');
|
|
||||||
setLoading(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setData({
|
|
||||||
temperature: data.temperature,
|
|
||||||
condition: data.condition,
|
|
||||||
location: location.city,
|
|
||||||
humidity: data.humidity,
|
|
||||||
windSpeed: data.windSpeed,
|
|
||||||
icon: data.icon,
|
|
||||||
});
|
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="bg-light-secondary dark:bg-dark-secondary rounded-xl border border-light-200 dark:border-dark-200 shadow-sm flex flex-row items-center w-full h-24 min-h-[96px] max-h-[96px] px-3 py-2 gap-3">
|
|
||||||
{loading ? (
|
|
||||||
<>
|
|
||||||
<div className="flex flex-col items-center justify-center w-16 min-w-16 max-w-16 h-full animate-pulse">
|
|
||||||
<div className="h-10 w-10 rounded-full bg-light-200 dark:bg-dark-200 mb-2" />
|
|
||||||
<div className="h-4 w-10 rounded bg-light-200 dark:bg-dark-200" />
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col justify-between flex-1 h-full py-1 animate-pulse">
|
|
||||||
<div className="flex flex-row items-center justify-between">
|
|
||||||
<div className="h-3 w-20 rounded bg-light-200 dark:bg-dark-200" />
|
|
||||||
<div className="h-3 w-12 rounded bg-light-200 dark:bg-dark-200" />
|
|
||||||
</div>
|
|
||||||
<div className="h-3 w-16 rounded bg-light-200 dark:bg-dark-200 mt-1" />
|
|
||||||
<div className="flex flex-row justify-between w-full mt-auto pt-1 border-t border-light-200 dark:border-dark-200">
|
|
||||||
<div className="h-3 w-16 rounded bg-light-200 dark:bg-dark-200" />
|
|
||||||
<div className="h-3 w-8 rounded bg-light-200 dark:bg-dark-200" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="flex flex-col items-center justify-center w-16 min-w-16 max-w-16 h-full">
|
|
||||||
<img
|
|
||||||
src={`/weather-ico/${data.icon}.svg`}
|
|
||||||
alt={data.condition}
|
|
||||||
className="h-10 w-auto"
|
|
||||||
/>
|
|
||||||
<span className="text-base font-semibold text-black dark:text-white">
|
|
||||||
{data.temperature}°C
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col justify-between flex-1 h-full py-1">
|
|
||||||
<div className="flex flex-row items-center justify-between">
|
|
||||||
<span className="text-xs font-medium text-black dark:text-white">
|
|
||||||
{data.location}
|
|
||||||
</span>
|
|
||||||
<span className="flex items-center text-xs text-black/60 dark:text-white/60">
|
|
||||||
<Wind className="w-3 h-3 mr-1" />
|
|
||||||
{data.windSpeed} km/h
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span className="text-xs text-black/60 dark:text-white/60 mt-1">
|
|
||||||
{data.condition}
|
|
||||||
</span>
|
|
||||||
<div className="flex flex-row justify-between w-full mt-auto pt-1 border-t border-light-200 dark:border-dark-200 text-xs text-black/60 dark:text-white/60">
|
|
||||||
<span>Humidity: {data.humidity}%</span>
|
|
||||||
<span>Now</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default WeatherWidget;
|
|
@ -1,18 +1,12 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
import toml from '@iarna/toml';
|
import toml from '@iarna/toml';
|
||||||
|
|
||||||
// Use dynamic imports for Node.js modules to prevent client-side errors
|
|
||||||
let fs: any;
|
|
||||||
let path: any;
|
|
||||||
if (typeof window === 'undefined') {
|
|
||||||
// We're on the server
|
|
||||||
fs = require('fs');
|
|
||||||
path = require('path');
|
|
||||||
}
|
|
||||||
|
|
||||||
const configFileName = 'config.toml';
|
const configFileName = 'config.toml';
|
||||||
|
|
||||||
interface Config {
|
interface Config {
|
||||||
GENERAL: {
|
GENERAL: {
|
||||||
|
PORT: number;
|
||||||
SIMILARITY_MEASURE: string;
|
SIMILARITY_MEASURE: string;
|
||||||
KEEP_ALIVE: string;
|
KEEP_ALIVE: string;
|
||||||
};
|
};
|
||||||
@ -32,12 +26,6 @@ interface Config {
|
|||||||
OLLAMA: {
|
OLLAMA: {
|
||||||
API_URL: string;
|
API_URL: string;
|
||||||
};
|
};
|
||||||
DEEPSEEK: {
|
|
||||||
API_KEY: string;
|
|
||||||
};
|
|
||||||
LM_STUDIO: {
|
|
||||||
API_URL: string;
|
|
||||||
};
|
|
||||||
CUSTOM_OPENAI: {
|
CUSTOM_OPENAI: {
|
||||||
API_URL: string;
|
API_URL: string;
|
||||||
API_KEY: string;
|
API_KEY: string;
|
||||||
@ -53,17 +41,12 @@ type RecursivePartial<T> = {
|
|||||||
[P in keyof T]?: RecursivePartial<T[P]>;
|
[P in keyof T]?: RecursivePartial<T[P]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadConfig = () => {
|
const loadConfig = () =>
|
||||||
// Server-side only
|
toml.parse(
|
||||||
if (typeof window === 'undefined') {
|
fs.readFileSync(path.join(__dirname, `../${configFileName}`), 'utf-8'),
|
||||||
return toml.parse(
|
) as any as Config;
|
||||||
fs.readFileSync(path.join(process.cwd(), `${configFileName}`), 'utf-8'),
|
|
||||||
) as any as Config;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client-side fallback - settings will be loaded via API
|
export const getPort = () => loadConfig().GENERAL.PORT;
|
||||||
return {} as Config;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getSimilarityMeasure = () =>
|
export const getSimilarityMeasure = () =>
|
||||||
loadConfig().GENERAL.SIMILARITY_MEASURE;
|
loadConfig().GENERAL.SIMILARITY_MEASURE;
|
||||||
@ -83,8 +66,6 @@ export const getSearxngApiEndpoint = () =>
|
|||||||
|
|
||||||
export const getOllamaApiEndpoint = () => loadConfig().MODELS.OLLAMA.API_URL;
|
export const getOllamaApiEndpoint = () => loadConfig().MODELS.OLLAMA.API_URL;
|
||||||
|
|
||||||
export const getDeepseekApiKey = () => loadConfig().MODELS.DEEPSEEK.API_KEY;
|
|
||||||
|
|
||||||
export const getCustomOpenaiApiKey = () =>
|
export const getCustomOpenaiApiKey = () =>
|
||||||
loadConfig().MODELS.CUSTOM_OPENAI.API_KEY;
|
loadConfig().MODELS.CUSTOM_OPENAI.API_KEY;
|
||||||
|
|
||||||
@ -94,9 +75,6 @@ export const getCustomOpenaiApiUrl = () =>
|
|||||||
export const getCustomOpenaiModelName = () =>
|
export const getCustomOpenaiModelName = () =>
|
||||||
loadConfig().MODELS.CUSTOM_OPENAI.MODEL_NAME;
|
loadConfig().MODELS.CUSTOM_OPENAI.MODEL_NAME;
|
||||||
|
|
||||||
export const getLMStudioApiEndpoint = () =>
|
|
||||||
loadConfig().MODELS.LM_STUDIO.API_URL;
|
|
||||||
|
|
||||||
const mergeConfigs = (current: any, update: any): any => {
|
const mergeConfigs = (current: any, update: any): any => {
|
||||||
if (update === null || update === undefined) {
|
if (update === null || update === undefined) {
|
||||||
return current;
|
return current;
|
||||||
@ -129,13 +107,11 @@ const mergeConfigs = (current: any, update: any): any => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const updateConfig = (config: RecursivePartial<Config>) => {
|
export const updateConfig = (config: RecursivePartial<Config>) => {
|
||||||
// Server-side only
|
const currentConfig = loadConfig();
|
||||||
if (typeof window === 'undefined') {
|
const mergedConfig = mergeConfigs(currentConfig, config);
|
||||||
const currentConfig = loadConfig();
|
|
||||||
const mergedConfig = mergeConfigs(currentConfig, config);
|
fs.writeFileSync(
|
||||||
fs.writeFileSync(
|
path.join(__dirname, `../${configFileName}`),
|
||||||
path.join(path.join(process.cwd(), `${configFileName}`)),
|
toml.stringify(mergedConfig),
|
||||||
toml.stringify(mergedConfig),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
@ -1,10 +1,8 @@
|
|||||||
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
||||||
import Database from 'better-sqlite3';
|
import Database from 'better-sqlite3';
|
||||||
import * as schema from './schema';
|
import * as schema from './schema';
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
const DATA_DIR = process.env.DATA_DIR || process.cwd();
|
const sqlite = new Database('data/db.sqlite');
|
||||||
const sqlite = new Database(path.join(DATA_DIR, './data/db.sqlite'));
|
|
||||||
const db = drizzle(sqlite, {
|
const db = drizzle(sqlite, {
|
||||||
schema: schema,
|
schema: schema,
|
||||||
});
|
});
|
@ -1,5 +0,0 @@
|
|||||||
import db from './';
|
|
||||||
import { migrate } from 'drizzle-orm/better-sqlite3/migrator';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
migrate(db, { migrationsFolder: path.join(process.cwd(), 'drizzle') });
|
|
@ -28,7 +28,7 @@ export class HuggingFaceTransformersEmbeddings
|
|||||||
|
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
|
|
||||||
private pipelinePromise: Promise<any> | undefined;
|
private pipelinePromise: Promise<any>;
|
||||||
|
|
||||||
constructor(fields?: Partial<HuggingFaceTransformersEmbeddingsParams>) {
|
constructor(fields?: Partial<HuggingFaceTransformersEmbeddingsParams>) {
|
||||||
super(fields ?? {});
|
super(fields ?? {});
|
||||||
|
@ -9,7 +9,7 @@ class LineOutputParser extends BaseOutputParser<string> {
|
|||||||
|
|
||||||
constructor(args?: LineOutputParserArgs) {
|
constructor(args?: LineOutputParserArgs) {
|
||||||
super();
|
super();
|
||||||
this.key = args?.key ?? this.key;
|
this.key = args.key ?? this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static lc_name() {
|
static lc_name() {
|
||||||
|
@ -9,7 +9,7 @@ class LineListOutputParser extends BaseOutputParser<string[]> {
|
|||||||
|
|
||||||
constructor(args?: LineListOutputParserArgs) {
|
constructor(args?: LineListOutputParserArgs) {
|
||||||
super();
|
super();
|
||||||
this.key = args?.key ?? this.key;
|
this.key = args.key ?? this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static lc_name() {
|
static lc_name() {
|
||||||
|
@ -1,43 +1,6 @@
|
|||||||
import { ChatAnthropic } from '@langchain/anthropic';
|
import { ChatAnthropic } from '@langchain/anthropic';
|
||||||
import { ChatModel } from '.';
|
import { getAnthropicApiKey } from '../../config';
|
||||||
import { getAnthropicApiKey } from '../config';
|
import logger from '../../utils/logger';
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'anthropic',
|
|
||||||
displayName: 'Anthropic',
|
|
||||||
};
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
|
|
||||||
const anthropicChatModels: Record<string, string>[] = [
|
|
||||||
{
|
|
||||||
displayName: 'Claude 3.7 Sonnet',
|
|
||||||
key: 'claude-3-7-sonnet-20250219',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Claude 3.5 Haiku',
|
|
||||||
key: 'claude-3-5-haiku-20241022',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Claude 3.5 Sonnet v2',
|
|
||||||
key: 'claude-3-5-sonnet-20241022',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Claude 3.5 Sonnet',
|
|
||||||
key: 'claude-3-5-sonnet-20240620',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Claude 3 Opus',
|
|
||||||
key: 'claude-3-opus-20240229',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Claude 3 Sonnet',
|
|
||||||
key: 'claude-3-sonnet-20240229',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Claude 3 Haiku',
|
|
||||||
key: 'claude-3-haiku-20240307',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const loadAnthropicChatModels = async () => {
|
export const loadAnthropicChatModels = async () => {
|
||||||
const anthropicApiKey = getAnthropicApiKey();
|
const anthropicApiKey = getAnthropicApiKey();
|
||||||
@ -45,22 +8,52 @@ export const loadAnthropicChatModels = async () => {
|
|||||||
if (!anthropicApiKey) return {};
|
if (!anthropicApiKey) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const chatModels: Record<string, ChatModel> = {};
|
const chatModels = {
|
||||||
|
'claude-3-5-sonnet-20241022': {
|
||||||
anthropicChatModels.forEach((model) => {
|
displayName: 'Claude 3.5 Sonnet',
|
||||||
chatModels[model.key] = {
|
|
||||||
displayName: model.displayName,
|
|
||||||
model: new ChatAnthropic({
|
model: new ChatAnthropic({
|
||||||
apiKey: anthropicApiKey,
|
|
||||||
modelName: model.key,
|
|
||||||
temperature: 0.7,
|
temperature: 0.7,
|
||||||
}) as unknown as BaseChatModel,
|
anthropicApiKey: anthropicApiKey,
|
||||||
};
|
model: 'claude-3-5-sonnet-20241022',
|
||||||
});
|
}),
|
||||||
|
},
|
||||||
|
'claude-3-5-haiku-20241022': {
|
||||||
|
displayName: 'Claude 3.5 Haiku',
|
||||||
|
model: new ChatAnthropic({
|
||||||
|
temperature: 0.7,
|
||||||
|
anthropicApiKey: anthropicApiKey,
|
||||||
|
model: 'claude-3-5-haiku-20241022',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'claude-3-opus-20240229': {
|
||||||
|
displayName: 'Claude 3 Opus',
|
||||||
|
model: new ChatAnthropic({
|
||||||
|
temperature: 0.7,
|
||||||
|
anthropicApiKey: anthropicApiKey,
|
||||||
|
model: 'claude-3-opus-20240229',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'claude-3-sonnet-20240229': {
|
||||||
|
displayName: 'Claude 3 Sonnet',
|
||||||
|
model: new ChatAnthropic({
|
||||||
|
temperature: 0.7,
|
||||||
|
anthropicApiKey: anthropicApiKey,
|
||||||
|
model: 'claude-3-sonnet-20240229',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'claude-3-haiku-20240307': {
|
||||||
|
displayName: 'Claude 3 Haiku',
|
||||||
|
model: new ChatAnthropic({
|
||||||
|
temperature: 0.7,
|
||||||
|
anthropicApiKey: anthropicApiKey,
|
||||||
|
model: 'claude-3-haiku-20240307',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return chatModels;
|
return chatModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading Anthropic models: ${err}`);
|
logger.error(`Error loading Anthropic models: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import { ChatOpenAI } from '@langchain/openai';
|
|
||||||
import { getDeepseekApiKey } from '../config';
|
|
||||||
import { ChatModel } from '.';
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'deepseek',
|
|
||||||
displayName: 'Deepseek AI',
|
|
||||||
};
|
|
||||||
|
|
||||||
const deepseekChatModels: Record<string, string>[] = [
|
|
||||||
{
|
|
||||||
displayName: 'Deepseek Chat (Deepseek V3)',
|
|
||||||
key: 'deepseek-chat',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Deepseek Reasoner (Deepseek R1)',
|
|
||||||
key: 'deepseek-reasoner',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const loadDeepseekChatModels = async () => {
|
|
||||||
const deepseekApiKey = getDeepseekApiKey();
|
|
||||||
|
|
||||||
if (!deepseekApiKey) return {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const chatModels: Record<string, ChatModel> = {};
|
|
||||||
|
|
||||||
deepseekChatModels.forEach((model) => {
|
|
||||||
chatModels[model.key] = {
|
|
||||||
displayName: model.displayName,
|
|
||||||
model: new ChatOpenAI({
|
|
||||||
openAIApiKey: deepseekApiKey,
|
|
||||||
modelName: model.key,
|
|
||||||
temperature: 0.7,
|
|
||||||
configuration: {
|
|
||||||
baseURL: 'https://api.deepseek.com',
|
|
||||||
},
|
|
||||||
}) as unknown as BaseChatModel,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return chatModels;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error loading Deepseek models: ${err}`);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
@ -2,65 +2,8 @@ import {
|
|||||||
ChatGoogleGenerativeAI,
|
ChatGoogleGenerativeAI,
|
||||||
GoogleGenerativeAIEmbeddings,
|
GoogleGenerativeAIEmbeddings,
|
||||||
} from '@langchain/google-genai';
|
} from '@langchain/google-genai';
|
||||||
import { getGeminiApiKey } from '../config';
|
import { getGeminiApiKey } from '../../config';
|
||||||
import { ChatModel, EmbeddingModel } from '.';
|
import logger from '../../utils/logger';
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'gemini',
|
|
||||||
displayName: 'Google Gemini',
|
|
||||||
};
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import { Embeddings } from '@langchain/core/embeddings';
|
|
||||||
|
|
||||||
const geminiChatModels: Record<string, string>[] = [
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 2.5 Flash Preview 05-20',
|
|
||||||
key: 'gemini-2.5-flash-preview-05-20',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 2.5 Pro Preview',
|
|
||||||
key: 'gemini-2.5-pro-preview-05-06',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 2.5 Pro Experimental',
|
|
||||||
key: 'gemini-2.5-pro-preview-05-06',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 2.0 Flash',
|
|
||||||
key: 'gemini-2.0-flash',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 2.0 Flash-Lite',
|
|
||||||
key: 'gemini-2.0-flash-lite',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 2.0 Flash Thinking Experimental',
|
|
||||||
key: 'gemini-2.0-flash-thinking-exp-01-21',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 1.5 Flash',
|
|
||||||
key: 'gemini-1.5-flash',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 1.5 Flash-8B',
|
|
||||||
key: 'gemini-1.5-flash-8b',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Gemini 1.5 Pro',
|
|
||||||
key: 'gemini-1.5-pro',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const geminiEmbeddingModels: Record<string, string>[] = [
|
|
||||||
{
|
|
||||||
displayName: 'Text Embedding 004',
|
|
||||||
key: 'models/text-embedding-004',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Embedding 001',
|
|
||||||
key: 'models/embedding-001',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const loadGeminiChatModels = async () => {
|
export const loadGeminiChatModels = async () => {
|
||||||
const geminiApiKey = getGeminiApiKey();
|
const geminiApiKey = getGeminiApiKey();
|
||||||
@ -68,47 +11,75 @@ export const loadGeminiChatModels = async () => {
|
|||||||
if (!geminiApiKey) return {};
|
if (!geminiApiKey) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const chatModels: Record<string, ChatModel> = {};
|
const chatModels = {
|
||||||
|
'gemini-1.5-flash': {
|
||||||
geminiChatModels.forEach((model) => {
|
displayName: 'Gemini 1.5 Flash',
|
||||||
chatModels[model.key] = {
|
|
||||||
displayName: model.displayName,
|
|
||||||
model: new ChatGoogleGenerativeAI({
|
model: new ChatGoogleGenerativeAI({
|
||||||
apiKey: geminiApiKey,
|
modelName: 'gemini-1.5-flash',
|
||||||
modelName: model.key,
|
|
||||||
temperature: 0.7,
|
temperature: 0.7,
|
||||||
}) as unknown as BaseChatModel,
|
apiKey: geminiApiKey,
|
||||||
};
|
}),
|
||||||
});
|
},
|
||||||
|
'gemini-1.5-flash-8b': {
|
||||||
|
displayName: 'Gemini 1.5 Flash 8B',
|
||||||
|
model: new ChatGoogleGenerativeAI({
|
||||||
|
modelName: 'gemini-1.5-flash-8b',
|
||||||
|
temperature: 0.7,
|
||||||
|
apiKey: geminiApiKey,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'gemini-1.5-pro': {
|
||||||
|
displayName: 'Gemini 1.5 Pro',
|
||||||
|
model: new ChatGoogleGenerativeAI({
|
||||||
|
modelName: 'gemini-1.5-pro',
|
||||||
|
temperature: 0.7,
|
||||||
|
apiKey: geminiApiKey,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'gemini-2.0-flash-exp': {
|
||||||
|
displayName: 'Gemini 2.0 Flash Exp',
|
||||||
|
model: new ChatGoogleGenerativeAI({
|
||||||
|
modelName: 'gemini-2.0-flash-exp',
|
||||||
|
temperature: 0.7,
|
||||||
|
apiKey: geminiApiKey,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'gemini-2.0-flash-thinking-exp-01-21': {
|
||||||
|
displayName: 'Gemini 2.0 Flash Thinking Exp 01-21',
|
||||||
|
model: new ChatGoogleGenerativeAI({
|
||||||
|
modelName: 'gemini-2.0-flash-thinking-exp-01-21',
|
||||||
|
temperature: 0.7,
|
||||||
|
apiKey: geminiApiKey,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return chatModels;
|
return chatModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading Gemini models: ${err}`);
|
logger.error(`Error loading Gemini models: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadGeminiEmbeddingModels = async () => {
|
export const loadGeminiEmbeddingsModels = async () => {
|
||||||
const geminiApiKey = getGeminiApiKey();
|
const geminiApiKey = getGeminiApiKey();
|
||||||
|
|
||||||
if (!geminiApiKey) return {};
|
if (!geminiApiKey) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const embeddingModels: Record<string, EmbeddingModel> = {};
|
const embeddingModels = {
|
||||||
|
'text-embedding-004': {
|
||||||
geminiEmbeddingModels.forEach((model) => {
|
displayName: 'Text Embedding',
|
||||||
embeddingModels[model.key] = {
|
|
||||||
displayName: model.displayName,
|
|
||||||
model: new GoogleGenerativeAIEmbeddings({
|
model: new GoogleGenerativeAIEmbeddings({
|
||||||
apiKey: geminiApiKey,
|
apiKey: geminiApiKey,
|
||||||
modelName: model.key,
|
modelName: 'text-embedding-004',
|
||||||
}) as unknown as Embeddings,
|
}),
|
||||||
};
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
return embeddingModels;
|
return embeddingModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading OpenAI embeddings models: ${err}`);
|
logger.error(`Error loading Gemini embeddings model: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,47 +1,136 @@
|
|||||||
import { ChatOpenAI } from '@langchain/openai';
|
import { ChatOpenAI } from '@langchain/openai';
|
||||||
import { getGroqApiKey } from '../config';
|
import { getGroqApiKey } from '../../config';
|
||||||
import { ChatModel } from '.';
|
import logger from '../../utils/logger';
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'groq',
|
|
||||||
displayName: 'Groq',
|
|
||||||
};
|
|
||||||
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
|
|
||||||
export const loadGroqChatModels = async () => {
|
export const loadGroqChatModels = async () => {
|
||||||
const groqApiKey = getGroqApiKey();
|
const groqApiKey = getGroqApiKey();
|
||||||
|
|
||||||
if (!groqApiKey) return {};
|
if (!groqApiKey) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch('https://api.groq.com/openai/v1/models', {
|
const chatModels = {
|
||||||
method: 'GET',
|
'llama-3.3-70b-versatile': {
|
||||||
headers: {
|
displayName: 'Llama 3.3 70B',
|
||||||
Authorization: `bearer ${groqApiKey}`,
|
model: new ChatOpenAI(
|
||||||
'Content-Type': 'application/json',
|
{
|
||||||
},
|
openAIApiKey: groqApiKey,
|
||||||
});
|
modelName: 'llama-3.3-70b-versatile',
|
||||||
|
temperature: 0.7,
|
||||||
const groqChatModels = (await res.json()).data;
|
},
|
||||||
const chatModels: Record<string, ChatModel> = {};
|
{
|
||||||
|
|
||||||
groqChatModels.forEach((model: any) => {
|
|
||||||
chatModels[model.id] = {
|
|
||||||
displayName: model.id,
|
|
||||||
model: new ChatOpenAI({
|
|
||||||
openAIApiKey: groqApiKey,
|
|
||||||
modelName: model.id,
|
|
||||||
temperature: 0.7,
|
|
||||||
configuration: {
|
|
||||||
baseURL: 'https://api.groq.com/openai/v1',
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
},
|
},
|
||||||
}) as unknown as BaseChatModel,
|
),
|
||||||
};
|
},
|
||||||
});
|
'llama-3.2-3b-preview': {
|
||||||
|
displayName: 'Llama 3.2 3B',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'llama-3.2-3b-preview',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'llama-3.2-11b-vision-preview': {
|
||||||
|
displayName: 'Llama 3.2 11B Vision',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'llama-3.2-11b-vision-preview',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'llama-3.2-90b-vision-preview': {
|
||||||
|
displayName: 'Llama 3.2 90B Vision',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'llama-3.2-90b-vision-preview',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'llama-3.1-8b-instant': {
|
||||||
|
displayName: 'Llama 3.1 8B',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'llama-3.1-8b-instant',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'llama3-8b-8192': {
|
||||||
|
displayName: 'LLaMA3 8B',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'llama3-8b-8192',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'llama3-70b-8192': {
|
||||||
|
displayName: 'LLaMA3 70B',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'llama3-70b-8192',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'mixtral-8x7b-32768': {
|
||||||
|
displayName: 'Mixtral 8x7B',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'mixtral-8x7b-32768',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'gemma2-9b-it': {
|
||||||
|
displayName: 'Gemma2 9B',
|
||||||
|
model: new ChatOpenAI(
|
||||||
|
{
|
||||||
|
openAIApiKey: groqApiKey,
|
||||||
|
modelName: 'gemma2-9b-it',
|
||||||
|
temperature: 0.7,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
baseURL: 'https://api.groq.com/openai/v1',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return chatModels;
|
return chatModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading Groq models: ${err}`);
|
logger.error(`Error loading Groq models: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,97 +1,33 @@
|
|||||||
import { Embeddings } from '@langchain/core/embeddings';
|
import { loadGroqChatModels } from './groq';
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
import { loadOllamaChatModels, loadOllamaEmbeddingsModels } from './ollama';
|
||||||
import {
|
import { loadOpenAIChatModels, loadOpenAIEmbeddingsModels } from './openai';
|
||||||
loadOpenAIChatModels,
|
import { loadAnthropicChatModels } from './anthropic';
|
||||||
loadOpenAIEmbeddingModels,
|
import { loadTransformersEmbeddingsModels } from './transformers';
|
||||||
PROVIDER_INFO as OpenAIInfo,
|
import { loadGeminiChatModels, loadGeminiEmbeddingsModels } from './gemini';
|
||||||
PROVIDER_INFO,
|
|
||||||
} from './openai';
|
|
||||||
import {
|
import {
|
||||||
getCustomOpenaiApiKey,
|
getCustomOpenaiApiKey,
|
||||||
getCustomOpenaiApiUrl,
|
getCustomOpenaiApiUrl,
|
||||||
getCustomOpenaiModelName,
|
getCustomOpenaiModelName,
|
||||||
} from '../config';
|
} from '../../config';
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
import { ChatOpenAI } from '@langchain/openai';
|
||||||
import {
|
|
||||||
loadOllamaChatModels,
|
|
||||||
loadOllamaEmbeddingModels,
|
|
||||||
PROVIDER_INFO as OllamaInfo,
|
|
||||||
} from './ollama';
|
|
||||||
import { loadGroqChatModels, PROVIDER_INFO as GroqInfo } from './groq';
|
|
||||||
import {
|
|
||||||
loadAnthropicChatModels,
|
|
||||||
PROVIDER_INFO as AnthropicInfo,
|
|
||||||
} from './anthropic';
|
|
||||||
import {
|
|
||||||
loadGeminiChatModels,
|
|
||||||
loadGeminiEmbeddingModels,
|
|
||||||
PROVIDER_INFO as GeminiInfo,
|
|
||||||
} from './gemini';
|
|
||||||
import {
|
|
||||||
loadTransformersEmbeddingsModels,
|
|
||||||
PROVIDER_INFO as TransformersInfo,
|
|
||||||
} from './transformers';
|
|
||||||
import {
|
|
||||||
loadDeepseekChatModels,
|
|
||||||
PROVIDER_INFO as DeepseekInfo,
|
|
||||||
} from './deepseek';
|
|
||||||
import {
|
|
||||||
loadLMStudioChatModels,
|
|
||||||
loadLMStudioEmbeddingsModels,
|
|
||||||
PROVIDER_INFO as LMStudioInfo,
|
|
||||||
} from './lmstudio';
|
|
||||||
|
|
||||||
export const PROVIDER_METADATA = {
|
const chatModelProviders = {
|
||||||
openai: OpenAIInfo,
|
|
||||||
ollama: OllamaInfo,
|
|
||||||
groq: GroqInfo,
|
|
||||||
anthropic: AnthropicInfo,
|
|
||||||
gemini: GeminiInfo,
|
|
||||||
transformers: TransformersInfo,
|
|
||||||
deepseek: DeepseekInfo,
|
|
||||||
lmstudio: LMStudioInfo,
|
|
||||||
custom_openai: {
|
|
||||||
key: 'custom_openai',
|
|
||||||
displayName: 'Custom OpenAI',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface ChatModel {
|
|
||||||
displayName: string;
|
|
||||||
model: BaseChatModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EmbeddingModel {
|
|
||||||
displayName: string;
|
|
||||||
model: Embeddings;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const chatModelProviders: Record<
|
|
||||||
string,
|
|
||||||
() => Promise<Record<string, ChatModel>>
|
|
||||||
> = {
|
|
||||||
openai: loadOpenAIChatModels,
|
openai: loadOpenAIChatModels,
|
||||||
ollama: loadOllamaChatModels,
|
|
||||||
groq: loadGroqChatModels,
|
groq: loadGroqChatModels,
|
||||||
|
ollama: loadOllamaChatModels,
|
||||||
anthropic: loadAnthropicChatModels,
|
anthropic: loadAnthropicChatModels,
|
||||||
gemini: loadGeminiChatModels,
|
gemini: loadGeminiChatModels,
|
||||||
deepseek: loadDeepseekChatModels,
|
|
||||||
lmstudio: loadLMStudioChatModels,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const embeddingModelProviders: Record<
|
const embeddingModelProviders = {
|
||||||
string,
|
openai: loadOpenAIEmbeddingsModels,
|
||||||
() => Promise<Record<string, EmbeddingModel>>
|
local: loadTransformersEmbeddingsModels,
|
||||||
> = {
|
ollama: loadOllamaEmbeddingsModels,
|
||||||
openai: loadOpenAIEmbeddingModels,
|
gemini: loadGeminiEmbeddingsModels,
|
||||||
ollama: loadOllamaEmbeddingModels,
|
|
||||||
gemini: loadGeminiEmbeddingModels,
|
|
||||||
transformers: loadTransformersEmbeddingsModels,
|
|
||||||
lmstudio: loadLMStudioEmbeddingsModels,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAvailableChatModelProviders = async () => {
|
export const getAvailableChatModelProviders = async () => {
|
||||||
const models: Record<string, Record<string, ChatModel>> = {};
|
const models = {};
|
||||||
|
|
||||||
for (const provider in chatModelProviders) {
|
for (const provider in chatModelProviders) {
|
||||||
const providerModels = await chatModelProviders[provider]();
|
const providerModels = await chatModelProviders[provider]();
|
||||||
@ -116,7 +52,7 @@ export const getAvailableChatModelProviders = async () => {
|
|||||||
configuration: {
|
configuration: {
|
||||||
baseURL: customOpenAiApiUrl,
|
baseURL: customOpenAiApiUrl,
|
||||||
},
|
},
|
||||||
}) as unknown as BaseChatModel,
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
@ -126,7 +62,7 @@ export const getAvailableChatModelProviders = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getAvailableEmbeddingModelProviders = async () => {
|
export const getAvailableEmbeddingModelProviders = async () => {
|
||||||
const models: Record<string, Record<string, EmbeddingModel>> = {};
|
const models = {};
|
||||||
|
|
||||||
for (const provider in embeddingModelProviders) {
|
for (const provider in embeddingModelProviders) {
|
||||||
const providerModels = await embeddingModelProviders[provider]();
|
const providerModels = await embeddingModelProviders[provider]();
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
import { getKeepAlive, getLMStudioApiEndpoint } from '../config';
|
|
||||||
import axios from 'axios';
|
|
||||||
import { ChatModel, EmbeddingModel } from '.';
|
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'lmstudio',
|
|
||||||
displayName: 'LM Studio',
|
|
||||||
};
|
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
|
||||||
import { OpenAIEmbeddings } from '@langchain/openai';
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import { Embeddings } from '@langchain/core/embeddings';
|
|
||||||
|
|
||||||
interface LMStudioModel {
|
|
||||||
id: string;
|
|
||||||
name?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ensureV1Endpoint = (endpoint: string): string =>
|
|
||||||
endpoint.endsWith('/v1') ? endpoint : `${endpoint}/v1`;
|
|
||||||
|
|
||||||
const checkServerAvailability = async (endpoint: string): Promise<boolean> => {
|
|
||||||
try {
|
|
||||||
await axios.get(`${ensureV1Endpoint(endpoint)}/models`, {
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const loadLMStudioChatModels = async () => {
|
|
||||||
const endpoint = getLMStudioApiEndpoint();
|
|
||||||
|
|
||||||
if (!endpoint) return {};
|
|
||||||
if (!(await checkServerAvailability(endpoint))) return {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`${ensureV1Endpoint(endpoint)}/models`, {
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const chatModels: Record<string, ChatModel> = {};
|
|
||||||
|
|
||||||
response.data.data.forEach((model: LMStudioModel) => {
|
|
||||||
chatModels[model.id] = {
|
|
||||||
displayName: model.name || model.id,
|
|
||||||
model: new ChatOpenAI({
|
|
||||||
openAIApiKey: 'lm-studio',
|
|
||||||
configuration: {
|
|
||||||
baseURL: ensureV1Endpoint(endpoint),
|
|
||||||
},
|
|
||||||
modelName: model.id,
|
|
||||||
temperature: 0.7,
|
|
||||||
streaming: true,
|
|
||||||
maxRetries: 3,
|
|
||||||
}) as unknown as BaseChatModel,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return chatModels;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error loading LM Studio models: ${err}`);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const loadLMStudioEmbeddingsModels = async () => {
|
|
||||||
const endpoint = getLMStudioApiEndpoint();
|
|
||||||
|
|
||||||
if (!endpoint) return {};
|
|
||||||
if (!(await checkServerAvailability(endpoint))) return {};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios.get(`${ensureV1Endpoint(endpoint)}/models`, {
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
});
|
|
||||||
|
|
||||||
const embeddingsModels: Record<string, EmbeddingModel> = {};
|
|
||||||
|
|
||||||
response.data.data.forEach((model: LMStudioModel) => {
|
|
||||||
embeddingsModels[model.id] = {
|
|
||||||
displayName: model.name || model.id,
|
|
||||||
model: new OpenAIEmbeddings({
|
|
||||||
openAIApiKey: 'lm-studio',
|
|
||||||
configuration: {
|
|
||||||
baseURL: ensureV1Endpoint(endpoint),
|
|
||||||
},
|
|
||||||
modelName: model.id,
|
|
||||||
}) as unknown as Embeddings,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return embeddingsModels;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error loading LM Studio embeddings model: ${err}`);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,78 +1,74 @@
|
|||||||
import axios from 'axios';
|
|
||||||
import { getKeepAlive, getOllamaApiEndpoint } from '../config';
|
|
||||||
import { ChatModel, EmbeddingModel } from '.';
|
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'ollama',
|
|
||||||
displayName: 'Ollama',
|
|
||||||
};
|
|
||||||
import { ChatOllama } from '@langchain/community/chat_models/ollama';
|
|
||||||
import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama';
|
import { OllamaEmbeddings } from '@langchain/community/embeddings/ollama';
|
||||||
|
import { getKeepAlive, getOllamaApiEndpoint } from '../../config';
|
||||||
|
import logger from '../../utils/logger';
|
||||||
|
import { ChatOllama } from '@langchain/community/chat_models/ollama';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
export const loadOllamaChatModels = async () => {
|
export const loadOllamaChatModels = async () => {
|
||||||
const ollamaApiEndpoint = getOllamaApiEndpoint();
|
const ollamaEndpoint = getOllamaApiEndpoint();
|
||||||
|
const keepAlive = getKeepAlive();
|
||||||
|
|
||||||
if (!ollamaApiEndpoint) return {};
|
if (!ollamaEndpoint) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(`${ollamaApiEndpoint}/api/tags`, {
|
const response = await axios.get(`${ollamaEndpoint}/api/tags`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { models } = res.data;
|
const { models: ollamaModels } = response.data;
|
||||||
|
|
||||||
const chatModels: Record<string, ChatModel> = {};
|
const chatModels = ollamaModels.reduce((acc, model) => {
|
||||||
|
acc[model.model] = {
|
||||||
models.forEach((model: any) => {
|
|
||||||
chatModels[model.model] = {
|
|
||||||
displayName: model.name,
|
displayName: model.name,
|
||||||
model: new ChatOllama({
|
model: new ChatOllama({
|
||||||
baseUrl: ollamaApiEndpoint,
|
baseUrl: ollamaEndpoint,
|
||||||
model: model.model,
|
model: model.model,
|
||||||
temperature: 0.7,
|
temperature: 0.7,
|
||||||
keepAlive: getKeepAlive(),
|
keepAlive: keepAlive,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
return chatModels;
|
return chatModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading Ollama models: ${err}`);
|
logger.error(`Error loading Ollama models: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadOllamaEmbeddingModels = async () => {
|
export const loadOllamaEmbeddingsModels = async () => {
|
||||||
const ollamaApiEndpoint = getOllamaApiEndpoint();
|
const ollamaEndpoint = getOllamaApiEndpoint();
|
||||||
|
|
||||||
if (!ollamaApiEndpoint) return {};
|
if (!ollamaEndpoint) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(`${ollamaApiEndpoint}/api/tags`, {
|
const response = await axios.get(`${ollamaEndpoint}/api/tags`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { models } = res.data;
|
const { models: ollamaModels } = response.data;
|
||||||
|
|
||||||
const embeddingModels: Record<string, EmbeddingModel> = {};
|
const embeddingsModels = ollamaModels.reduce((acc, model) => {
|
||||||
|
acc[model.model] = {
|
||||||
models.forEach((model: any) => {
|
|
||||||
embeddingModels[model.model] = {
|
|
||||||
displayName: model.name,
|
displayName: model.name,
|
||||||
model: new OllamaEmbeddings({
|
model: new OllamaEmbeddings({
|
||||||
baseUrl: ollamaApiEndpoint,
|
baseUrl: ollamaEndpoint,
|
||||||
model: model.model,
|
model: model.model,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
|
||||||
return embeddingModels;
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return embeddingsModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading Ollama embeddings models: ${err}`);
|
logger.error(`Error loading Ollama embeddings model: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,107 +1,89 @@
|
|||||||
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
|
import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
|
||||||
import { getOpenaiApiKey } from '../config';
|
import { getOpenaiApiKey } from '../../config';
|
||||||
import { ChatModel, EmbeddingModel } from '.';
|
import logger from '../../utils/logger';
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'openai',
|
|
||||||
displayName: 'OpenAI',
|
|
||||||
};
|
|
||||||
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
||||||
import { Embeddings } from '@langchain/core/embeddings';
|
|
||||||
|
|
||||||
const openaiChatModels: Record<string, string>[] = [
|
|
||||||
{
|
|
||||||
displayName: 'GPT-3.5 Turbo',
|
|
||||||
key: 'gpt-3.5-turbo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'GPT-4',
|
|
||||||
key: 'gpt-4',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'GPT-4 turbo',
|
|
||||||
key: 'gpt-4-turbo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'GPT-4 omni',
|
|
||||||
key: 'gpt-4o',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'GPT-4 omni mini',
|
|
||||||
key: 'gpt-4o-mini',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'GPT 4.1 nano',
|
|
||||||
key: 'gpt-4.1-nano',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'GPT 4.1 mini',
|
|
||||||
key: 'gpt-4.1-mini',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'GPT 4.1',
|
|
||||||
key: 'gpt-4.1',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const openaiEmbeddingModels: Record<string, string>[] = [
|
|
||||||
{
|
|
||||||
displayName: 'Text Embedding 3 Small',
|
|
||||||
key: 'text-embedding-3-small',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Text Embedding 3 Large',
|
|
||||||
key: 'text-embedding-3-large',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const loadOpenAIChatModels = async () => {
|
export const loadOpenAIChatModels = async () => {
|
||||||
const openaiApiKey = getOpenaiApiKey();
|
const openAIApiKey = getOpenaiApiKey();
|
||||||
|
|
||||||
if (!openaiApiKey) return {};
|
if (!openAIApiKey) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const chatModels: Record<string, ChatModel> = {};
|
const chatModels = {
|
||||||
|
'gpt-3.5-turbo': {
|
||||||
openaiChatModels.forEach((model) => {
|
displayName: 'GPT-3.5 Turbo',
|
||||||
chatModels[model.key] = {
|
|
||||||
displayName: model.displayName,
|
|
||||||
model: new ChatOpenAI({
|
model: new ChatOpenAI({
|
||||||
openAIApiKey: openaiApiKey,
|
openAIApiKey,
|
||||||
modelName: model.key,
|
modelName: 'gpt-3.5-turbo',
|
||||||
temperature: 0.7,
|
temperature: 0.7,
|
||||||
}) as unknown as BaseChatModel,
|
}),
|
||||||
};
|
},
|
||||||
});
|
'gpt-4': {
|
||||||
|
displayName: 'GPT-4',
|
||||||
|
model: new ChatOpenAI({
|
||||||
|
openAIApiKey,
|
||||||
|
modelName: 'gpt-4',
|
||||||
|
temperature: 0.7,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'gpt-4-turbo': {
|
||||||
|
displayName: 'GPT-4 turbo',
|
||||||
|
model: new ChatOpenAI({
|
||||||
|
openAIApiKey,
|
||||||
|
modelName: 'gpt-4-turbo',
|
||||||
|
temperature: 0.7,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'gpt-4o': {
|
||||||
|
displayName: 'GPT-4 omni',
|
||||||
|
model: new ChatOpenAI({
|
||||||
|
openAIApiKey,
|
||||||
|
modelName: 'gpt-4o',
|
||||||
|
temperature: 0.7,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
'gpt-4o-mini': {
|
||||||
|
displayName: 'GPT-4 omni mini',
|
||||||
|
model: new ChatOpenAI({
|
||||||
|
openAIApiKey,
|
||||||
|
modelName: 'gpt-4o-mini',
|
||||||
|
temperature: 0.7,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return chatModels;
|
return chatModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading OpenAI models: ${err}`);
|
logger.error(`Error loading OpenAI models: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadOpenAIEmbeddingModels = async () => {
|
export const loadOpenAIEmbeddingsModels = async () => {
|
||||||
const openaiApiKey = getOpenaiApiKey();
|
const openAIApiKey = getOpenaiApiKey();
|
||||||
|
|
||||||
if (!openaiApiKey) return {};
|
if (!openAIApiKey) return {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const embeddingModels: Record<string, EmbeddingModel> = {};
|
const embeddingModels = {
|
||||||
|
'text-embedding-3-small': {
|
||||||
openaiEmbeddingModels.forEach((model) => {
|
displayName: 'Text Embedding 3 Small',
|
||||||
embeddingModels[model.key] = {
|
|
||||||
displayName: model.displayName,
|
|
||||||
model: new OpenAIEmbeddings({
|
model: new OpenAIEmbeddings({
|
||||||
openAIApiKey: openaiApiKey,
|
openAIApiKey,
|
||||||
modelName: model.key,
|
modelName: 'text-embedding-3-small',
|
||||||
}) as unknown as Embeddings,
|
}),
|
||||||
};
|
},
|
||||||
});
|
'text-embedding-3-large': {
|
||||||
|
displayName: 'Text Embedding 3 Large',
|
||||||
|
model: new OpenAIEmbeddings({
|
||||||
|
openAIApiKey,
|
||||||
|
modelName: 'text-embedding-3-large',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
return embeddingModels;
|
return embeddingModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading OpenAI embeddings models: ${err}`);
|
logger.error(`Error loading OpenAI embeddings model: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
|
import logger from '../../utils/logger';
|
||||||
import { HuggingFaceTransformersEmbeddings } from '../huggingfaceTransformer';
|
import { HuggingFaceTransformersEmbeddings } from '../huggingfaceTransformer';
|
||||||
|
|
||||||
export const PROVIDER_INFO = {
|
|
||||||
key: 'transformers',
|
|
||||||
displayName: 'Hugging Face',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const loadTransformersEmbeddingsModels = async () => {
|
export const loadTransformersEmbeddingsModels = async () => {
|
||||||
try {
|
try {
|
||||||
const embeddingModels = {
|
const embeddingModels = {
|
||||||
@ -30,7 +26,7 @@ export const loadTransformersEmbeddingsModels = async () => {
|
|||||||
|
|
||||||
return embeddingModels;
|
return embeddingModels;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Error loading Transformers embeddings model: ${err}`);
|
logger.error(`Error loading Transformers embeddings model: ${err}`);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
import MetaSearchAgent from '@/lib/search/metaSearchAgent';
|
|
||||||
import prompts from '../prompts';
|
|
||||||
|
|
||||||
export const searchHandlers: Record<string, MetaSearchAgent> = {
|
|
||||||
webSearch: new MetaSearchAgent({
|
|
||||||
activeEngines: [],
|
|
||||||
queryGeneratorPrompt: prompts.webSearchRetrieverPrompt,
|
|
||||||
responsePrompt: prompts.webSearchResponsePrompt,
|
|
||||||
rerank: true,
|
|
||||||
rerankThreshold: 0.3,
|
|
||||||
searchWeb: true,
|
|
||||||
summarizer: true,
|
|
||||||
}),
|
|
||||||
academicSearch: new MetaSearchAgent({
|
|
||||||
activeEngines: ['arxiv', 'google scholar', 'pubmed'],
|
|
||||||
queryGeneratorPrompt: prompts.academicSearchRetrieverPrompt,
|
|
||||||
responsePrompt: prompts.academicSearchResponsePrompt,
|
|
||||||
rerank: true,
|
|
||||||
rerankThreshold: 0,
|
|
||||||
searchWeb: true,
|
|
||||||
summarizer: false,
|
|
||||||
}),
|
|
||||||
writingAssistant: new MetaSearchAgent({
|
|
||||||
activeEngines: [],
|
|
||||||
queryGeneratorPrompt: '',
|
|
||||||
responsePrompt: prompts.writingAssistantPrompt,
|
|
||||||
rerank: true,
|
|
||||||
rerankThreshold: 0,
|
|
||||||
searchWeb: false,
|
|
||||||
summarizer: false,
|
|
||||||
}),
|
|
||||||
wolframAlphaSearch: new MetaSearchAgent({
|
|
||||||
activeEngines: ['wolframalpha'],
|
|
||||||
queryGeneratorPrompt: prompts.wolframAlphaSearchRetrieverPrompt,
|
|
||||||
responsePrompt: prompts.wolframAlphaSearchResponsePrompt,
|
|
||||||
rerank: false,
|
|
||||||
rerankThreshold: 0,
|
|
||||||
searchWeb: true,
|
|
||||||
summarizer: false,
|
|
||||||
}),
|
|
||||||
youtubeSearch: new MetaSearchAgent({
|
|
||||||
activeEngines: ['youtube'],
|
|
||||||
queryGeneratorPrompt: prompts.youtubeSearchRetrieverPrompt,
|
|
||||||
responsePrompt: prompts.youtubeSearchResponsePrompt,
|
|
||||||
rerank: true,
|
|
||||||
rerankThreshold: 0.3,
|
|
||||||
searchWeb: true,
|
|
||||||
summarizer: false,
|
|
||||||
}),
|
|
||||||
redditSearch: new MetaSearchAgent({
|
|
||||||
activeEngines: ['reddit'],
|
|
||||||
queryGeneratorPrompt: prompts.redditSearchRetrieverPrompt,
|
|
||||||
responsePrompt: prompts.redditSearchResponsePrompt,
|
|
||||||
rerank: true,
|
|
||||||
rerankThreshold: 0.3,
|
|
||||||
searchWeb: true,
|
|
||||||
summarizer: false,
|
|
||||||
}),
|
|
||||||
};
|
|
@ -1,5 +1,5 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { getSearxngApiEndpoint } from './config';
|
import { getSearxngApiEndpoint } from '../config';
|
||||||
|
|
||||||
interface SearxngSearchOptions {
|
interface SearxngSearchOptions {
|
||||||
categories?: string[];
|
categories?: string[];
|
||||||
@ -30,12 +30,11 @@ export const searchSearxng = async (
|
|||||||
|
|
||||||
if (opts) {
|
if (opts) {
|
||||||
Object.keys(opts).forEach((key) => {
|
Object.keys(opts).forEach((key) => {
|
||||||
const value = opts[key as keyof SearxngSearchOptions];
|
if (Array.isArray(opts[key])) {
|
||||||
if (Array.isArray(value)) {
|
url.searchParams.append(key, opts[key].join(','));
|
||||||
url.searchParams.append(key, value.join(','));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
url.searchParams.append(key, value as string);
|
url.searchParams.append(key, opts[key]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
src/lib/types/compute-dot.d.ts
vendored
@ -1,5 +0,0 @@
|
|||||||
declare function computeDot(vectorA: number[], vectorB: number[]): number;
|
|
||||||
|
|
||||||
declare module 'compute-dot' {
|
|
||||||
export default computeDot;
|
|
||||||
}
|
|
@ -51,10 +51,6 @@ export const academicSearchResponsePrompt = `
|
|||||||
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
||||||
- You are set on focus mode 'Academic', this means you will be searching for academic papers and articles on the web.
|
- You are set on focus mode 'Academic', this means you will be searching for academic papers and articles on the web.
|
||||||
|
|
||||||
### User instructions
|
|
||||||
These instructions are shared to you by the user and not by the system. You will have to follow them but give them less priority than the above instructions. If the user has provided specific instructions or preferences, incorporate them into your response while adhering to the overall guidelines.
|
|
||||||
{systemInstructions}
|
|
||||||
|
|
||||||
### Example Output
|
### Example Output
|
||||||
- Begin with a brief introduction summarizing the event or query topic.
|
- Begin with a brief introduction summarizing the event or query topic.
|
||||||
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
@ -51,10 +51,6 @@ export const redditSearchResponsePrompt = `
|
|||||||
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
||||||
- You are set on focus mode 'Reddit', this means you will be searching for information, opinions and discussions on the web using Reddit.
|
- You are set on focus mode 'Reddit', this means you will be searching for information, opinions and discussions on the web using Reddit.
|
||||||
|
|
||||||
### User instructions
|
|
||||||
These instructions are shared to you by the user and not by the system. You will have to follow them but give them less priority than the above instructions. If the user has provided specific instructions or preferences, incorporate them into your response while adhering to the overall guidelines.
|
|
||||||
{systemInstructions}
|
|
||||||
|
|
||||||
### Example Output
|
### Example Output
|
||||||
- Begin with a brief introduction summarizing the event or query topic.
|
- Begin with a brief introduction summarizing the event or query topic.
|
||||||
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
@ -1,6 +1,7 @@
|
|||||||
export const webSearchRetrieverPrompt = `
|
export const webSearchRetrieverPrompt = `
|
||||||
You are an AI question rephraser. You will be given a conversation and a follow-up question, you will have to rephrase the follow up question so it is a standalone question and can be used by another LLM to search the web for information to answer it.
|
You are an AI question rephraser. You will be given a conversation and a follow-up question, you will have to rephrase the follow up question so it is a standalone question and can be used by another LLM to search the web for information to answer it.
|
||||||
If it is a simple writing task or a greeting (unless the greeting contains a question after it) like Hi, Hello, How are you, etc. than a question then you need to return \`not_needed\` as the response (This is because the LLM won't need to search the web for finding information on this topic).
|
If you receive a question in a language other than English and it is related to the region, culture, or customs associated with that language, process the question in the original language. Otherwise, translate it into English and proceed with the following instructions.
|
||||||
|
If it is a smple writing task or a greeting (unless the greeting contains a question after it) like Hi, Hello, How are you, etc. than a question then you need to return \`not_needed\` as the response (This is because the LLM won't need to search the web for finding information on this topic).
|
||||||
If the user asks some question from some URL or wants you to summarize a PDF or a webpage (via URL) you need to return the links inside the \`links\` XML block and the question inside the \`question\` XML block. If the user wants to you to summarize the webpage or the PDF you need to return \`summarize\` inside the \`question\` XML block in place of a question and the link to summarize in the \`links\` XML block.
|
If the user asks some question from some URL or wants you to summarize a PDF or a webpage (via URL) you need to return the links inside the \`links\` XML block and the question inside the \`question\` XML block. If the user wants to you to summarize the webpage or the PDF you need to return \`summarize\` inside the \`question\` XML block in place of a question and the link to summarize in the \`links\` XML block.
|
||||||
You must always return the rephrased question inside the \`question\` XML block, if there are no links in the follow-up question then don't insert a \`links\` XML block in your response.
|
You must always return the rephrased question inside the \`question\` XML block, if there are no links in the follow-up question then don't insert a \`links\` XML block in your response.
|
||||||
|
|
||||||
@ -92,10 +93,6 @@ export const webSearchResponsePrompt = `
|
|||||||
- If the user provides vague input or if relevant information is missing, explain what additional details might help refine the search.
|
- If the user provides vague input or if relevant information is missing, explain what additional details might help refine the search.
|
||||||
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
||||||
|
|
||||||
### User instructions
|
|
||||||
These instructions are shared to you by the user and not by the system. You will have to follow them but give them less priority than the above instructions. If the user has provided specific instructions or preferences, incorporate them into your response while adhering to the overall guidelines.
|
|
||||||
{systemInstructions}
|
|
||||||
|
|
||||||
### Example Output
|
### Example Output
|
||||||
- Begin with a brief introduction summarizing the event or query topic.
|
- Begin with a brief introduction summarizing the event or query topic.
|
||||||
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
@ -51,10 +51,6 @@ export const wolframAlphaSearchResponsePrompt = `
|
|||||||
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
||||||
- You are set on focus mode 'Wolfram Alpha', this means you will be searching for information on the web using Wolfram Alpha. It is a computational knowledge engine that can answer factual queries and perform computations.
|
- You are set on focus mode 'Wolfram Alpha', this means you will be searching for information on the web using Wolfram Alpha. It is a computational knowledge engine that can answer factual queries and perform computations.
|
||||||
|
|
||||||
### User instructions
|
|
||||||
These instructions are shared to you by the user and not by the system. You will have to follow them but give them less priority than the above instructions. If the user has provided specific instructions or preferences, incorporate them into your response while adhering to the overall guidelines.
|
|
||||||
{systemInstructions}
|
|
||||||
|
|
||||||
### Example Output
|
### Example Output
|
||||||
- Begin with a brief introduction summarizing the event or query topic.
|
- Begin with a brief introduction summarizing the event or query topic.
|
||||||
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
@ -7,10 +7,6 @@ You have to cite the answer using [number] notation. You must cite the sentences
|
|||||||
Place these citations at the end of that particular sentence. You can cite the same sentence multiple times if it is relevant to the user's query like [number1][number2].
|
Place these citations at the end of that particular sentence. You can cite the same sentence multiple times if it is relevant to the user's query like [number1][number2].
|
||||||
However you do not need to cite it using the same number. You can use different numbers to cite the same sentence multiple times. The number refers to the number of the search result (passed in the context) used to generate that part of the answer.
|
However you do not need to cite it using the same number. You can use different numbers to cite the same sentence multiple times. The number refers to the number of the search result (passed in the context) used to generate that part of the answer.
|
||||||
|
|
||||||
### User instructions
|
|
||||||
These instructions are shared to you by the user and not by the system. You will have to follow them but give them less priority than the above instructions. If the user has provided specific instructions or preferences, incorporate them into your response while adhering to the overall guidelines.
|
|
||||||
{systemInstructions}
|
|
||||||
|
|
||||||
<context>
|
<context>
|
||||||
{context}
|
{context}
|
||||||
</context>
|
</context>
|
@ -51,10 +51,6 @@ export const youtubeSearchResponsePrompt = `
|
|||||||
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
- If no relevant information is found, say: "Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?" Be transparent about limitations and suggest alternatives or ways to reframe the query.
|
||||||
- You are set on focus mode 'Youtube', this means you will be searching for videos on the web using Youtube and providing information based on the video's transcrip
|
- You are set on focus mode 'Youtube', this means you will be searching for videos on the web using Youtube and providing information based on the video's transcrip
|
||||||
|
|
||||||
### User instructions
|
|
||||||
These instructions are shared to you by the user and not by the system. You will have to follow them but give them less priority than the above instructions. If the user has provided specific instructions or preferences, incorporate them into your response while adhering to the overall guidelines.
|
|
||||||
{systemInstructions}
|
|
||||||
|
|
||||||
### Example Output
|
### Example Output
|
||||||
- Begin with a brief introduction summarizing the event or query topic.
|
- Begin with a brief introduction summarizing the event or query topic.
|
||||||
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
- Follow with detailed sections under clear headings, covering all aspects of the query if possible.
|
66
src/routes/chats.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import logger from '../utils/logger';
|
||||||
|
import db from '../db/index';
|
||||||
|
import { eq } from 'drizzle-orm';
|
||||||
|
import { chats, messages } from '../db/schema';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get('/', async (_, res) => {
|
||||||
|
try {
|
||||||
|
let chats = await db.query.chats.findMany();
|
||||||
|
|
||||||
|
chats = chats.reverse();
|
||||||
|
|
||||||
|
return res.status(200).json({ chats: chats });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
logger.error(`Error in getting chats: ${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/:id', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const chatExists = await db.query.chats.findFirst({
|
||||||
|
where: eq(chats.id, req.params.id),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!chatExists) {
|
||||||
|
return res.status(404).json({ message: 'Chat not found' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatMessages = await db.query.messages.findMany({
|
||||||
|
where: eq(messages.chatId, req.params.id),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ chat: chatExists, messages: chatMessages });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
logger.error(`Error in getting chat: ${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.delete(`/:id`, async (req, res) => {
|
||||||
|
try {
|
||||||
|
const chatExists = await db.query.chats.findFirst({
|
||||||
|
where: eq(chats.id, req.params.id),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!chatExists) {
|
||||||
|
return res.status(404).json({ message: 'Chat not found' });
|
||||||
|
}
|
||||||
|
|
||||||
|
await db.delete(chats).where(eq(chats.id, req.params.id)).execute();
|
||||||
|
await db
|
||||||
|
.delete(messages)
|
||||||
|
.where(eq(messages.chatId, req.params.id))
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
return res.status(200).json({ message: 'Chat deleted successfully' });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
logger.error(`Error in deleting chat: ${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
104
src/routes/config.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import {
|
||||||
|
getAvailableChatModelProviders,
|
||||||
|
getAvailableEmbeddingModelProviders,
|
||||||
|
} from '../lib/providers';
|
||||||
|
import {
|
||||||
|
getGroqApiKey,
|
||||||
|
getOllamaApiEndpoint,
|
||||||
|
getAnthropicApiKey,
|
||||||
|
getGeminiApiKey,
|
||||||
|
getOpenaiApiKey,
|
||||||
|
updateConfig,
|
||||||
|
getCustomOpenaiApiUrl,
|
||||||
|
getCustomOpenaiApiKey,
|
||||||
|
getCustomOpenaiModelName,
|
||||||
|
} from '../config';
|
||||||
|
import logger from '../utils/logger';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get('/', async (_, res) => {
|
||||||
|
try {
|
||||||
|
const config = {};
|
||||||
|
|
||||||
|
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
|
||||||
|
getAvailableChatModelProviders(),
|
||||||
|
getAvailableEmbeddingModelProviders(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
config['chatModelProviders'] = {};
|
||||||
|
config['embeddingModelProviders'] = {};
|
||||||
|
|
||||||
|
for (const provider in chatModelProviders) {
|
||||||
|
config['chatModelProviders'][provider] = Object.keys(
|
||||||
|
chatModelProviders[provider],
|
||||||
|
).map((model) => {
|
||||||
|
return {
|
||||||
|
name: model,
|
||||||
|
displayName: chatModelProviders[provider][model].displayName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const provider in embeddingModelProviders) {
|
||||||
|
config['embeddingModelProviders'][provider] = Object.keys(
|
||||||
|
embeddingModelProviders[provider],
|
||||||
|
).map((model) => {
|
||||||
|
return {
|
||||||
|
name: model,
|
||||||
|
displayName: embeddingModelProviders[provider][model].displayName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
config['openaiApiKey'] = getOpenaiApiKey();
|
||||||
|
config['ollamaApiUrl'] = getOllamaApiEndpoint();
|
||||||
|
config['anthropicApiKey'] = getAnthropicApiKey();
|
||||||
|
config['groqApiKey'] = getGroqApiKey();
|
||||||
|
config['geminiApiKey'] = getGeminiApiKey();
|
||||||
|
config['customOpenaiApiUrl'] = getCustomOpenaiApiUrl();
|
||||||
|
config['customOpenaiApiKey'] = getCustomOpenaiApiKey();
|
||||||
|
config['customOpenaiModelName'] = getCustomOpenaiModelName();
|
||||||
|
|
||||||
|
res.status(200).json(config);
|
||||||
|
} catch (err: any) {
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
logger.error(`Error getting config: ${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/', async (req, res) => {
|
||||||
|
const config = req.body;
|
||||||
|
|
||||||
|
const updatedConfig = {
|
||||||
|
MODELS: {
|
||||||
|
OPENAI: {
|
||||||
|
API_KEY: config.openaiApiKey,
|
||||||
|
},
|
||||||
|
GROQ: {
|
||||||
|
API_KEY: config.groqApiKey,
|
||||||
|
},
|
||||||
|
ANTHROPIC: {
|
||||||
|
API_KEY: config.anthropicApiKey,
|
||||||
|
},
|
||||||
|
GEMINI: {
|
||||||
|
API_KEY: config.geminiApiKey,
|
||||||
|
},
|
||||||
|
OLLAMA: {
|
||||||
|
API_URL: config.ollamaApiUrl,
|
||||||
|
},
|
||||||
|
CUSTOM_OPENAI: {
|
||||||
|
API_URL: config.customOpenaiApiUrl,
|
||||||
|
API_KEY: config.customOpenaiApiKey,
|
||||||
|
MODEL_NAME: config.customOpenaiModelName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
updateConfig(updatedConfig);
|
||||||
|
|
||||||
|
res.status(200).json({ message: 'Config updated' });
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
48
src/routes/discover.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import { searchSearxng } from '../lib/searxng';
|
||||||
|
import logger from '../utils/logger';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get('/', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const data = (
|
||||||
|
await Promise.all([
|
||||||
|
searchSearxng('site:businessinsider.com AI', {
|
||||||
|
engines: ['bing news'],
|
||||||
|
pageno: 1,
|
||||||
|
}),
|
||||||
|
searchSearxng('site:www.exchangewire.com AI', {
|
||||||
|
engines: ['bing news'],
|
||||||
|
pageno: 1,
|
||||||
|
}),
|
||||||
|
searchSearxng('site:yahoo.com AI', {
|
||||||
|
engines: ['bing news'],
|
||||||
|
pageno: 1,
|
||||||
|
}),
|
||||||
|
searchSearxng('site:businessinsider.com tech', {
|
||||||
|
engines: ['bing news'],
|
||||||
|
pageno: 1,
|
||||||
|
}),
|
||||||
|
searchSearxng('site:www.exchangewire.com tech', {
|
||||||
|
engines: ['bing news'],
|
||||||
|
pageno: 1,
|
||||||
|
}),
|
||||||
|
searchSearxng('site:yahoo.com tech', {
|
||||||
|
engines: ['bing news'],
|
||||||
|
pageno: 1,
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.map((result) => result.results)
|
||||||
|
.flat()
|
||||||
|
.sort(() => Math.random() - 0.5);
|
||||||
|
|
||||||
|
return res.json({ blogs: data });
|
||||||
|
} catch (err: any) {
|
||||||
|
logger.error(`Error in discover route: ${err.message}`);
|
||||||
|
return res.status(500).json({ message: 'An error has occurred' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
82
src/routes/images.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import handleImageSearch from '../chains/imageSearchAgent';
|
||||||
|
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||||
|
import { getAvailableChatModelProviders } from '../lib/providers';
|
||||||
|
import { HumanMessage, AIMessage } from '@langchain/core/messages';
|
||||||
|
import logger from '../utils/logger';
|
||||||
|
import { ChatOpenAI } from '@langchain/openai';
|
||||||
|
import {
|
||||||
|
getCustomOpenaiApiKey,
|
||||||
|
getCustomOpenaiApiUrl,
|
||||||
|
getCustomOpenaiModelName,
|
||||||
|
} from '../config';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
interface ChatModel {
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImageSearchBody {
|
||||||
|
query: string;
|
||||||
|
chatHistory: any[];
|
||||||
|
chatModel?: ChatModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post('/', async (req, res) => {
|
||||||
|
try {
|
||||||
|
let body: ImageSearchBody = req.body;
|
||||||
|
|
||||||
|
const chatHistory = body.chatHistory.map((msg: any) => {
|
||||||
|
if (msg.role === 'user') {
|
||||||
|
return new HumanMessage(msg.content);
|
||||||
|
} else if (msg.role === 'assistant') {
|
||||||
|
return new AIMessage(msg.content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const chatModelProviders = await getAvailableChatModelProviders();
|
||||||
|
|
||||||
|
const chatModelProvider =
|
||||||
|
body.chatModel?.provider || Object.keys(chatModelProviders)[0];
|
||||||
|
const chatModel =
|
||||||
|
body.chatModel?.model ||
|
||||||
|
Object.keys(chatModelProviders[chatModelProvider])[0];
|
||||||
|
|
||||||
|
let llm: BaseChatModel | undefined;
|
||||||
|
|
||||||
|
if (body.chatModel?.provider === 'custom_openai') {
|
||||||
|
llm = new ChatOpenAI({
|
||||||
|
modelName: getCustomOpenaiModelName(),
|
||||||
|
openAIApiKey: getCustomOpenaiApiKey(),
|
||||||
|
temperature: 0.7,
|
||||||
|
configuration: {
|
||||||
|
baseURL: getCustomOpenaiApiUrl(),
|
||||||
|
},
|
||||||
|
}) as unknown as BaseChatModel;
|
||||||
|
} else if (
|
||||||
|
chatModelProviders[chatModelProvider] &&
|
||||||
|
chatModelProviders[chatModelProvider][chatModel]
|
||||||
|
) {
|
||||||
|
llm = chatModelProviders[chatModelProvider][chatModel]
|
||||||
|
.model as unknown as BaseChatModel | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!llm) {
|
||||||
|
return res.status(400).json({ message: 'Invalid model selected' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const images = await handleImageSearch(
|
||||||
|
{ query: body.query, chat_history: chatHistory },
|
||||||
|
llm,
|
||||||
|
);
|
||||||
|
|
||||||
|
res.status(200).json({ images });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
logger.error(`Error in image search: ${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
24
src/routes/index.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import imagesRouter from './images';
|
||||||
|
import videosRouter from './videos';
|
||||||
|
import configRouter from './config';
|
||||||
|
import modelsRouter from './models';
|
||||||
|
import suggestionsRouter from './suggestions';
|
||||||
|
import chatsRouter from './chats';
|
||||||
|
import searchRouter from './search';
|
||||||
|
import discoverRouter from './discover';
|
||||||
|
import uploadsRouter from './uploads';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.use('/images', imagesRouter);
|
||||||
|
router.use('/videos', videosRouter);
|
||||||
|
router.use('/config', configRouter);
|
||||||
|
router.use('/models', modelsRouter);
|
||||||
|
router.use('/suggestions', suggestionsRouter);
|
||||||
|
router.use('/chats', chatsRouter);
|
||||||
|
router.use('/search', searchRouter);
|
||||||
|
router.use('/discover', discoverRouter);
|
||||||
|
router.use('/uploads', uploadsRouter);
|
||||||
|
|
||||||
|
export default router;
|
36
src/routes/models.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import logger from '../utils/logger';
|
||||||
|
import {
|
||||||
|
getAvailableChatModelProviders,
|
||||||
|
getAvailableEmbeddingModelProviders,
|
||||||
|
} from '../lib/providers';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get('/', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
|
||||||
|
getAvailableChatModelProviders(),
|
||||||
|
getAvailableEmbeddingModelProviders(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Object.keys(chatModelProviders).forEach((provider) => {
|
||||||
|
Object.keys(chatModelProviders[provider]).forEach((model) => {
|
||||||
|
delete chatModelProviders[provider][model].model;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(embeddingModelProviders).forEach((provider) => {
|
||||||
|
Object.keys(embeddingModelProviders[provider]).forEach((model) => {
|
||||||
|
delete embeddingModelProviders[provider][model].model;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json({ chatModelProviders, embeddingModelProviders });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
logger.error(err.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
158
src/routes/search.ts
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import logger from '../utils/logger';
|
||||||
|
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||||
|
import type { Embeddings } from '@langchain/core/embeddings';
|
||||||
|
import { ChatOpenAI } from '@langchain/openai';
|
||||||
|
import {
|
||||||
|
getAvailableChatModelProviders,
|
||||||
|
getAvailableEmbeddingModelProviders,
|
||||||
|
} from '../lib/providers';
|
||||||
|
import { searchHandlers } from '../websocket/messageHandler';
|
||||||
|
import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
|
||||||
|
import { MetaSearchAgentType } from '../search/metaSearchAgent';
|
||||||
|
import {
|
||||||
|
getCustomOpenaiApiKey,
|
||||||
|
getCustomOpenaiApiUrl,
|
||||||
|
getCustomOpenaiModelName,
|
||||||
|
} from '../config';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
interface chatModel {
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
customOpenAIKey?: string;
|
||||||
|
customOpenAIBaseURL?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface embeddingModel {
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ChatRequestBody {
|
||||||
|
optimizationMode: 'speed' | 'balanced';
|
||||||
|
focusMode: string;
|
||||||
|
chatModel?: chatModel;
|
||||||
|
embeddingModel?: embeddingModel;
|
||||||
|
query: string;
|
||||||
|
history: Array<[string, string]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post('/', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const body: ChatRequestBody = req.body;
|
||||||
|
|
||||||
|
if (!body.focusMode || !body.query) {
|
||||||
|
return res.status(400).json({ message: 'Missing focus mode or query' });
|
||||||
|
}
|
||||||
|
|
||||||
|
body.history = body.history || [];
|
||||||
|
body.optimizationMode = body.optimizationMode || 'balanced';
|
||||||
|
|
||||||
|
const history: BaseMessage[] = body.history.map((msg) => {
|
||||||
|
if (msg[0] === 'human') {
|
||||||
|
return new HumanMessage({
|
||||||
|
content: msg[1],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return new AIMessage({
|
||||||
|
content: msg[1],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const [chatModelProviders, embeddingModelProviders] = await Promise.all([
|
||||||
|
getAvailableChatModelProviders(),
|
||||||
|
getAvailableEmbeddingModelProviders(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const chatModelProvider =
|
||||||
|
body.chatModel?.provider || Object.keys(chatModelProviders)[0];
|
||||||
|
const chatModel =
|
||||||
|
body.chatModel?.model ||
|
||||||
|
Object.keys(chatModelProviders[chatModelProvider])[0];
|
||||||
|
|
||||||
|
const embeddingModelProvider =
|
||||||
|
body.embeddingModel?.provider || Object.keys(embeddingModelProviders)[0];
|
||||||
|
const embeddingModel =
|
||||||
|
body.embeddingModel?.model ||
|
||||||
|
Object.keys(embeddingModelProviders[embeddingModelProvider])[0];
|
||||||
|
|
||||||
|
let llm: BaseChatModel | undefined;
|
||||||
|
let embeddings: Embeddings | undefined;
|
||||||
|
|
||||||
|
if (body.chatModel?.provider === 'custom_openai') {
|
||||||
|
llm = new ChatOpenAI({
|
||||||
|
modelName: body.chatModel?.model || getCustomOpenaiModelName(),
|
||||||
|
openAIApiKey:
|
||||||
|
body.chatModel?.customOpenAIKey || getCustomOpenaiApiKey(),
|
||||||
|
temperature: 0.7,
|
||||||
|
configuration: {
|
||||||
|
baseURL:
|
||||||
|
body.chatModel?.customOpenAIBaseURL || getCustomOpenaiApiUrl(),
|
||||||
|
},
|
||||||
|
}) as unknown as BaseChatModel;
|
||||||
|
} else if (
|
||||||
|
chatModelProviders[chatModelProvider] &&
|
||||||
|
chatModelProviders[chatModelProvider][chatModel]
|
||||||
|
) {
|
||||||
|
llm = chatModelProviders[chatModelProvider][chatModel]
|
||||||
|
.model as unknown as BaseChatModel | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
embeddingModelProviders[embeddingModelProvider] &&
|
||||||
|
embeddingModelProviders[embeddingModelProvider][embeddingModel]
|
||||||
|
) {
|
||||||
|
embeddings = embeddingModelProviders[embeddingModelProvider][
|
||||||
|
embeddingModel
|
||||||
|
].model as Embeddings | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!llm || !embeddings) {
|
||||||
|
return res.status(400).json({ message: 'Invalid model selected' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchHandler: MetaSearchAgentType = searchHandlers[body.focusMode];
|
||||||
|
|
||||||
|
if (!searchHandler) {
|
||||||
|
return res.status(400).json({ message: 'Invalid focus mode' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const emitter = await searchHandler.searchAndAnswer(
|
||||||
|
body.query,
|
||||||
|
history,
|
||||||
|
llm,
|
||||||
|
embeddings,
|
||||||
|
body.optimizationMode,
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
let message = '';
|
||||||
|
let sources = [];
|
||||||
|
|
||||||
|
emitter.on('data', (data) => {
|
||||||
|
const parsedData = JSON.parse(data);
|
||||||
|
if (parsedData.type === 'response') {
|
||||||
|
message += parsedData.data;
|
||||||
|
} else if (parsedData.type === 'sources') {
|
||||||
|
sources = parsedData.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
emitter.on('end', () => {
|
||||||
|
res.status(200).json({ message, sources });
|
||||||
|
});
|
||||||
|
|
||||||
|
emitter.on('error', (data) => {
|
||||||
|
const parsedData = JSON.parse(data);
|
||||||
|
res.status(500).json({ message: parsedData.data });
|
||||||
|
});
|
||||||
|
} catch (err: any) {
|
||||||
|
logger.error(`Error in getting search results: ${err.message}`);
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
81
src/routes/suggestions.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import express from 'express';
|
||||||
|
import generateSuggestions from '../chains/suggestionGeneratorAgent';
|
||||||
|
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||||
|
import { getAvailableChatModelProviders } from '../lib/providers';
|
||||||
|
import { HumanMessage, AIMessage } from '@langchain/core/messages';
|
||||||
|
import logger from '../utils/logger';
|
||||||
|
import { ChatOpenAI } from '@langchain/openai';
|
||||||
|
import {
|
||||||
|
getCustomOpenaiApiKey,
|
||||||
|
getCustomOpenaiApiUrl,
|
||||||
|
getCustomOpenaiModelName,
|
||||||
|
} from '../config';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
interface ChatModel {
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SuggestionsBody {
|
||||||
|
chatHistory: any[];
|
||||||
|
chatModel?: ChatModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post('/', async (req, res) => {
|
||||||
|
try {
|
||||||
|
let body: SuggestionsBody = req.body;
|
||||||
|
|
||||||
|
const chatHistory = body.chatHistory.map((msg: any) => {
|
||||||
|
if (msg.role === 'user') {
|
||||||
|
return new HumanMessage(msg.content);
|
||||||
|
} else if (msg.role === 'assistant') {
|
||||||
|
return new AIMessage(msg.content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const chatModelProviders = await getAvailableChatModelProviders();
|
||||||
|
|
||||||
|
const chatModelProvider =
|
||||||
|
body.chatModel?.provider || Object.keys(chatModelProviders)[0];
|
||||||
|
const chatModel =
|
||||||
|
body.chatModel?.model ||
|
||||||
|
Object.keys(chatModelProviders[chatModelProvider])[0];
|
||||||
|
|
||||||
|
let llm: BaseChatModel | undefined;
|
||||||
|
|
||||||
|
if (body.chatModel?.provider === 'custom_openai') {
|
||||||
|
llm = new ChatOpenAI({
|
||||||
|
modelName: getCustomOpenaiModelName(),
|
||||||
|
openAIApiKey: getCustomOpenaiApiKey(),
|
||||||
|
temperature: 0.7,
|
||||||
|
configuration: {
|
||||||
|
baseURL: getCustomOpenaiApiUrl(),
|
||||||
|
},
|
||||||
|
}) as unknown as BaseChatModel;
|
||||||
|
} else if (
|
||||||
|
chatModelProviders[chatModelProvider] &&
|
||||||
|
chatModelProviders[chatModelProvider][chatModel]
|
||||||
|
) {
|
||||||
|
llm = chatModelProviders[chatModelProvider][chatModel]
|
||||||
|
.model as unknown as BaseChatModel | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!llm) {
|
||||||
|
return res.status(400).json({ message: 'Invalid model selected' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const suggestions = await generateSuggestions(
|
||||||
|
{ chat_history: chatHistory },
|
||||||
|
llm,
|
||||||
|
);
|
||||||
|
|
||||||
|
res.status(200).json({ suggestions: suggestions });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({ message: 'An error has occurred.' });
|
||||||
|
logger.error(`Error in generating suggestions: ${err.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|