diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..9e754bd
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+patreon: KaizKhatri
+custom: https://www.paypal.me/kaizkhatri
diff --git a/.github/ISSUE_TEMPLATE/----bug-report.md b/.github/ISSUE_TEMPLATE/----bug-report.md
new file mode 100644
index 0000000..db30f32
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/----bug-report.md
@@ -0,0 +1,20 @@
+---
+name: " \U0001F41B Bug Report"
+about: Did something not work?
+title: ''
+labels: bug
+assignees: ''
+
+---
+
+## Description of the problem
+
+## How has this issue affected you? What are you trying to accomplish?
+
+### Logs or Screenshots: (optional)
+
+### Your Environment
+
+| Software | Name/Version |
+| ---------------- | ------------ |
+| Operating System | |
diff --git a/.github/ISSUE_TEMPLATE/---feature.md b/.github/ISSUE_TEMPLATE/---feature.md
new file mode 100644
index 0000000..945a67e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/---feature.md
@@ -0,0 +1,12 @@
+---
+name: "\U0001F308 Feature"
+about: " What cool thing would you like to add?"
+title: ''
+labels: enhancement
+assignees: ''
+
+---
+
+# What is this feature?
+# How the feature should work?
+# You have examples or an idea of how it can be implemented?
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..ec4bb38
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..157b9fe
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,39 @@
+
+
+## What kind of change does this PR introduce?
+
+
+
+## What is the current behavior?
+
+
+
+## What is the new behavior?
+
+
+
+## What steps did you take to test this? This is required before I can merge, make sure to test the flow you've updated.
+
+1. Step A
+2. Step B
+3. Step C
+
+## Checklist
+
+
+
+
+
+- [ ] Documentation
+- [ ] Testing
+- [ ] Ready to be merged
+- [ ] Added myself to contributors table
+
+
+
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 0000000..d9f6563
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,17 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 60
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 7
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - pinned
+ - security
+# Label to use when marking an issue as stale
+staleLabel: wontfix
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..53e5725
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,95 @@
+name: build
+
+on:
+ push:
+ paths-ignore:
+ - "**.md"
+ - "**.bbcode"
+ - LICENSE
+ branches: [main, dev]
+
+ pull_request:
+ paths-ignore:
+ - "**.md"
+ - "**.bbcode"
+ - LICENSE
+ branches: [main]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install build dependencies (apt)
+ run: |
+ sudo apt install libx11-dev libxcursor-dev libpng-dev
+ continue-on-error: false
+
+ - name: Get yarn cache directory path
+ id: yarn-cache-dir-path
+ run: echo "::set-output name=dir::$(yarn cache dir)"
+
+ - uses: actions/cache@v2
+ id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
+ with:
+ path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+ key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-
+
+ - uses: actions/setup-node@v1
+ with:
+ node-version: "12.x"
+ - run: yarn install
+ - run: yarn render
+
+ - name: Set up Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: "3.x"
+
+ - name: Cache pip dependencies
+ uses: actions/cache@v2
+ with:
+ # This path is specific to Ubuntu
+ path: ~/.cache/pip
+ # Look to see if there is a cache hit for the corresponding requirements file
+ key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
+ ${{ runner.os }}-
+
+ - name: Install pip dependencies
+ run: |
+ python -m pip install --upgrade pip
+ if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+ continue-on-error: false
+
+ - name: Generating `GoogleDot` Cursor Theme
+ run: python build.py
+
+ - name: Compressing Artifacts
+ run: |
+ tar -cvzf logs.tar.gz build.log
+ tar -cvzf bitmaps.tar.gz bitmaps
+ tar -cvzf GoogleDot.tar.gz themes
+
+ - name: Uploading `GoogleDot` Build Log artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: logs
+ path: logs.tar.gz
+
+ - name: Uploading `bitmaps` artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: bitmaps
+ path: bitmaps.tar.gz
+
+ - name: Uploading `GoogleDot` Theme artifact
+ uses: actions/upload-artifact@v2
+ with:
+ name: GoogleDot
+ path: GoogleDot.tar.gz
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b616e64..1a7652e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,3 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [unreleased]
+
+## [v1.0.0] - 27 Oct 2020
+
+### Added
+
+- Initial release π
+- Logo and badges
+- CI/CD Pipelines
+
+[unreleased]: https://github.com/ful1e5/Google_Cursor/compare/v1.0.0...main
+[v1.0.0]: https://github.com/ful1e5/Google_Cursor/tree/v1.0.0
diff --git a/PLING.bbcode b/PLING.bbcode
new file mode 100644
index 0000000..777f068
--- /dev/null
+++ b/PLING.bbcode
@@ -0,0 +1,40 @@
+[b]GoogleDot [/b] Cursor Theme with [b]HiDPi[/b] Display support. This Cursor is built with [b][url=https://github.com/ful1e5/clickgen]clickgen[/url][/b] and render with the [b][url=https://github.com/puppeteer/puppeteer/]puppeteer[/url][/b].
+[i]Available Sizes[/i] [b]22, 24, 28, 32, 40, 48, 56, 64, 72, 80, 88, 96
+
+[/b][i]Get latest build[/i] @[b][url=https://github.com/ful1e5/Google_Cursor/actions]GitHub Actions[/url][/b]
+[i]Release Notification[/i] at [b][url=https://twitter.com/ful1e5]Twitter[/url][/b](@ful1e5)
+
+[b]Linux/X11 installation[/b]
+Get the latest stable Linux release from the [b][url=https://www.pling.com/p/1215613#files-panel]Pling[/url][/b]. Unpack [b].tar.gz[/b] file and follow these [b]commands[/b].
+
+[b]Install[/b]
+[b]For all user:[/b]
+[code]sudo mv GoogleDot /usr/share/icons[/code]
+[b]For local user:[/b]
+[code]mv GoogleDot ~/.icons[/code]
+
+[b]Uninstall[/b]
+[b]From all user:[/b]
+[code]sudo rm -r /usr/share/icons/GoogleDot[/code]
+[b]From local user:[/b]
+[code]rm -r ~/.icons/GoogleDot[/code]
+
+[b]Window installation[/b]
+[list=1]
+ [*]unzip [b]GoogleDot_Windows.zip[/b] file[/*]
+ [*]Open [b]GoogleDot_Windows/[/b] in Explorer, and [b]right-click[/b] on [b]install.inf[/b].[/*]
+ [*]Click 'Install' from the context menu, and authorise the modifications to your system.[/*]
+ [*]Open [i]Control Panel > Personalisation and Appearance > Change mouse pointers[/i], and select [b]GoogleDot Cursors[/b].[/*]
+ [*]Click '[b]Apply[/b]'.[/*]
+[/list]
+
+[b]How I help the Creator?[/b]
+[list=2]
+ [*]Give a [b]Star[/b] or [b]Follow[/b] on [b][url=https://github.com/ful1e5/Google_Cursor]GitHub[/url][/b] (issues & PullRequest are welcome).[/*]
+ [*]By giving a [b]Pling[/b] or [b][url=https://www.paypal.me/kaizkhatri]Donation[/url][/b].[/*]
+ [*][b]Download[/b] from[url=https://www.pling.com/p/1408466/] Pling.com[/url] Product page that helps to [b]increases[/b] my [b]monthly payout[/b].[/*]
+ [*][b][url=https://www.pling.com/support]Become Supporter of Pling.com[/url][/b], So we become [b]Full-Time [/b]Libre & FOSS content creator [b];)[/b][/*]
+[/list]
+
+[b]License & Terms[/b]
+'[b]GoogleDot[/b]' Cursor Theme is available under the terms of the [b]GPL-3.0[/b] license.
\ No newline at end of file
diff --git a/README.md b/README.md
index e515309..6cba4ae 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,282 @@
-# Google_Cursor
+
+
+
+
+ π Cursor theme inspired on Google
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+---
+
+
+
+# GoogleDot Cursor
+
+Cursor theme inspired on **google material design** for `Windows` and `Linux` with _HiDPi Support_ π.
+
+#### Cursor Sizes
+
+22
+24
+28
+32
+40
+48
+56
+64
+72
+80
+88
+96
+
+#### Colors
+
+![#4285F4](https://imgur.com/NXEup6E.png)
+![#FFFFFF](https://imgur.com/cvFxSBb.png)
+
+#### Quick install
+
+
+
+
+
+
+
+#### Preview:
+
+> Detailed Cursors Informations inside [src/svgs/README.md](https://github.com/ful1e5/Google_Cursor/blob/main/src/svg/README.md)
+
+
+
+
+
+
+ GoogleDot Cursors π
+
+
+
+### Manual Install
+
+#### Linux/X11
+
+```bash
+# extract `GoogleDot.tar.gz`
+tar -xvf GoogleDot.tar.gz
+
+# For local users
+mv GoogleDot ~/.icons/
+
+# For all users
+sudo mv GoogleDot /usr/share/icons/
+```
+
+
+#### Windows
+
+1. unzip `GoogleDot_Windows.zip` file
+2. Open `GoogleDot_Windows/` in Explorer, and **right click** on `install.inf`.
+3. Click 'Install' from the context menu, and authorize the modifications to your system.
+4. Open _Control Panel > Personalization and Appearance > Change mouse pointers_, and select **GoogleDot Cursors**.
+5. Click '**Apply**'.
+
+
+
+# Dependencies
+
+## Runtime Dependencies
+
+- libxcursor-dev
+- libx11-dev
+- libpng-dev (<=1.6)
+
+#### Install Runtime Dependencies
+
+##### macOS
+
+```bash
+brew cask install xquartz libpng
+```
+
+##### Debain/ubuntu
+
+```bash
+sudo apt install libx11-dev libxcursor-dev libpng-dev
+```
+
+##### ArchLinux/Manjaro
+
+```bash
+sudo pacman -S libx11 libxcursor libpng
+```
+
+##### Fedora/Fedora Silverblue/CentOS/RHEL
+
+```bash
+sudo dnf install libx11-devel libxcursor-devel libpng-devel
+```
+
+## Build Dependencies
+
+- [nodejs](https://nodejs.org/en/) (<=12.x.x)
+- [yarn](https://classic.yarnpkg.com/en/docs/install/)
+- [python](https://www.python.org/downloads/) (<=3.6)
+- [pip3](https://pip.pypa.io/en/stable/installing/)
+
+### Node Packages
+
+- [puppeteer](https://www.npmjs.com/package/puppeteer)
+- [pngjs](https://www.npmjs.com/package/pngjs)
+- [pixelmatch](https://www.npmjs.com/package/pixelmatch)
+
+### PyPi Packages
+
+- [clickgen](https://pypi.org/project/clickgen/s)
+- [Pillow](https://pypi.org/project/Pillow/)
+
+## Build From Scratch
+
+### β‘ Auto Build (using GitHub Actions)
+
+GitHub Actions is automatically runs on every `push`(on **main** and **dev** branches) and `pull request`(on **main** branch), You found theme resources in `artifact` section of **build**.GitHub **Actions** available inside [.github/workflows](https://github.com/ful1e5/Google_Cursor/tree/main/.github/workflows) directory.
+
+### Manual Build
+
+#### Setup python environment
+
+```bash
+python3 -m pip install --upgrade pip # Update pip to latest
+python3 -m pip3 install virtualenv # Install python virtual environment
+virtualenv venv # Create new virtualenv named `venv`
+source venv/bin/activate # Activate virtualenv
+
+# For Deactivate virtualenv
+deactivate
+```
+
+#### Compile From Source
+
+> Make sure your [python environment](#setup-python-environment) setup and `virtualenv` is **active**.
+
+```bash
+yarn install # Install all Node Packages
+yarn py_install # Install all PyPi Packages
+yarn compile # Compile the cursor theme
+```
+
+After build `bitmaps` and `themes` directory are generated at project **root**.
+
+### Install Build Theme
+
+All builded cursor themes are available inside `themes` directory.
+
+#### Linux
+
+```bash
+cd ./themes
+rm -rf ~/.icons/GoogleDot && cp GoogleDot ~/.icons/ # installing Theme to local user(recommend)
+```
+
+#### Windows
+
+1. unzip `GoogleDot_Windows.zip` file
+2. Open the `settings` app.
+3. **Goto** `Devices` -> `Mouse` -> `Additional Mouse Options`.
+4. **Goto** the `pointers` tab.
+5. Replace each cursor in the currently applied cursor set with the corresponding cursor in the `GoogleDot_Windows` folder.
+6. Click "**save as**" and type in the desired name.
+7. Click "**apply**" and "**ok**".
+
+
+
+# Bugs
+
+Bugs π should be reported [here](https://github.com/ful1e5/Google_Cursor/issues) on the Github issues page.
+
+
+
+# Getting Help
+
+You can create a **issue**, I will help you. π
+
+
+
+# Contributing
+
+Check [CONTRIBUTING.md](CONTRIBUTING.md), any suggestions for features and contributions to the continuing code masterelopment can be made via the issue tracker or code contributions via a `Fork` & `Pull requests`.
+
+
+
+## Support
+
+Give a **β
** or Follow on [GitHub](https://github.com/ful1e5),That's work as **Steroid π** for me. π
+
+> For extra support
+
+
+
+
+
+
+
+
+ ( `ΟΒ΄ )ΫΆβ¬ΞΉβββββββοΊ€
+
+
+ I'm Using Katana
+
\ No newline at end of file
diff --git a/build.py b/build.py
new file mode 100644
index 0000000..2382e1a
--- /dev/null
+++ b/build.py
@@ -0,0 +1,16 @@
+import log
+from clickgen import build_cursor_theme
+
+from config import name, sizes, delay, bitmaps_dir, temp_folder
+from helper import init_build, pack_it
+
+
+def build() -> None:
+ init_build()
+ build_cursor_theme(name, image_dir=bitmaps_dir,
+ cursor_sizes=sizes, out_path=temp_folder, hotspots=None, archive=False, delay=delay)
+ pack_it()
+
+
+if __name__ == "__main__":
+ build()
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..fe475cb
--- /dev/null
+++ b/config.py
@@ -0,0 +1,46 @@
+import tempfile
+import json
+
+# Build Config
+delay = 50
+name = "GoogleDot"
+sizes = [22, 24, 28, 32, 40, 48, 56, 64, 72, 80, 88, 96]
+
+bitmaps_dir = "./bitmaps"
+package_dir = "./themes"
+temp_folder = tempfile.mkdtemp()
+
+# Cleanup Configs
+x11_out = name
+win_out = name + "-Windows"
+
+# getting author name
+with open("./package.json") as f:
+ data = json.loads(f.read())
+ author = data["author"]
+
+# Windows Cursors Config
+windows_cursors = {
+ "left_ptr_watch.ani": "AppStarting.ani",
+ "left_ptr.cur": "Arrow.cur",
+ "crosshair.cur": "Cross.cur",
+ "hand2.cur": "Hand.cur",
+ "pencil.cur": "Handwriting.cur",
+ "dnd-ask.cur": "Help.cur",
+ "xterm.cur": "IBeam.cur",
+ "circle.cur": "NO.cur",
+ "all-scroll.cur": "SizeAll.cur",
+ "bd_double_arrow.cur": "SizeNWSE.cur",
+ "sb_v_double_arrow.cur": "SizeNS.cur",
+ "fd_double_arrow.cur": "SizeNESW.cur",
+ "sb_h_double_arrow.cur": "SizeWE.cur",
+ "sb_up_arrow.cur": "UpArrow.cur",
+ "wait.ani": "Wait.ani",
+}
+
+# Windows install.inf file content
+with open("./scripts/windows.inf") as f:
+ data = f.read()
+ window_install_inf_content = data.replace(
+ "", name + " Cursors"
+ ).replace("", author)
diff --git a/helper.py b/helper.py
new file mode 100644
index 0000000..cc88968
--- /dev/null
+++ b/helper.py
@@ -0,0 +1,71 @@
+import shutil
+import json
+import sys
+
+from config import (
+ name,
+ temp_folder,
+ bitmaps_dir,
+ win_out,
+ x11_out,
+ window_install_inf_content,
+ windows_cursors,
+ package_dir,
+)
+from os import path, listdir, rename, remove
+
+
+x11_out_dir = path.join(package_dir, x11_out)
+win_out_dir = path.join(package_dir, win_out)
+
+
+def window_bundle() -> None:
+ # Remove & Rename cursors
+ # If Key found => Rename else Remove
+ for cursor in listdir(win_out_dir):
+ old_path = path.join(win_out_dir, cursor)
+
+ try:
+ new_path = path.join(win_out_dir, windows_cursors[cursor])
+ rename(old_path, new_path)
+ except KeyError:
+ remove(old_path)
+
+ # creating install.inf file
+ install_inf_path = path.join(win_out_dir, "install.inf")
+ with open(install_inf_path, "w") as file:
+ file.write(window_install_inf_content)
+
+
+def init_build() -> None:
+ """
+ Print build version.
+ Remove previously built packages && Check Bitmaps.
+ """
+ with open("./package.json", "r") as package_file:
+ data = json.loads(package_file.read())
+ version = data["version"]
+ print("β‘ GoogleDot Builder v%s" % version)
+
+ # cleanup old packages
+ if path.exists(package_dir):
+ shutil.rmtree(package_dir)
+
+ # Checking Bitmaps directory
+ if not path.exists(bitmaps_dir):
+ print(
+ "β BITMAPS NOT FOUND.\n\n`yarn install && yarn render` to Generates Bitmaps"
+ )
+ sys.exit(1)
+
+
+def pack_it() -> None:
+ """
+ Create Crisp π¦ Packages for Windows & X11 Cursor Theme.
+ """
+ # Rename directory
+ shutil.move(path.join(temp_folder, name, "x11"), x11_out_dir)
+ shutil.move(path.join(temp_folder, name, "win"), win_out_dir)
+
+ # create install.inf file in Windows Theme
+ window_bundle()
diff --git a/log.py b/log.py
new file mode 100644
index 0000000..0e8767e
--- /dev/null
+++ b/log.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+
+import logging
+
+logging.basicConfig(
+ filename="build.log",
+ filemode="w",
+ format="%(name)s - %(levelname)s - %(message)s",
+ level=logging.DEBUG,
+)
diff --git a/nodemon.json b/nodemon.json
new file mode 100644
index 0000000..cde9605
--- /dev/null
+++ b/nodemon.json
@@ -0,0 +1,13 @@
+{
+ "restartable": "rs",
+ "ignore": [".git", "node_modules/**/node_modules"],
+ "verbose": true,
+ "execMap": {
+ "ts": "node --require ts-node/register"
+ },
+ "watch": ["src/"],
+ "env": {
+ "NODE_ENV": "development"
+ },
+ "ext": "js,json,ts"
+}
diff --git a/package.json b/package.json
index 14a33a3..a1e9bef 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,15 @@
"author": "Kaiz Khatri",
"license": "GPL-3.0",
"private": true,
+ "scripts": {
+ "clean": "rm -rf bitmaps themes",
+ "dev": "nodemon src/index.ts",
+ "watch": "nodemon --inspect src/index.ts",
+ "py_install": "pip install -r requirements.txt",
+ "render": "npx ts-node src/index.ts",
+ "build": "python build.py",
+ "compile": "yarn clean && yarn render && yarn build"
+ },
"devDependencies": {
"@types/pixelmatch": "^5.2.2",
"@types/pngjs": "^3.4.2",
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..dbfa3c9
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
+clickgen==1.1.7
+Pillow<=8.0.1
diff --git a/scripts/windows.inf b/scripts/windows.inf
new file mode 100644
index 0000000..0586241
--- /dev/null
+++ b/scripts/windows.inf
@@ -0,0 +1,52 @@
+[Version]
+signature="$CHICAGO$"
+ By Kaiz Khatri
+https://github.com/ful1e5/apple_cursor
+
+[DefaultInstall]
+CopyFiles = Scheme.Cur
+AddReg = Scheme.Reg
+
+[DestinationDirs]
+Scheme.Cur = 10,"%CUR_DIR%"
+
+[Scheme.Reg]
+HKCU,"Control Panel\Cursors\Schemes","%SCHEME_NAME%",,"%10%\%CUR_DIR%\%pointer%,%10%\%CUR_DIR%\%help%,%10%\%CUR_DIR%\%work%,%10%\%CUR_DIR%\%busy%,%10%\%CUR_DIR%\%Cross%,%10%\%CUR_DIR%\%Text%,%10%\%CUR_DIR%\%Hand%,%10%\%CUR_DIR%\%Unavailiable%,%10%\%CUR_DIR%\%Vert%,%10%\%CUR_DIR%\%Horz%,%10%\%CUR_DIR%\%Dgn1%,%10%\%CUR_DIR%\%Dgn2%,%10%\%CUR_DIR%\%move%,%10%\%CUR_DIR%\%alternate%,%10%\%CUR_DIR%\%link%"
+
+; -- Installed files
+
+[Scheme.Cur]
+"Arrow.cur"
+"Help.cur"
+"AppStarting.ani"
+"Wait.ani"
+"Cross.cur"
+"IBeam.cur"
+"Handwriting.cur"
+"NO.cur"
+"SizeNS.cur"
+"SizeWE.cur"
+"SizeNWSE.cur"
+"SizeNESW.cur"
+"SizeAll.cur"
+"UpArrow.cur"
+"Hand.cur"
+
+[Strings]
+CUR_DIR = "Cursors\"
+SCHEME_NAME = ""
+pointer = "Arrow.cur"
+help = "Help.cur"
+work = "AppStarting.ani"
+busy = "Wait.ani"
+cross = "Cross.cur"
+text = "IBeam.cur"
+hand = "Handwriting.cur"
+unavailiable = "NO.cur"
+vert = "SizeNS.cur"
+horz = "SizeWE.cur"
+dgn1 = "SizeNWSE.cur"
+dgn2 = "SizeNESW.cur"
+move = "SizeAll.cur"
+alternate = "UpArrow.cur"
+link = "Hand.cur"
\ No newline at end of file
diff --git a/src/config.ts b/src/config.ts
new file mode 100644
index 0000000..843b7b5
--- /dev/null
+++ b/src/config.ts
@@ -0,0 +1,31 @@
+import { resolve } from "path";
+import { readdirSync, existsSync } from "fs";
+
+// Source Directory
+const svgsDir = resolve(__dirname, "svg");
+if (!existsSync(svgsDir)) {
+ console.log("Source .svg files not found");
+}
+
+const staticCursorsDir = resolve(svgsDir, "static");
+const animatedCursorsDir = resolve(svgsDir, "animated");
+
+// Out Directory
+const bitmapsDir = resolve(__dirname, "../", "bitmaps");
+
+// Cursors
+const staticCursors = readdirSync(staticCursorsDir).map((f) =>
+ resolve(staticCursorsDir, f)
+);
+const animatedCursors = readdirSync(animatedCursorsDir).map((f) =>
+ resolve(animatedCursorsDir, f)
+);
+
+// Animated Config
+const animatedClip = {
+ x: 4,
+ y: 4,
+ width: 200,
+ height: 200,
+};
+export { staticCursors, animatedCursors, bitmapsDir, animatedClip };
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..5007114
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,124 @@
+import fs from "fs";
+import path from "path";
+import puppeteer from "puppeteer";
+
+import { generateRenderTemplate } from "./utils/htmlTemplate";
+import {
+ staticCursors,
+ bitmapsDir,
+ animatedCursors,
+ animatedClip,
+} from "./config";
+import { matchImages } from "./utils/matchImages";
+import { saveFrames, Frames } from "./utils/saveFrames";
+import { getFrameName } from "./utils/getFrameName";
+
+const main = async () => {
+ const browser = await puppeteer.launch({
+ ignoreDefaultArgs: [" --single-process ", "--no-sandbox"],
+ headless: true,
+ });
+
+ if (!fs.existsSync(bitmapsDir)) {
+ fs.mkdirSync(bitmapsDir);
+ }
+
+ try {
+ console.log("πΈ Rendering Static Cursors...");
+
+ for (let svgPath of staticCursors) {
+ const buffer = fs.readFileSync(path.resolve(svgPath), "utf8");
+ if (!buffer) throw new Error(`${svgPath} File Read error`);
+
+ // Generating HTML Template
+ const data = buffer.toString();
+ const template = generateRenderTemplate(data);
+
+ // config
+ const bitmapName = `${path.basename(svgPath, ".svg")}.png`;
+ const out = path.resolve(bitmapsDir, bitmapName);
+
+ // Render
+ const page = await browser.newPage();
+ await page.setContent(template);
+
+ await page.waitForSelector("#container");
+ const svgElement = await page.$("#container svg");
+ if (!svgElement) throw new Error("svg element not found");
+ await svgElement.screenshot({ omitBackground: true, path: out });
+
+ await page.close();
+ }
+
+ console.log("π₯ Rendering Animated Cursors...");
+
+ for (let svgPath of animatedCursors) {
+ const buffer = fs.readFileSync(svgPath, "utf8");
+ if (!buffer) throw new Error(`${svgPath} File Read error`);
+
+ // Generating HTML Template
+ const data = buffer.toString();
+ const template = generateRenderTemplate(data);
+
+ const page = await browser.newPage();
+ await page.setContent(template, { waitUntil: "networkidle2" });
+
+ await page.waitForSelector("#container");
+ const svgElement = await page.$("#container svg");
+ if (!svgElement) throw new Error("svg element not found");
+
+ // Render Config
+ let index = 1;
+ let breakRendering = false;
+ const frames: Frames = {};
+ const firstKey = getFrameName(index, svgPath);
+
+ console.log("Rendering", path.basename(svgPath), "...");
+ console.log(firstKey);
+
+ // 1st Frame
+ frames[firstKey] = {
+ buffer: await svgElement.screenshot({
+ omitBackground: true,
+ clip: animatedClip,
+ encoding: "binary",
+ }),
+ };
+
+ // Pushing frames until it match to 1st frame
+ index++;
+ while (!breakRendering) {
+ const newFrame = await svgElement.screenshot({
+ omitBackground: true,
+ clip: animatedClip,
+ encoding: "binary",
+ });
+ const key = getFrameName(index, svgPath);
+ console.log(key);
+ const diff = matchImages({
+ img1Buff: frames[firstKey].buffer,
+ img2Buff: newFrame,
+ });
+
+ if (!(diff < 700)) {
+ frames[key] = { buffer: newFrame };
+ } else {
+ breakRendering = true;
+ }
+ index++;
+ }
+
+ saveFrames(frames);
+
+ await page.close();
+ }
+
+ console.log(`\nBitmaps stored at ${bitmapsDir}\n\nπ Render Done.`);
+ process.exit(0);
+ } catch (error) {
+ console.error(error);
+ process.exit(1);
+ }
+};
+
+main();
diff --git a/src/svg/README.md b/src/svg/README.md
new file mode 100644
index 0000000..e3d6153
--- /dev/null
+++ b/src/svg/README.md
@@ -0,0 +1,52 @@
+# Cursor Source Info
+
+## Symbolic Cursors
+
+| Preview | Source | Symbolic links | Windows Cursor name |
+| :-------------------------------------------------------: | :---------------------: | :-------------------------------------------------------------: | :--------------------------: |
+| | all_scroll.svg | `None` | `SizeAll.cur` |
+| | bottom_left_corner.svg | `fd_double_arrow.svg` `top_right_corner.svg` | `SizeNESW.cur` |
+| | bottom_right_corner.svg | `bd_double_arrow.svg` `top_left_corner.svg` | `SizeNWSE.cur` |
+| | bottom_tee.svg | `None` | |
+| | center_ptr.svg | `None` | |
+| | circle.svg | `crossed_circle.svg` `dnd_no_drop.svg` | `NO.cur` |
+| | context_menu.svg | `None` | |
+| | copy.svg | `dnd_copy.svg` | |
+| | cross.svg | `tcross.svg` | |
+| | crosshair.svg | `None` | `Cross.cur` |
+| | dotbox.svg | `None` | |
+| | hand1.svg | `None` | |
+| | hand2.svg | `None` | `Hand.cur` |
+| | left_ptr.svg | `None` | `Arrow.cur` |
+| | left_side.svg | `right_side.svg` | |
+| | left_tee.svg | `None` | |
+| | link.svg | `dnd_link.svg` | |
+| | ll_angle.svg | `None` | |
+| | lr_angle.svg | `None` | |
+| | move.svg | `dnd_move.svg` `dnd_none.svg` `grabbing.svg` `pointer_move.svg` | |
+| | pencil.svg | `None` | `Handwriting.cur` |
+| | plus.svg | `None` | |
+| | question_arrow.svg | `dnd_ask.svg` | `Help.cur` |
+| | right_ptr.svg | `None` | |
+| | right_tee.svg | `None` | |
+| | sb_down_arrow.svg | `None` | |
+| | sb_h_double_arrow.svg | `None` | `SizeWE.cur` |
+| | sb_left_arrow.svg | `None` | |
+| | sb_right_arrow.svg | `None` | |
+| | sb_up_arrow.svg | `None` | `UpArrow.cur` |
+| | sb_v_double_arrow.svg | `None` | `SizeNS.cur` |
+| | top_side.svg | `bottom_side.svg` | |
+| | top_tee.svg | `None` | |
+| | ul_angle.svg | `None` | |
+| | ur_angle.svg | `None` | |
+| | vertical_text.svg | `None` | |
+| | wait.svg | `left_ptr_watch.svg` | `AppStarting.ani` `Wait.ani` |
+| | wayland_cursor.svg | `None` | |
+| | x_cursor.svg | `None` | |
+| | xterm.svg | `None` | `IBeam.cur` |
+| | zoom_in.svg | `None` | |
+| | zoom_out.svg | `None` | |
+
+
+
+
diff --git a/src/svg/animated/left_ptr_watch.svg b/src/svg/animated/left_ptr_watch.svg
new file mode 120000
index 0000000..89f76d4
--- /dev/null
+++ b/src/svg/animated/left_ptr_watch.svg
@@ -0,0 +1 @@
+wait.svg
\ No newline at end of file
diff --git a/src/svg/animated/wait.svg b/src/svg/animated/wait.svg
new file mode 100644
index 0000000..fb03daa
--- /dev/null
+++ b/src/svg/animated/wait.svg
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/all_scroll.svg b/src/svg/static/all_scroll.svg
new file mode 120000
index 0000000..37362fe
--- /dev/null
+++ b/src/svg/static/all_scroll.svg
@@ -0,0 +1 @@
+move.svg
\ No newline at end of file
diff --git a/src/svg/static/bd_double_arrow.svg b/src/svg/static/bd_double_arrow.svg
new file mode 120000
index 0000000..a3a3e2d
--- /dev/null
+++ b/src/svg/static/bd_double_arrow.svg
@@ -0,0 +1 @@
+bottom_right_corner.svg
\ No newline at end of file
diff --git a/src/svg/static/bottom_left_corner.svg b/src/svg/static/bottom_left_corner.svg
new file mode 100644
index 0000000..ecc4ea4
--- /dev/null
+++ b/src/svg/static/bottom_left_corner.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/bottom_right_corner.svg b/src/svg/static/bottom_right_corner.svg
new file mode 100644
index 0000000..47603fa
--- /dev/null
+++ b/src/svg/static/bottom_right_corner.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/bottom_side.svg b/src/svg/static/bottom_side.svg
new file mode 120000
index 0000000..9c7bb92
--- /dev/null
+++ b/src/svg/static/bottom_side.svg
@@ -0,0 +1 @@
+top_side.svg
\ No newline at end of file
diff --git a/src/svg/static/bottom_tee.svg b/src/svg/static/bottom_tee.svg
new file mode 100644
index 0000000..f6dc412
--- /dev/null
+++ b/src/svg/static/bottom_tee.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/center_ptr.svg b/src/svg/static/center_ptr.svg
new file mode 100644
index 0000000..304f6ef
--- /dev/null
+++ b/src/svg/static/center_ptr.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/circle.svg b/src/svg/static/circle.svg
new file mode 100644
index 0000000..9392cf4
--- /dev/null
+++ b/src/svg/static/circle.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/context_menu.svg b/src/svg/static/context_menu.svg
new file mode 100644
index 0000000..43e14f9
--- /dev/null
+++ b/src/svg/static/context_menu.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/copy.svg b/src/svg/static/copy.svg
new file mode 100644
index 0000000..1387ec4
--- /dev/null
+++ b/src/svg/static/copy.svg
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/cross.svg b/src/svg/static/cross.svg
new file mode 100644
index 0000000..d894d8d
--- /dev/null
+++ b/src/svg/static/cross.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/crossed_circle.svg b/src/svg/static/crossed_circle.svg
new file mode 100644
index 0000000..8535691
--- /dev/null
+++ b/src/svg/static/crossed_circle.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/crosshair.svg b/src/svg/static/crosshair.svg
new file mode 100644
index 0000000..09f696f
--- /dev/null
+++ b/src/svg/static/crosshair.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/dnd_ask.svg b/src/svg/static/dnd_ask.svg
new file mode 120000
index 0000000..14c57d2
--- /dev/null
+++ b/src/svg/static/dnd_ask.svg
@@ -0,0 +1 @@
+question_arrow.svg
\ No newline at end of file
diff --git a/src/svg/static/dnd_copy.svg b/src/svg/static/dnd_copy.svg
new file mode 120000
index 0000000..4b1d7e7
--- /dev/null
+++ b/src/svg/static/dnd_copy.svg
@@ -0,0 +1 @@
+copy.svg
\ No newline at end of file
diff --git a/src/svg/static/dnd_link.svg b/src/svg/static/dnd_link.svg
new file mode 120000
index 0000000..4abb12d
--- /dev/null
+++ b/src/svg/static/dnd_link.svg
@@ -0,0 +1 @@
+link.svg
\ No newline at end of file
diff --git a/src/svg/static/dnd_move.svg b/src/svg/static/dnd_move.svg
new file mode 120000
index 0000000..37362fe
--- /dev/null
+++ b/src/svg/static/dnd_move.svg
@@ -0,0 +1 @@
+move.svg
\ No newline at end of file
diff --git a/src/svg/static/dnd_no_drop.svg b/src/svg/static/dnd_no_drop.svg
new file mode 100644
index 0000000..f636fbe
--- /dev/null
+++ b/src/svg/static/dnd_no_drop.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/dnd_none.svg b/src/svg/static/dnd_none.svg
new file mode 120000
index 0000000..37362fe
--- /dev/null
+++ b/src/svg/static/dnd_none.svg
@@ -0,0 +1 @@
+move.svg
\ No newline at end of file
diff --git a/src/svg/static/dotbox.svg b/src/svg/static/dotbox.svg
new file mode 100644
index 0000000..32e58c9
--- /dev/null
+++ b/src/svg/static/dotbox.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/fd_double_arrow.svg b/src/svg/static/fd_double_arrow.svg
new file mode 120000
index 0000000..acc15d0
--- /dev/null
+++ b/src/svg/static/fd_double_arrow.svg
@@ -0,0 +1 @@
+bottom_left_corner.svg
\ No newline at end of file
diff --git a/src/svg/static/grabbing.svg b/src/svg/static/grabbing.svg
new file mode 120000
index 0000000..37362fe
--- /dev/null
+++ b/src/svg/static/grabbing.svg
@@ -0,0 +1 @@
+move.svg
\ No newline at end of file
diff --git a/src/svg/static/hand1.svg b/src/svg/static/hand1.svg
new file mode 100644
index 0000000..1b65ca7
--- /dev/null
+++ b/src/svg/static/hand1.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/hand2.svg b/src/svg/static/hand2.svg
new file mode 100644
index 0000000..172f354
--- /dev/null
+++ b/src/svg/static/hand2.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/left_ptr.svg b/src/svg/static/left_ptr.svg
new file mode 100644
index 0000000..bf8f500
--- /dev/null
+++ b/src/svg/static/left_ptr.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/left_side.svg b/src/svg/static/left_side.svg
new file mode 100644
index 0000000..0982847
--- /dev/null
+++ b/src/svg/static/left_side.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/left_tee.svg b/src/svg/static/left_tee.svg
new file mode 100644
index 0000000..c14a78d
--- /dev/null
+++ b/src/svg/static/left_tee.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/link.svg b/src/svg/static/link.svg
new file mode 100644
index 0000000..cb2e097
--- /dev/null
+++ b/src/svg/static/link.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/ll_angle.svg b/src/svg/static/ll_angle.svg
new file mode 100644
index 0000000..78fc6a3
--- /dev/null
+++ b/src/svg/static/ll_angle.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/lr_angle.svg b/src/svg/static/lr_angle.svg
new file mode 100644
index 0000000..7184991
--- /dev/null
+++ b/src/svg/static/lr_angle.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/move.svg b/src/svg/static/move.svg
new file mode 100644
index 0000000..2cff4c2
--- /dev/null
+++ b/src/svg/static/move.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/pencil.svg b/src/svg/static/pencil.svg
new file mode 100644
index 0000000..baa6c99
--- /dev/null
+++ b/src/svg/static/pencil.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/plus.svg b/src/svg/static/plus.svg
new file mode 100644
index 0000000..10d4426
--- /dev/null
+++ b/src/svg/static/plus.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/pointer_move.svg b/src/svg/static/pointer_move.svg
new file mode 120000
index 0000000..37362fe
--- /dev/null
+++ b/src/svg/static/pointer_move.svg
@@ -0,0 +1 @@
+move.svg
\ No newline at end of file
diff --git a/src/svg/static/question_arrow.svg b/src/svg/static/question_arrow.svg
new file mode 100644
index 0000000..272e764
--- /dev/null
+++ b/src/svg/static/question_arrow.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/right_ptr.svg b/src/svg/static/right_ptr.svg
new file mode 100644
index 0000000..8dcbe1e
--- /dev/null
+++ b/src/svg/static/right_ptr.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/right_side.svg b/src/svg/static/right_side.svg
new file mode 120000
index 0000000..36e195a
--- /dev/null
+++ b/src/svg/static/right_side.svg
@@ -0,0 +1 @@
+left_side.svg
\ No newline at end of file
diff --git a/src/svg/static/right_tee.svg b/src/svg/static/right_tee.svg
new file mode 100644
index 0000000..8ba22f7
--- /dev/null
+++ b/src/svg/static/right_tee.svg
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/sb_down_arrow.svg b/src/svg/static/sb_down_arrow.svg
new file mode 100644
index 0000000..8f96717
--- /dev/null
+++ b/src/svg/static/sb_down_arrow.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/sb_h_double_arrow.svg b/src/svg/static/sb_h_double_arrow.svg
new file mode 100644
index 0000000..1a2f351
--- /dev/null
+++ b/src/svg/static/sb_h_double_arrow.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/sb_left_arrow.svg b/src/svg/static/sb_left_arrow.svg
new file mode 100644
index 0000000..6491106
--- /dev/null
+++ b/src/svg/static/sb_left_arrow.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/sb_right_arrow.svg b/src/svg/static/sb_right_arrow.svg
new file mode 100644
index 0000000..47f3f56
--- /dev/null
+++ b/src/svg/static/sb_right_arrow.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/sb_up_arrow.svg b/src/svg/static/sb_up_arrow.svg
new file mode 100644
index 0000000..627e252
--- /dev/null
+++ b/src/svg/static/sb_up_arrow.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/sb_v_double_arrow.svg b/src/svg/static/sb_v_double_arrow.svg
new file mode 100644
index 0000000..0b3757f
--- /dev/null
+++ b/src/svg/static/sb_v_double_arrow.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/tcross.svg b/src/svg/static/tcross.svg
new file mode 120000
index 0000000..e0b26b0
--- /dev/null
+++ b/src/svg/static/tcross.svg
@@ -0,0 +1 @@
+cross.svg
\ No newline at end of file
diff --git a/src/svg/static/top_left_corner.svg b/src/svg/static/top_left_corner.svg
new file mode 120000
index 0000000..a3a3e2d
--- /dev/null
+++ b/src/svg/static/top_left_corner.svg
@@ -0,0 +1 @@
+bottom_right_corner.svg
\ No newline at end of file
diff --git a/src/svg/static/top_right_corner.svg b/src/svg/static/top_right_corner.svg
new file mode 120000
index 0000000..acc15d0
--- /dev/null
+++ b/src/svg/static/top_right_corner.svg
@@ -0,0 +1 @@
+bottom_left_corner.svg
\ No newline at end of file
diff --git a/src/svg/static/top_side.svg b/src/svg/static/top_side.svg
new file mode 100644
index 0000000..b8666bc
--- /dev/null
+++ b/src/svg/static/top_side.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/svg/static/top_tee.svg b/src/svg/static/top_tee.svg
new file mode 100644
index 0000000..ffd9248
--- /dev/null
+++ b/src/svg/static/top_tee.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/ul_angle.svg b/src/svg/static/ul_angle.svg
new file mode 100644
index 0000000..60b1912
--- /dev/null
+++ b/src/svg/static/ul_angle.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/ur_angle.svg b/src/svg/static/ur_angle.svg
new file mode 100644
index 0000000..fdb9b82
--- /dev/null
+++ b/src/svg/static/ur_angle.svg
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/vertical_text.svg b/src/svg/static/vertical_text.svg
new file mode 100644
index 0000000..afc487f
--- /dev/null
+++ b/src/svg/static/vertical_text.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/svg/static/wayland_cursor.svg b/src/svg/static/wayland_cursor.svg
new file mode 100644
index 0000000..3114d5d
--- /dev/null
+++ b/src/svg/static/wayland_cursor.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/svg/static/x_cursor.svg b/src/svg/static/x_cursor.svg
new file mode 100644
index 0000000..45fa0a6
--- /dev/null
+++ b/src/svg/static/x_cursor.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/svg/static/xterm.svg b/src/svg/static/xterm.svg
new file mode 100644
index 0000000..73d7b47
--- /dev/null
+++ b/src/svg/static/xterm.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/svg/static/zoom_in.svg b/src/svg/static/zoom_in.svg
new file mode 100644
index 0000000..6a37c6d
--- /dev/null
+++ b/src/svg/static/zoom_in.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/svg/static/zoom_out.svg b/src/svg/static/zoom_out.svg
new file mode 100644
index 0000000..da679da
--- /dev/null
+++ b/src/svg/static/zoom_out.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/utils/getFrameName.ts b/src/utils/getFrameName.ts
new file mode 100644
index 0000000..5b3dfff
--- /dev/null
+++ b/src/utils/getFrameName.ts
@@ -0,0 +1,14 @@
+import path from "path";
+
+export const frameNumber = (index: number, endIndex: number) => {
+ let result = "" + index;
+ while (result.length < endIndex) {
+ result = "0" + result;
+ }
+ return result;
+};
+
+export const getFrameName = (index: number, fileName: string) => {
+ const frame = frameNumber(index, 2);
+ return `${path.basename(fileName, ".svg")}-${frame}.png`;
+};
diff --git a/src/utils/htmlTemplate.ts b/src/utils/htmlTemplate.ts
new file mode 100644
index 0000000..05ea0cb
--- /dev/null
+++ b/src/utils/htmlTemplate.ts
@@ -0,0 +1,19 @@
+export const template = `
+
+
+
+
+
+ Eggy Render Template
+
+
+
+
+
+
+
+
+`;
+
+export const generateRenderTemplate = (svg: string) =>
+ template.replace("", svg);
diff --git a/src/utils/matchImages.ts b/src/utils/matchImages.ts
new file mode 100644
index 0000000..aceffa8
--- /dev/null
+++ b/src/utils/matchImages.ts
@@ -0,0 +1,19 @@
+import { PNG } from "pngjs";
+import pixelmatch from "pixelmatch";
+
+interface MatchImagesArgs {
+ img1Buff: Buffer;
+ img2Buff: Buffer;
+}
+
+export const matchImages = ({ img1Buff, img2Buff }: MatchImagesArgs) => {
+ const img1 = PNG.sync.read(img1Buff);
+ const img2 = PNG.sync.read(img2Buff);
+ const { width, height } = img1;
+
+ const diff = new PNG({ width, height });
+
+ return pixelmatch(img1.data, img2.data, diff.data, width, height, {
+ threshold: 0.25,
+ });
+};
diff --git a/src/utils/saveFrames.ts b/src/utils/saveFrames.ts
new file mode 100644
index 0000000..f3be527
--- /dev/null
+++ b/src/utils/saveFrames.ts
@@ -0,0 +1,16 @@
+import fs from "fs";
+import path from "path";
+import { bitmapsDir } from "../config";
+
+export interface Frames {
+ [fileName: string]: {
+ buffer: Buffer;
+ };
+}
+
+export const saveFrames = (frames: Frames) => {
+ for (let [fileName, { buffer }] of Object.entries(frames)) {
+ const out_path = path.resolve(bitmapsDir, fileName);
+ fs.writeFileSync(out_path, buffer, { encoding: "binary" });
+ }
+};
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..a26a563
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "target": "es2017",
+ "module": "commonjs",
+ "lib": ["es2015", "dom"],
+ "outDir": "dist",
+ "typeRoots": ["node_modules/@types"],
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": true,
+ "resolveJsonModule": true,
+ "noFallthroughCasesInSwitch": true,
+ "esModuleInterop": true
+ },
+ "include": ["src/**/*", "node_modules/@types/puppeteer/index.d.ts"],
+ "exclude": ["node_modules", "**/*.test.ts"]
+}