├── .editorconfig ├── .envrc ├── .github └── workflows │ ├── build.yml │ └── deploy.yml ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── flake.lock ├── flake.nix ├── mvnw ├── mvnw.cmd ├── palette ├── palette.json ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── catppuccin │ │ ├── Color.java │ │ ├── Flavor.java │ │ ├── Pair.java │ │ └── Palette.java │ └── test │ └── java │ └── com │ └── catppuccin │ └── PaletteTests.java ├── pom.xml ├── processing ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── catppuccin │ ├── GeneratedPalette.java │ ├── POJO.java │ └── PaletteProcessor.java └── renovate.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # EditorConfig is awesome: https://EditorConfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | charset = utf-8 9 | indent_size = 2 10 | indent_style = space 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | 15 | # go 16 | [*.go] 17 | indent_style = tab 18 | indent_size = 4 19 | 20 | # python 21 | [*.{ini,py,py.tpl,rst}] 22 | indent_size = 4 23 | 24 | # rust 25 | [*.rs] 26 | indent_size = 4 27 | 28 | # java 29 | [*.java] 30 | indent_size = 4 31 | 32 | # documentation, utils 33 | [*.{md,mdx,diff}] 34 | trim_trailing_whitespace = false 35 | 36 | # windows shell scripts 37 | [*.{cmd,bat,ps1}] 38 | end_of_line = crlf 39 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use flake; 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 'main' 7 | paths: 8 | - 'palette/**' 9 | - 'processing/**' 10 | - 'pom.xml' 11 | - '.mvn/**' 12 | pull_request: 13 | paths: 14 | - 'palette/**' 15 | - 'processing/**' 16 | - 'pom.xml' 17 | - '.mvn/**' 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout Repository 24 | uses: actions/checkout@v4 25 | 26 | - name: Setup Java 27 | uses: actions/setup-java@v4 28 | with: 29 | distribution: 'adopt' 30 | java-version: '8' 31 | cache: 'maven' 32 | 33 | - name: Build 34 | run: mvn -B -DskipTests clean package 35 | 36 | - name: Test 37 | run: mvn test 38 | 39 | - name: Archive Palette Artifacts 40 | uses: actions/upload-artifact@v4 41 | with: 42 | name: palette-jars 43 | path: ./palette/target/*.jar 44 | 45 | - name: Archive Processing Artifacts 46 | uses: actions/upload-artifact@v4 47 | with: 48 | name: processing-jars 49 | path: ./processing/target/*.jar 50 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Setup Java 16 | uses: actions/setup-java@v4 17 | with: 18 | distribution: 'adopt' 19 | java-version: '8' 20 | cache: 'maven' 21 | server-id: ossrh 22 | server-username: OSSRH_USERNAME 23 | server-password: OSSRH_TOKEN 24 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 25 | gpg-passphrase: MAVEN_GPG_PASSPHRASE 26 | 27 | - name: Build 28 | run: mvn -B -DskipTests clean package 29 | 30 | - name: Deploy 31 | env: 32 | OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} 33 | OSSRH_TOKEN: ${{ secrets.OSSRH_TOKEN }} 34 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 35 | run: mvn -B -DskipTests deploy 36 | 37 | - name: Create Release 38 | uses: ncipollo/release-action@v1 39 | with: 40 | artifacts: "palette/target/*.jar,processing/target/*.jar" 41 | generateReleaseNotes: true 42 | makeLatest: true 43 | draft: true 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/ 8 | *.iws 9 | *.iml 10 | *.ipr 11 | 12 | ### Eclipse ### 13 | .apt_generated 14 | .classpath 15 | .factorypath 16 | .project 17 | .settings 18 | .springBeans 19 | .sts4-cache 20 | 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | build/ 28 | !**/src/main/**/build/ 29 | !**/src/test/**/build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | 34 | ### Mac OS ### 35 | .DS_Store 36 | 37 | .direnv/ -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/catppuccin/java/48ad3174db43286ef7408feb7609451a2bf6970e/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Project layout 2 | 3 | This project uses the Maven Multi Module system to build the various modules. There is the main module, the palette, 4 | which depends on the secondary module 'processing', to do the code generation based on our `palette.json`. 5 | The multi module system is used as it is the easiest way to get our processing module to build at the same time, and then get used 6 | by, the palette module. This also has the benefit of allowing us to publish the processing module independently. 7 | 8 | The `palette.json` is vendored for simplicity, and must be manually updated if/when it changes. 9 | 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-present Catppuccin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Logo
3 | 4 | Catppuccin for Java 5 | 6 |

7 | 8 |

9 | 10 | 11 | 12 | 13 |

14 | 15 | ## Installation 16 | 17 | Be sure to replace the **VERSION** key below with the version shown above! 18 | 19 | ### Maven 20 | 21 | ```xml 22 | 23 | 24 | 25 | com.catppuccin 26 | catppuccin-palette 27 | VERSION 28 | 29 | ``` 30 | 31 | ### Gradle 32 | 33 | ```gradle 34 | repositories { 35 | mavenCentral() 36 | } 37 | 38 | dependencies { 39 | // https://mvnrepository.com/artifact/com.catppuccin/catppuccin-palette 40 | implementation group: 'com.catppuccin', name: 'catppuccin-palette', version: 'VERSION' 41 | } 42 | ``` 43 | 44 | ### Binaries 45 | 46 | If you choose not to use a build tool, pre-built `.jar` files are available with every 47 | single [release](https://github.com/catppuccin/java/releases). 48 | 49 | ## Usage 50 | 51 | ```java 52 | package com.catppuccin; 53 | 54 | public class Main { 55 | public static void main(String[] args) { 56 | String mocha = Palette.MOCHA.name(); // mocha 57 | String mochaBaseHex = Palette.MOCHA.base().hex(); // 1e1e2e 58 | int[] mochaBaseRGB = Palette.MOCHA.base().components(); // [30, 30, 46] 59 | 60 | // loop through just frappé 61 | for (Pair colourPair : Palette.FRAPPE.toList()) { 62 | String name = colourPair.key(); 63 | Color colour = colourPair.value(); 64 | System.out.println(name + ": " + colour.hex()); 65 | } 66 | 67 | // loop through every colour 68 | for (Flavour flavour : Palette.toList()) { 69 | System.out.println("Flavour: " + flavour.name()); 70 | for (Pair colourPair : flavour.toList()) { 71 | String name = colourPair.key(); 72 | Color colour = colourPair.value(); 73 | System.out.println(name + ": " + colour.hex()); 74 | } 75 | } 76 | } 77 | } 78 | ``` 79 | 80 | ## Contributing 81 | 82 | If you are looking to contribute, please read through our 83 | [CONTRIBUTING.md](https://github.com/catppuccin/.github/blob/main/CONTRIBUTING.md) first! 84 | 85 | ## 💝 Thanks to 86 | 87 | - [Hamothy](https://github.com/sgoudham) 88 | - [nullishamy](https://github.com/nullishamy) 89 | 90 |   91 | 92 |

93 | 94 |

95 | 96 |

97 | Copyright © 2023-present Catppuccin Org 98 |

99 | 100 |

101 | 102 |

103 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1694529238, 9 | "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "flake-utils_2": { 22 | "inputs": { 23 | "systems": "systems_2" 24 | }, 25 | "locked": { 26 | "lastModified": 1681202837, 27 | "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", 28 | "owner": "numtide", 29 | "repo": "flake-utils", 30 | "rev": "cfacdce06f30d2b68473a46042957675eebb3401", 31 | "type": "github" 32 | }, 33 | "original": { 34 | "owner": "numtide", 35 | "repo": "flake-utils", 36 | "type": "github" 37 | } 38 | }, 39 | "nixpkgs": { 40 | "locked": { 41 | "lastModified": 1694767346, 42 | "narHash": "sha256-5uH27SiVFUwsTsqC5rs3kS7pBoNhtoy9QfTP9BmknGk=", 43 | "owner": "NixOS", 44 | "repo": "nixpkgs", 45 | "rev": "ace5093e36ab1e95cb9463863491bee90d5a4183", 46 | "type": "github" 47 | }, 48 | "original": { 49 | "owner": "NixOS", 50 | "ref": "nixos-unstable", 51 | "repo": "nixpkgs", 52 | "type": "github" 53 | } 54 | }, 55 | "nixpkgs_2": { 56 | "locked": { 57 | "lastModified": 1681358109, 58 | "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", 59 | "owner": "NixOS", 60 | "repo": "nixpkgs", 61 | "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9", 62 | "type": "github" 63 | }, 64 | "original": { 65 | "owner": "NixOS", 66 | "ref": "nixpkgs-unstable", 67 | "repo": "nixpkgs", 68 | "type": "github" 69 | } 70 | }, 71 | "root": { 72 | "inputs": { 73 | "flake-utils": "flake-utils", 74 | "nixpkgs": "nixpkgs", 75 | "rust-overlay": "rust-overlay" 76 | } 77 | }, 78 | "rust-overlay": { 79 | "inputs": { 80 | "flake-utils": "flake-utils_2", 81 | "nixpkgs": "nixpkgs_2" 82 | }, 83 | "locked": { 84 | "lastModified": 1694743934, 85 | "narHash": "sha256-4pn0x+OiOFWefBpgyufFVaAeG+LwfVUI/HMCma8xdHU=", 86 | "owner": "oxalica", 87 | "repo": "rust-overlay", 88 | "rev": "6a26dd6da9b4f28d9b4c397bd22b5df4bec8f78a", 89 | "type": "github" 90 | }, 91 | "original": { 92 | "owner": "oxalica", 93 | "repo": "rust-overlay", 94 | "type": "github" 95 | } 96 | }, 97 | "systems": { 98 | "locked": { 99 | "lastModified": 1681028828, 100 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 101 | "owner": "nix-systems", 102 | "repo": "default", 103 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 104 | "type": "github" 105 | }, 106 | "original": { 107 | "owner": "nix-systems", 108 | "repo": "default", 109 | "type": "github" 110 | } 111 | }, 112 | "systems_2": { 113 | "locked": { 114 | "lastModified": 1681028828, 115 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 116 | "owner": "nix-systems", 117 | "repo": "default", 118 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 119 | "type": "github" 120 | }, 121 | "original": { 122 | "owner": "nix-systems", 123 | "repo": "default", 124 | "type": "github" 125 | } 126 | } 127 | }, 128 | "root": "root", 129 | "version": 7 130 | } 131 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A devShell example"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 | rust-overlay.url = "github:oxalica/rust-overlay"; 7 | flake-utils.url = "github:numtide/flake-utils"; 8 | }; 9 | 10 | outputs = { self, nixpkgs, rust-overlay, flake-utils, ... }: 11 | flake-utils.lib.eachDefaultSystem (system: 12 | let 13 | overlays = [ (import rust-overlay) ]; 14 | pkgs = import nixpkgs { 15 | inherit system overlays; 16 | }; 17 | in 18 | with pkgs; 19 | { 20 | devShell = mkShell { 21 | buildInputs = [ 22 | openjdk11-bootstrap 23 | ]; 24 | }; 25 | } 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.3.2 23 | # 24 | # Optional ENV vars 25 | # ----------------- 26 | # JAVA_HOME - location of a JDK home dir, required when download maven via java source 27 | # MVNW_REPOURL - repo url base for downloading maven distribution 28 | # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 29 | # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output 30 | # ---------------------------------------------------------------------------- 31 | 32 | set -euf 33 | [ "${MVNW_VERBOSE-}" != debug ] || set -x 34 | 35 | # OS specific support. 36 | native_path() { printf %s\\n "$1"; } 37 | case "$(uname)" in 38 | CYGWIN* | MINGW*) 39 | [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" 40 | native_path() { cygpath --path --windows "$1"; } 41 | ;; 42 | esac 43 | 44 | # set JAVACMD and JAVACCMD 45 | set_java_home() { 46 | # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched 47 | if [ -n "${JAVA_HOME-}" ]; then 48 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 49 | # IBM's JDK on AIX uses strange locations for the executables 50 | JAVACMD="$JAVA_HOME/jre/sh/java" 51 | JAVACCMD="$JAVA_HOME/jre/sh/javac" 52 | else 53 | JAVACMD="$JAVA_HOME/bin/java" 54 | JAVACCMD="$JAVA_HOME/bin/javac" 55 | 56 | if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then 57 | echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 58 | echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 59 | return 1 60 | fi 61 | fi 62 | else 63 | JAVACMD="$( 64 | 'set' +e 65 | 'unset' -f command 2>/dev/null 66 | 'command' -v java 67 | )" || : 68 | JAVACCMD="$( 69 | 'set' +e 70 | 'unset' -f command 2>/dev/null 71 | 'command' -v javac 72 | )" || : 73 | 74 | if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then 75 | echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 76 | return 1 77 | fi 78 | fi 79 | } 80 | 81 | # hash string like Java String::hashCode 82 | hash_string() { 83 | str="${1:-}" h=0 84 | while [ -n "$str" ]; do 85 | char="${str%"${str#?}"}" 86 | h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) 87 | str="${str#?}" 88 | done 89 | printf %x\\n $h 90 | } 91 | 92 | verbose() { :; } 93 | [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } 94 | 95 | die() { 96 | printf %s\\n "$1" >&2 97 | exit 1 98 | } 99 | 100 | trim() { 101 | # MWRAPPER-139: 102 | # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. 103 | # Needed for removing poorly interpreted newline sequences when running in more 104 | # exotic environments such as mingw bash on Windows. 105 | printf "%s" "${1}" | tr -d '[:space:]' 106 | } 107 | 108 | # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties 109 | while IFS="=" read -r key value; do 110 | case "${key-}" in 111 | distributionUrl) distributionUrl=$(trim "${value-}") ;; 112 | distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; 113 | esac 114 | done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" 115 | [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" 116 | 117 | case "${distributionUrl##*/}" in 118 | maven-mvnd-*bin.*) 119 | MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ 120 | case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in 121 | *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; 122 | :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; 123 | :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; 124 | :Linux*x86_64*) distributionPlatform=linux-amd64 ;; 125 | *) 126 | echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 127 | distributionPlatform=linux-amd64 128 | ;; 129 | esac 130 | distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" 131 | ;; 132 | maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; 133 | *) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; 134 | esac 135 | 136 | # apply MVNW_REPOURL and calculate MAVEN_HOME 137 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 138 | [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" 139 | distributionUrlName="${distributionUrl##*/}" 140 | distributionUrlNameMain="${distributionUrlName%.*}" 141 | distributionUrlNameMain="${distributionUrlNameMain%-bin}" 142 | MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" 143 | MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" 144 | 145 | exec_maven() { 146 | unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : 147 | exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" 148 | } 149 | 150 | if [ -d "$MAVEN_HOME" ]; then 151 | verbose "found existing MAVEN_HOME at $MAVEN_HOME" 152 | exec_maven "$@" 153 | fi 154 | 155 | case "${distributionUrl-}" in 156 | *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; 157 | *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; 158 | esac 159 | 160 | # prepare tmp dir 161 | if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then 162 | clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } 163 | trap clean HUP INT TERM EXIT 164 | else 165 | die "cannot create temp dir" 166 | fi 167 | 168 | mkdir -p -- "${MAVEN_HOME%/*}" 169 | 170 | # Download and Install Apache Maven 171 | verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 172 | verbose "Downloading from: $distributionUrl" 173 | verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 174 | 175 | # select .zip or .tar.gz 176 | if ! command -v unzip >/dev/null; then 177 | distributionUrl="${distributionUrl%.zip}.tar.gz" 178 | distributionUrlName="${distributionUrl##*/}" 179 | fi 180 | 181 | # verbose opt 182 | __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' 183 | [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v 184 | 185 | # normalize http auth 186 | case "${MVNW_PASSWORD:+has-password}" in 187 | '') MVNW_USERNAME='' MVNW_PASSWORD='' ;; 188 | has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; 189 | esac 190 | 191 | if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then 192 | verbose "Found wget ... using wget" 193 | wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" 194 | elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then 195 | verbose "Found curl ... using curl" 196 | curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" 197 | elif set_java_home; then 198 | verbose "Falling back to use Java to download" 199 | javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" 200 | targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" 201 | cat >"$javaSource" <<-END 202 | public class Downloader extends java.net.Authenticator 203 | { 204 | protected java.net.PasswordAuthentication getPasswordAuthentication() 205 | { 206 | return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); 207 | } 208 | public static void main( String[] args ) throws Exception 209 | { 210 | setDefault( new Downloader() ); 211 | java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); 212 | } 213 | } 214 | END 215 | # For Cygwin/MinGW, switch paths to Windows format before running javac and java 216 | verbose " - Compiling Downloader.java ..." 217 | "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" 218 | verbose " - Running Downloader.java ..." 219 | "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" 220 | fi 221 | 222 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 223 | if [ -n "${distributionSha256Sum-}" ]; then 224 | distributionSha256Result=false 225 | if [ "$MVN_CMD" = mvnd.sh ]; then 226 | echo "Checksum validation is not supported for maven-mvnd." >&2 227 | echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 228 | exit 1 229 | elif command -v sha256sum >/dev/null; then 230 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then 231 | distributionSha256Result=true 232 | fi 233 | elif command -v shasum >/dev/null; then 234 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then 235 | distributionSha256Result=true 236 | fi 237 | else 238 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 239 | echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 240 | exit 1 241 | fi 242 | if [ $distributionSha256Result = false ]; then 243 | echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 244 | echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 245 | exit 1 246 | fi 247 | fi 248 | 249 | # unzip and move 250 | if command -v unzip >/dev/null; then 251 | unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" 252 | else 253 | tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" 254 | fi 255 | printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" 256 | mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" 257 | 258 | clean || : 259 | exec_maven "$@" 260 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM http://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.2 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | if ($env:MAVEN_USER_HOME) { 83 | $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" 84 | } 85 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 86 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 87 | 88 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 89 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 90 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 91 | exit $? 92 | } 93 | 94 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 95 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 96 | } 97 | 98 | # prepare tmp dir 99 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 100 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 101 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 102 | trap { 103 | if ($TMP_DOWNLOAD_DIR.Exists) { 104 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 105 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 106 | } 107 | } 108 | 109 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 110 | 111 | # Download and Install Apache Maven 112 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 113 | Write-Verbose "Downloading from: $distributionUrl" 114 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 115 | 116 | $webclient = New-Object System.Net.WebClient 117 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 118 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 119 | } 120 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 121 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 122 | 123 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 124 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 125 | if ($distributionSha256Sum) { 126 | if ($USE_MVND) { 127 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 128 | } 129 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 130 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 131 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 132 | } 133 | } 134 | 135 | # unzip and move 136 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 137 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 138 | try { 139 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 140 | } catch { 141 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 142 | Write-Error "fail to move MAVEN_HOME" 143 | } 144 | } finally { 145 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 146 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 147 | } 148 | 149 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 150 | -------------------------------------------------------------------------------- /palette/palette.json: -------------------------------------------------------------------------------- 1 | { 2 | "latte": { 3 | "name": "Latte", 4 | "emoji": "🌻", 5 | "order": 0, 6 | "dark": false, 7 | "colors": { 8 | "rosewater": { 9 | "name": "Rosewater", 10 | "order": 0, 11 | "hex": "#dc8a78", 12 | "rgb": { 13 | "r": 220, 14 | "g": 138, 15 | "b": 120 16 | }, 17 | "hsl": { 18 | "h": 10.799999999999995, 19 | "s": 0.5882352941176472, 20 | "l": 0.6666666666666667 21 | }, 22 | "accent": true 23 | }, 24 | "flamingo": { 25 | "name": "Flamingo", 26 | "order": 1, 27 | "hex": "#dd7878", 28 | "rgb": { 29 | "r": 221, 30 | "g": 120, 31 | "b": 120 32 | }, 33 | "hsl": { 34 | "h": 0, 35 | "s": 0.5976331360946746, 36 | "l": 0.6686274509803922 37 | }, 38 | "accent": true 39 | }, 40 | "pink": { 41 | "name": "Pink", 42 | "order": 2, 43 | "hex": "#ea76cb", 44 | "rgb": { 45 | "r": 234, 46 | "g": 118, 47 | "b": 203 48 | }, 49 | "hsl": { 50 | "h": 316.0344827586207, 51 | "s": 0.7341772151898731, 52 | "l": 0.6901960784313725 53 | }, 54 | "accent": true 55 | }, 56 | "mauve": { 57 | "name": "Mauve", 58 | "order": 3, 59 | "hex": "#8839ef", 60 | "rgb": { 61 | "r": 136, 62 | "g": 57, 63 | "b": 239 64 | }, 65 | "hsl": { 66 | "h": 266.0439560439561, 67 | "s": 0.8504672897196262, 68 | "l": 0.5803921568627451 69 | }, 70 | "accent": true 71 | }, 72 | "red": { 73 | "name": "Red", 74 | "order": 4, 75 | "hex": "#d20f39", 76 | "rgb": { 77 | "r": 210, 78 | "g": 15, 79 | "b": 57 80 | }, 81 | "hsl": { 82 | "h": 347.0769230769231, 83 | "s": 0.8666666666666666, 84 | "l": 0.4411764705882353 85 | }, 86 | "accent": true 87 | }, 88 | "maroon": { 89 | "name": "Maroon", 90 | "order": 5, 91 | "hex": "#e64553", 92 | "rgb": { 93 | "r": 230, 94 | "g": 69, 95 | "b": 83 96 | }, 97 | "hsl": { 98 | "h": 354.78260869565213, 99 | "s": 0.76303317535545, 100 | "l": 0.5862745098039216 101 | }, 102 | "accent": true 103 | }, 104 | "peach": { 105 | "name": "Peach", 106 | "order": 6, 107 | "hex": "#fe640b", 108 | "rgb": { 109 | "r": 254, 110 | "g": 100, 111 | "b": 11 112 | }, 113 | "hsl": { 114 | "h": 21.975308641975307, 115 | "s": 0.9918367346938776, 116 | "l": 0.5196078431372549 117 | }, 118 | "accent": true 119 | }, 120 | "yellow": { 121 | "name": "Yellow", 122 | "order": 7, 123 | "hex": "#df8e1d", 124 | "rgb": { 125 | "r": 223, 126 | "g": 142, 127 | "b": 29 128 | }, 129 | "hsl": { 130 | "h": 34.948453608247426, 131 | "s": 0.7698412698412698, 132 | "l": 0.49411764705882355 133 | }, 134 | "accent": true 135 | }, 136 | "green": { 137 | "name": "Green", 138 | "order": 8, 139 | "hex": "#40a02b", 140 | "rgb": { 141 | "r": 64, 142 | "g": 160, 143 | "b": 43 144 | }, 145 | "hsl": { 146 | "h": 109.23076923076923, 147 | "s": 0.5763546798029556, 148 | "l": 0.39803921568627454 149 | }, 150 | "accent": true 151 | }, 152 | "teal": { 153 | "name": "Teal", 154 | "order": 9, 155 | "hex": "#179299", 156 | "rgb": { 157 | "r": 23, 158 | "g": 146, 159 | "b": 153 160 | }, 161 | "hsl": { 162 | "h": 183.23076923076923, 163 | "s": 0.7386363636363636, 164 | "l": 0.34509803921568627 165 | }, 166 | "accent": true 167 | }, 168 | "sky": { 169 | "name": "Sky", 170 | "order": 10, 171 | "hex": "#04a5e5", 172 | "rgb": { 173 | "r": 4, 174 | "g": 165, 175 | "b": 229 176 | }, 177 | "hsl": { 178 | "h": 197.0666666666667, 179 | "s": 0.965665236051502, 180 | "l": 0.45686274509803926 181 | }, 182 | "accent": true 183 | }, 184 | "sapphire": { 185 | "name": "Sapphire", 186 | "order": 11, 187 | "hex": "#209fb5", 188 | "rgb": { 189 | "r": 32, 190 | "g": 159, 191 | "b": 181 192 | }, 193 | "hsl": { 194 | "h": 188.85906040268458, 195 | "s": 0.6995305164319249, 196 | "l": 0.4176470588235294 197 | }, 198 | "accent": true 199 | }, 200 | "blue": { 201 | "name": "Blue", 202 | "order": 12, 203 | "hex": "#1e66f5", 204 | "rgb": { 205 | "r": 30, 206 | "g": 102, 207 | "b": 245 208 | }, 209 | "hsl": { 210 | "h": 219.90697674418607, 211 | "s": 0.9148936170212768, 212 | "l": 0.5392156862745098 213 | }, 214 | "accent": true 215 | }, 216 | "lavender": { 217 | "name": "Lavender", 218 | "order": 13, 219 | "hex": "#7287fd", 220 | "rgb": { 221 | "r": 114, 222 | "g": 135, 223 | "b": 253 224 | }, 225 | "hsl": { 226 | "h": 230.93525179856115, 227 | "s": 0.9720279720279721, 228 | "l": 0.7196078431372549 229 | }, 230 | "accent": true 231 | }, 232 | "text": { 233 | "name": "Text", 234 | "order": 14, 235 | "hex": "#4c4f69", 236 | "rgb": { 237 | "r": 76, 238 | "g": 79, 239 | "b": 105 240 | }, 241 | "hsl": { 242 | "h": 233.79310344827587, 243 | "s": 0.16022099447513813, 244 | "l": 0.3549019607843137 245 | }, 246 | "accent": false 247 | }, 248 | "subtext1": { 249 | "name": "Subtext 1", 250 | "order": 15, 251 | "hex": "#5c5f77", 252 | "rgb": { 253 | "r": 92, 254 | "g": 95, 255 | "b": 119 256 | }, 257 | "hsl": { 258 | "h": 233.33333333333334, 259 | "s": 0.1279620853080569, 260 | "l": 0.4137254901960784 261 | }, 262 | "accent": false 263 | }, 264 | "subtext0": { 265 | "name": "Subtext 0", 266 | "order": 16, 267 | "hex": "#6c6f85", 268 | "rgb": { 269 | "r": 108, 270 | "g": 111, 271 | "b": 133 272 | }, 273 | "hsl": { 274 | "h": 232.79999999999998, 275 | "s": 0.10373443983402494, 276 | "l": 0.4725490196078431 277 | }, 278 | "accent": false 279 | }, 280 | "overlay2": { 281 | "name": "Overlay 2", 282 | "order": 17, 283 | "hex": "#7c7f93", 284 | "rgb": { 285 | "r": 124, 286 | "g": 127, 287 | "b": 147 288 | }, 289 | "hsl": { 290 | "h": 232.17391304347825, 291 | "s": 0.09623430962343092, 292 | "l": 0.5313725490196078 293 | }, 294 | "accent": false 295 | }, 296 | "overlay1": { 297 | "name": "Overlay 1", 298 | "order": 18, 299 | "hex": "#8c8fa1", 300 | "rgb": { 301 | "r": 140, 302 | "g": 143, 303 | "b": 161 304 | }, 305 | "hsl": { 306 | "h": 231.42857142857144, 307 | "s": 0.10047846889952144, 308 | "l": 0.5901960784313726 309 | }, 310 | "accent": false 311 | }, 312 | "overlay0": { 313 | "name": "Overlay 0", 314 | "order": 19, 315 | "hex": "#9ca0b0", 316 | "rgb": { 317 | "r": 156, 318 | "g": 160, 319 | "b": 176 320 | }, 321 | "hsl": { 322 | "h": 228.00000000000003, 323 | "s": 0.11235955056179768, 324 | "l": 0.6509803921568628 325 | }, 326 | "accent": false 327 | }, 328 | "surface2": { 329 | "name": "Surface 2", 330 | "order": 20, 331 | "hex": "#acb0be", 332 | "rgb": { 333 | "r": 172, 334 | "g": 176, 335 | "b": 190 336 | }, 337 | "hsl": { 338 | "h": 226.6666666666667, 339 | "s": 0.12162162162162159, 340 | "l": 0.7098039215686275 341 | }, 342 | "accent": false 343 | }, 344 | "surface1": { 345 | "name": "Surface 1", 346 | "order": 21, 347 | "hex": "#bcc0cc", 348 | "rgb": { 349 | "r": 188, 350 | "g": 192, 351 | "b": 204 352 | }, 353 | "hsl": { 354 | "h": 225.00000000000003, 355 | "s": 0.13559322033898308, 356 | "l": 0.7686274509803922 357 | }, 358 | "accent": false 359 | }, 360 | "surface0": { 361 | "name": "Surface 0", 362 | "order": 22, 363 | "hex": "#ccd0da", 364 | "rgb": { 365 | "r": 204, 366 | "g": 208, 367 | "b": 218 368 | }, 369 | "hsl": { 370 | "h": 222.85714285714292, 371 | "s": 0.1590909090909089, 372 | "l": 0.8274509803921568 373 | }, 374 | "accent": false 375 | }, 376 | "base": { 377 | "name": "Base", 378 | "order": 23, 379 | "hex": "#eff1f5", 380 | "rgb": { 381 | "r": 239, 382 | "g": 241, 383 | "b": 245 384 | }, 385 | "hsl": { 386 | "h": 220.00000000000009, 387 | "s": 0.23076923076923136, 388 | "l": 0.9490196078431372 389 | }, 390 | "accent": false 391 | }, 392 | "mantle": { 393 | "name": "Mantle", 394 | "order": 24, 395 | "hex": "#e6e9ef", 396 | "rgb": { 397 | "r": 230, 398 | "g": 233, 399 | "b": 239 400 | }, 401 | "hsl": { 402 | "h": 220.00000000000006, 403 | "s": 0.21951219512195116, 404 | "l": 0.919607843137255 405 | }, 406 | "accent": false 407 | }, 408 | "crust": { 409 | "name": "Crust", 410 | "order": 25, 411 | "hex": "#dce0e8", 412 | "rgb": { 413 | "r": 220, 414 | "g": 224, 415 | "b": 232 416 | }, 417 | "hsl": { 418 | "h": 220.00000000000006, 419 | "s": 0.20689655172413762, 420 | "l": 0.8862745098039215 421 | }, 422 | "accent": false 423 | } 424 | } 425 | }, 426 | "frappe": { 427 | "name": "Frappé", 428 | "emoji": "🪴", 429 | "order": 1, 430 | "dark": true, 431 | "colors": { 432 | "rosewater": { 433 | "name": "Rosewater", 434 | "order": 0, 435 | "hex": "#f2d5cf", 436 | "rgb": { 437 | "r": 242, 438 | "g": 213, 439 | "b": 207 440 | }, 441 | "hsl": { 442 | "h": 10.2857142857143, 443 | "s": 0.5737704918032784, 444 | "l": 0.8803921568627451 445 | }, 446 | "accent": true 447 | }, 448 | "flamingo": { 449 | "name": "Flamingo", 450 | "order": 1, 451 | "hex": "#eebebe", 452 | "rgb": { 453 | "r": 238, 454 | "g": 190, 455 | "b": 190 456 | }, 457 | "hsl": { 458 | "h": 0, 459 | "s": 0.5853658536585367, 460 | "l": 0.8392156862745098 461 | }, 462 | "accent": true 463 | }, 464 | "pink": { 465 | "name": "Pink", 466 | "order": 2, 467 | "hex": "#f4b8e4", 468 | "rgb": { 469 | "r": 244, 470 | "g": 184, 471 | "b": 228 472 | }, 473 | "hsl": { 474 | "h": 316, 475 | "s": 0.7317073170731713, 476 | "l": 0.8392156862745098 477 | }, 478 | "accent": true 479 | }, 480 | "mauve": { 481 | "name": "Mauve", 482 | "order": 3, 483 | "hex": "#ca9ee6", 484 | "rgb": { 485 | "r": 202, 486 | "g": 158, 487 | "b": 230 488 | }, 489 | "hsl": { 490 | "h": 276.66666666666663, 491 | "s": 0.5901639344262294, 492 | "l": 0.7607843137254902 493 | }, 494 | "accent": true 495 | }, 496 | "red": { 497 | "name": "Red", 498 | "order": 4, 499 | "hex": "#e78284", 500 | "rgb": { 501 | "r": 231, 502 | "g": 130, 503 | "b": 132 504 | }, 505 | "hsl": { 506 | "h": 358.8118811881188, 507 | "s": 0.6778523489932885, 508 | "l": 0.7078431372549019 509 | }, 510 | "accent": true 511 | }, 512 | "maroon": { 513 | "name": "Maroon", 514 | "order": 5, 515 | "hex": "#ea999c", 516 | "rgb": { 517 | "r": 234, 518 | "g": 153, 519 | "b": 156 520 | }, 521 | "hsl": { 522 | "h": 357.77777777777777, 523 | "s": 0.6585365853658534, 524 | "l": 0.7588235294117647 525 | }, 526 | "accent": true 527 | }, 528 | "peach": { 529 | "name": "Peach", 530 | "order": 6, 531 | "hex": "#ef9f76", 532 | "rgb": { 533 | "r": 239, 534 | "g": 159, 535 | "b": 118 536 | }, 537 | "hsl": { 538 | "h": 20.33057851239669, 539 | "s": 0.7908496732026143, 540 | "l": 0.7 541 | }, 542 | "accent": true 543 | }, 544 | "yellow": { 545 | "name": "Yellow", 546 | "order": 7, 547 | "hex": "#e5c890", 548 | "rgb": { 549 | "r": 229, 550 | "g": 200, 551 | "b": 144 552 | }, 553 | "hsl": { 554 | "h": 39.52941176470588, 555 | "s": 0.6204379562043796, 556 | "l": 0.7313725490196079 557 | }, 558 | "accent": true 559 | }, 560 | "green": { 561 | "name": "Green", 562 | "order": 8, 563 | "hex": "#a6d189", 564 | "rgb": { 565 | "r": 166, 566 | "g": 209, 567 | "b": 137 568 | }, 569 | "hsl": { 570 | "h": 95.83333333333331, 571 | "s": 0.4390243902439024, 572 | "l": 0.6784313725490196 573 | }, 574 | "accent": true 575 | }, 576 | "teal": { 577 | "name": "Teal", 578 | "order": 9, 579 | "hex": "#81c8be", 580 | "rgb": { 581 | "r": 129, 582 | "g": 200, 583 | "b": 190 584 | }, 585 | "hsl": { 586 | "h": 171.5492957746479, 587 | "s": 0.3922651933701657, 588 | "l": 0.6450980392156862 589 | }, 590 | "accent": true 591 | }, 592 | "sky": { 593 | "name": "Sky", 594 | "order": 10, 595 | "hex": "#99d1db", 596 | "rgb": { 597 | "r": 153, 598 | "g": 209, 599 | "b": 219 600 | }, 601 | "hsl": { 602 | "h": 189.09090909090907, 603 | "s": 0.47826086956521735, 604 | "l": 0.7294117647058823 605 | }, 606 | "accent": true 607 | }, 608 | "sapphire": { 609 | "name": "Sapphire", 610 | "order": 11, 611 | "hex": "#85c1dc", 612 | "rgb": { 613 | "r": 133, 614 | "g": 193, 615 | "b": 220 616 | }, 617 | "hsl": { 618 | "h": 198.62068965517244, 619 | "s": 0.5541401273885351, 620 | "l": 0.692156862745098 621 | }, 622 | "accent": true 623 | }, 624 | "blue": { 625 | "name": "Blue", 626 | "order": 12, 627 | "hex": "#8caaee", 628 | "rgb": { 629 | "r": 140, 630 | "g": 170, 631 | "b": 238 632 | }, 633 | "hsl": { 634 | "h": 221.6326530612245, 635 | "s": 0.7424242424242424, 636 | "l": 0.7411764705882353 637 | }, 638 | "accent": true 639 | }, 640 | "lavender": { 641 | "name": "Lavender", 642 | "order": 13, 643 | "hex": "#babbf1", 644 | "rgb": { 645 | "r": 186, 646 | "g": 187, 647 | "b": 241 648 | }, 649 | "hsl": { 650 | "h": 238.90909090909093, 651 | "s": 0.6626506024096385, 652 | "l": 0.8372549019607842 653 | }, 654 | "accent": true 655 | }, 656 | "text": { 657 | "name": "Text", 658 | "order": 14, 659 | "hex": "#c6d0f5", 660 | "rgb": { 661 | "r": 198, 662 | "g": 208, 663 | "b": 245 664 | }, 665 | "hsl": { 666 | "h": 227.2340425531915, 667 | "s": 0.7014925373134333, 668 | "l": 0.8686274509803922 669 | }, 670 | "accent": false 671 | }, 672 | "subtext1": { 673 | "name": "Subtext 1", 674 | "order": 15, 675 | "hex": "#b5bfe2", 676 | "rgb": { 677 | "r": 181, 678 | "g": 191, 679 | "b": 226 680 | }, 681 | "hsl": { 682 | "h": 226.66666666666669, 683 | "s": 0.43689320388349495, 684 | "l": 0.7980392156862746 685 | }, 686 | "accent": false 687 | }, 688 | "subtext0": { 689 | "name": "Subtext 0", 690 | "order": 16, 691 | "hex": "#a5adce", 692 | "rgb": { 693 | "r": 165, 694 | "g": 173, 695 | "b": 206 696 | }, 697 | "hsl": { 698 | "h": 228.29268292682926, 699 | "s": 0.2949640287769784, 700 | "l": 0.7274509803921569 701 | }, 702 | "accent": false 703 | }, 704 | "overlay2": { 705 | "name": "Overlay 2", 706 | "order": 17, 707 | "hex": "#949cbb", 708 | "rgb": { 709 | "r": 148, 710 | "g": 156, 711 | "b": 187 712 | }, 713 | "hsl": { 714 | "h": 227.69230769230768, 715 | "s": 0.22285714285714275, 716 | "l": 0.6568627450980392 717 | }, 718 | "accent": false 719 | }, 720 | "overlay1": { 721 | "name": "Overlay 1", 722 | "order": 18, 723 | "hex": "#838ba7", 724 | "rgb": { 725 | "r": 131, 726 | "g": 139, 727 | "b": 167 728 | }, 729 | "hsl": { 730 | "h": 226.66666666666669, 731 | "s": 0.16981132075471703, 732 | "l": 0.584313725490196 733 | }, 734 | "accent": false 735 | }, 736 | "overlay0": { 737 | "name": "Overlay 0", 738 | "order": 19, 739 | "hex": "#737994", 740 | "rgb": { 741 | "r": 115, 742 | "g": 121, 743 | "b": 148 744 | }, 745 | "hsl": { 746 | "h": 229.0909090909091, 747 | "s": 0.13360323886639683, 748 | "l": 0.515686274509804 749 | }, 750 | "accent": false 751 | }, 752 | "surface2": { 753 | "name": "Surface 2", 754 | "order": 20, 755 | "hex": "#626880", 756 | "rgb": { 757 | "r": 98, 758 | "g": 104, 759 | "b": 128 760 | }, 761 | "hsl": { 762 | "h": 228.00000000000003, 763 | "s": 0.1327433628318584, 764 | "l": 0.44313725490196076 765 | }, 766 | "accent": false 767 | }, 768 | "surface1": { 769 | "name": "Surface 1", 770 | "order": 21, 771 | "hex": "#51576d", 772 | "rgb": { 773 | "r": 81, 774 | "g": 87, 775 | "b": 109 776 | }, 777 | "hsl": { 778 | "h": 227.14285714285714, 779 | "s": 0.14736842105263157, 780 | "l": 0.37254901960784315 781 | }, 782 | "accent": false 783 | }, 784 | "surface0": { 785 | "name": "Surface 0", 786 | "order": 22, 787 | "hex": "#414559", 788 | "rgb": { 789 | "r": 65, 790 | "g": 69, 791 | "b": 89 792 | }, 793 | "hsl": { 794 | "h": 230.00000000000003, 795 | "s": 0.15584415584415584, 796 | "l": 0.30196078431372547 797 | }, 798 | "accent": false 799 | }, 800 | "base": { 801 | "name": "Base", 802 | "order": 23, 803 | "hex": "#303446", 804 | "rgb": { 805 | "r": 48, 806 | "g": 52, 807 | "b": 70 808 | }, 809 | "hsl": { 810 | "h": 229.0909090909091, 811 | "s": 0.18644067796610175, 812 | "l": 0.23137254901960785 813 | }, 814 | "accent": false 815 | }, 816 | "mantle": { 817 | "name": "Mantle", 818 | "order": 24, 819 | "hex": "#292c3c", 820 | "rgb": { 821 | "r": 41, 822 | "g": 44, 823 | "b": 60 824 | }, 825 | "hsl": { 826 | "h": 230.52631578947367, 827 | "s": 0.18811881188118806, 828 | "l": 0.19803921568627453 829 | }, 830 | "accent": false 831 | }, 832 | "crust": { 833 | "name": "Crust", 834 | "order": 25, 835 | "hex": "#232634", 836 | "rgb": { 837 | "r": 35, 838 | "g": 38, 839 | "b": 52 840 | }, 841 | "hsl": { 842 | "h": 229.41176470588238, 843 | "s": 0.19540229885057467, 844 | "l": 0.17058823529411765 845 | }, 846 | "accent": false 847 | } 848 | } 849 | }, 850 | "macchiato": { 851 | "name": "Macchiato", 852 | "emoji": "🌺", 853 | "order": 2, 854 | "dark": true, 855 | "colors": { 856 | "rosewater": { 857 | "name": "Rosewater", 858 | "order": 0, 859 | "hex": "#f4dbd6", 860 | "rgb": { 861 | "r": 244, 862 | "g": 219, 863 | "b": 214 864 | }, 865 | "hsl": { 866 | "h": 9.999999999999963, 867 | "s": 0.5769230769230775, 868 | "l": 0.8980392156862745 869 | }, 870 | "accent": true 871 | }, 872 | "flamingo": { 873 | "name": "Flamingo", 874 | "order": 1, 875 | "hex": "#f0c6c6", 876 | "rgb": { 877 | "r": 240, 878 | "g": 198, 879 | "b": 198 880 | }, 881 | "hsl": { 882 | "h": 0, 883 | "s": 0.5833333333333333, 884 | "l": 0.8588235294117648 885 | }, 886 | "accent": true 887 | }, 888 | "pink": { 889 | "name": "Pink", 890 | "order": 2, 891 | "hex": "#f5bde6", 892 | "rgb": { 893 | "r": 245, 894 | "g": 189, 895 | "b": 230 896 | }, 897 | "hsl": { 898 | "h": 316.0714285714286, 899 | "s": 0.7368421052631583, 900 | "l": 0.8509803921568628 901 | }, 902 | "accent": true 903 | }, 904 | "mauve": { 905 | "name": "Mauve", 906 | "order": 3, 907 | "hex": "#c6a0f6", 908 | "rgb": { 909 | "r": 198, 910 | "g": 160, 911 | "b": 246 912 | }, 913 | "hsl": { 914 | "h": 266.51162790697674, 915 | "s": 0.8269230769230772, 916 | "l": 0.7960784313725491 917 | }, 918 | "accent": true 919 | }, 920 | "red": { 921 | "name": "Red", 922 | "order": 4, 923 | "hex": "#ed8796", 924 | "rgb": { 925 | "r": 237, 926 | "g": 135, 927 | "b": 150 928 | }, 929 | "hsl": { 930 | "h": 351.1764705882353, 931 | "s": 0.7391304347826088, 932 | "l": 0.7294117647058824 933 | }, 934 | "accent": true 935 | }, 936 | "maroon": { 937 | "name": "Maroon", 938 | "order": 5, 939 | "hex": "#ee99a0", 940 | "rgb": { 941 | "r": 238, 942 | "g": 153, 943 | "b": 160 944 | }, 945 | "hsl": { 946 | "h": 355.05882352941177, 947 | "s": 0.7142857142857143, 948 | "l": 0.7666666666666666 949 | }, 950 | "accent": true 951 | }, 952 | "peach": { 953 | "name": "Peach", 954 | "order": 6, 955 | "hex": "#f5a97f", 956 | "rgb": { 957 | "r": 245, 958 | "g": 169, 959 | "b": 127 960 | }, 961 | "hsl": { 962 | "h": 21.355932203389827, 963 | "s": 0.8550724637681162, 964 | "l": 0.7294117647058824 965 | }, 966 | "accent": true 967 | }, 968 | "yellow": { 969 | "name": "Yellow", 970 | "order": 7, 971 | "hex": "#eed49f", 972 | "rgb": { 973 | "r": 238, 974 | "g": 212, 975 | "b": 159 976 | }, 977 | "hsl": { 978 | "h": 40.253164556962034, 979 | "s": 0.6991150442477877, 980 | "l": 0.7784313725490196 981 | }, 982 | "accent": true 983 | }, 984 | "green": { 985 | "name": "Green", 986 | "order": 8, 987 | "hex": "#a6da95", 988 | "rgb": { 989 | "r": 166, 990 | "g": 218, 991 | "b": 149 992 | }, 993 | "hsl": { 994 | "h": 105.21739130434783, 995 | "s": 0.4825174825174825, 996 | "l": 0.7196078431372549 997 | }, 998 | "accent": true 999 | }, 1000 | "teal": { 1001 | "name": "Teal", 1002 | "order": 9, 1003 | "hex": "#8bd5ca", 1004 | "rgb": { 1005 | "r": 139, 1006 | "g": 213, 1007 | "b": 202 1008 | }, 1009 | "hsl": { 1010 | "h": 171.08108108108107, 1011 | "s": 0.46835443037974706, 1012 | "l": 0.6901960784313725 1013 | }, 1014 | "accent": true 1015 | }, 1016 | "sky": { 1017 | "name": "Sky", 1018 | "order": 10, 1019 | "hex": "#91d7e3", 1020 | "rgb": { 1021 | "r": 145, 1022 | "g": 215, 1023 | "b": 227 1024 | }, 1025 | "hsl": { 1026 | "h": 188.78048780487802, 1027 | "s": 0.5942028985507245, 1028 | "l": 0.7294117647058823 1029 | }, 1030 | "accent": true 1031 | }, 1032 | "sapphire": { 1033 | "name": "Sapphire", 1034 | "order": 11, 1035 | "hex": "#7dc4e4", 1036 | "rgb": { 1037 | "r": 125, 1038 | "g": 196, 1039 | "b": 228 1040 | }, 1041 | "hsl": { 1042 | "h": 198.64077669902912, 1043 | "s": 0.6560509554140128, 1044 | "l": 0.692156862745098 1045 | }, 1046 | "accent": true 1047 | }, 1048 | "blue": { 1049 | "name": "Blue", 1050 | "order": 12, 1051 | "hex": "#8aadf4", 1052 | "rgb": { 1053 | "r": 138, 1054 | "g": 173, 1055 | "b": 244 1056 | }, 1057 | "hsl": { 1058 | "h": 220.188679245283, 1059 | "s": 0.8281250000000003, 1060 | "l": 0.7490196078431373 1061 | }, 1062 | "accent": true 1063 | }, 1064 | "lavender": { 1065 | "name": "Lavender", 1066 | "order": 13, 1067 | "hex": "#b7bdf8", 1068 | "rgb": { 1069 | "r": 183, 1070 | "g": 189, 1071 | "b": 248 1072 | }, 1073 | "hsl": { 1074 | "h": 234.46153846153848, 1075 | "s": 0.8227848101265824, 1076 | "l": 0.8450980392156863 1077 | }, 1078 | "accent": true 1079 | }, 1080 | "text": { 1081 | "name": "Text", 1082 | "order": 14, 1083 | "hex": "#cad3f5", 1084 | "rgb": { 1085 | "r": 202, 1086 | "g": 211, 1087 | "b": 245 1088 | }, 1089 | "hsl": { 1090 | "h": 227.4418604651163, 1091 | "s": 0.6825396825396831, 1092 | "l": 0.8764705882352941 1093 | }, 1094 | "accent": false 1095 | }, 1096 | "subtext1": { 1097 | "name": "Subtext 1", 1098 | "order": 15, 1099 | "hex": "#b8c0e0", 1100 | "rgb": { 1101 | "r": 184, 1102 | "g": 192, 1103 | "b": 224 1104 | }, 1105 | "hsl": { 1106 | "h": 228, 1107 | "s": 0.39215686274509803, 1108 | "l": 0.8 1109 | }, 1110 | "accent": false 1111 | }, 1112 | "subtext0": { 1113 | "name": "Subtext 0", 1114 | "order": 16, 1115 | "hex": "#a5adcb", 1116 | "rgb": { 1117 | "r": 165, 1118 | "g": 173, 1119 | "b": 203 1120 | }, 1121 | "hsl": { 1122 | "h": 227.36842105263156, 1123 | "s": 0.2676056338028167, 1124 | "l": 0.7215686274509804 1125 | }, 1126 | "accent": false 1127 | }, 1128 | "overlay2": { 1129 | "name": "Overlay 2", 1130 | "order": 17, 1131 | "hex": "#939ab7", 1132 | "rgb": { 1133 | "r": 147, 1134 | "g": 154, 1135 | "b": 183 1136 | }, 1137 | "hsl": { 1138 | "h": 228.33333333333331, 1139 | "s": 0.2000000000000001, 1140 | "l": 0.6470588235294117 1141 | }, 1142 | "accent": false 1143 | }, 1144 | "overlay1": { 1145 | "name": "Overlay 1", 1146 | "order": 18, 1147 | "hex": "#8087a2", 1148 | "rgb": { 1149 | "r": 128, 1150 | "g": 135, 1151 | "b": 162 1152 | }, 1153 | "hsl": { 1154 | "h": 227.6470588235294, 1155 | "s": 0.1545454545454545, 1156 | "l": 0.5686274509803921 1157 | }, 1158 | "accent": false 1159 | }, 1160 | "overlay0": { 1161 | "name": "Overlay 0", 1162 | "order": 19, 1163 | "hex": "#6e738d", 1164 | "rgb": { 1165 | "r": 110, 1166 | "g": 115, 1167 | "b": 141 1168 | }, 1169 | "hsl": { 1170 | "h": 230.32258064516128, 1171 | "s": 0.12350597609561753, 1172 | "l": 0.49215686274509807 1173 | }, 1174 | "accent": false 1175 | }, 1176 | "surface2": { 1177 | "name": "Surface 2", 1178 | "order": 20, 1179 | "hex": "#5b6078", 1180 | "rgb": { 1181 | "r": 91, 1182 | "g": 96, 1183 | "b": 120 1184 | }, 1185 | "hsl": { 1186 | "h": 229.65517241379308, 1187 | "s": 0.13744075829383887, 1188 | "l": 0.4137254901960784 1189 | }, 1190 | "accent": false 1191 | }, 1192 | "surface1": { 1193 | "name": "Surface 1", 1194 | "order": 21, 1195 | "hex": "#494d64", 1196 | "rgb": { 1197 | "r": 73, 1198 | "g": 77, 1199 | "b": 100 1200 | }, 1201 | "hsl": { 1202 | "h": 231.11111111111114, 1203 | "s": 0.15606936416184972, 1204 | "l": 0.3392156862745098 1205 | }, 1206 | "accent": false 1207 | }, 1208 | "surface0": { 1209 | "name": "Surface 0", 1210 | "order": 22, 1211 | "hex": "#363a4f", 1212 | "rgb": { 1213 | "r": 54, 1214 | "g": 58, 1215 | "b": 79 1216 | }, 1217 | "hsl": { 1218 | "h": 230.4, 1219 | "s": 0.1879699248120301, 1220 | "l": 0.2607843137254902 1221 | }, 1222 | "accent": false 1223 | }, 1224 | "base": { 1225 | "name": "Base", 1226 | "order": 23, 1227 | "hex": "#24273a", 1228 | "rgb": { 1229 | "r": 36, 1230 | "g": 39, 1231 | "b": 58 1232 | }, 1233 | "hsl": { 1234 | "h": 231.8181818181818, 1235 | "s": 0.23404255319148934, 1236 | "l": 0.1843137254901961 1237 | }, 1238 | "accent": false 1239 | }, 1240 | "mantle": { 1241 | "name": "Mantle", 1242 | "order": 24, 1243 | "hex": "#1e2030", 1244 | "rgb": { 1245 | "r": 30, 1246 | "g": 32, 1247 | "b": 48 1248 | }, 1249 | "hsl": { 1250 | "h": 233.33333333333334, 1251 | "s": 0.23076923076923075, 1252 | "l": 0.15294117647058825 1253 | }, 1254 | "accent": false 1255 | }, 1256 | "crust": { 1257 | "name": "Crust", 1258 | "order": 25, 1259 | "hex": "#181926", 1260 | "rgb": { 1261 | "r": 24, 1262 | "g": 25, 1263 | "b": 38 1264 | }, 1265 | "hsl": { 1266 | "h": 235.71428571428572, 1267 | "s": 0.22580645161290322, 1268 | "l": 0.12156862745098039 1269 | }, 1270 | "accent": false 1271 | } 1272 | } 1273 | }, 1274 | "mocha": { 1275 | "name": "Mocha", 1276 | "emoji": "🌿", 1277 | "order": 3, 1278 | "dark": true, 1279 | "colors": { 1280 | "rosewater": { 1281 | "name": "Rosewater", 1282 | "order": 0, 1283 | "hex": "#f5e0dc", 1284 | "rgb": { 1285 | "r": 245, 1286 | "g": 224, 1287 | "b": 220 1288 | }, 1289 | "hsl": { 1290 | "h": 9.599999999999968, 1291 | "s": 0.555555555555556, 1292 | "l": 0.911764705882353 1293 | }, 1294 | "accent": true 1295 | }, 1296 | "flamingo": { 1297 | "name": "Flamingo", 1298 | "order": 1, 1299 | "hex": "#f2cdcd", 1300 | "rgb": { 1301 | "r": 242, 1302 | "g": 205, 1303 | "b": 205 1304 | }, 1305 | "hsl": { 1306 | "h": 0, 1307 | "s": 0.587301587301587, 1308 | "l": 0.8764705882352941 1309 | }, 1310 | "accent": true 1311 | }, 1312 | "pink": { 1313 | "name": "Pink", 1314 | "order": 2, 1315 | "hex": "#f5c2e7", 1316 | "rgb": { 1317 | "r": 245, 1318 | "g": 194, 1319 | "b": 231 1320 | }, 1321 | "hsl": { 1322 | "h": 316.4705882352941, 1323 | "s": 0.7183098591549301, 1324 | "l": 0.8607843137254902 1325 | }, 1326 | "accent": true 1327 | }, 1328 | "mauve": { 1329 | "name": "Mauve", 1330 | "order": 3, 1331 | "hex": "#cba6f7", 1332 | "rgb": { 1333 | "r": 203, 1334 | "g": 166, 1335 | "b": 247 1336 | }, 1337 | "hsl": { 1338 | "h": 267.4074074074074, 1339 | "s": 0.8350515463917528, 1340 | "l": 0.8098039215686275 1341 | }, 1342 | "accent": true 1343 | }, 1344 | "red": { 1345 | "name": "Red", 1346 | "order": 4, 1347 | "hex": "#f38ba8", 1348 | "rgb": { 1349 | "r": 243, 1350 | "g": 139, 1351 | "b": 168 1352 | }, 1353 | "hsl": { 1354 | "h": 343.2692307692308, 1355 | "s": 0.8124999999999998, 1356 | "l": 0.7490196078431373 1357 | }, 1358 | "accent": true 1359 | }, 1360 | "maroon": { 1361 | "name": "Maroon", 1362 | "order": 5, 1363 | "hex": "#eba0ac", 1364 | "rgb": { 1365 | "r": 235, 1366 | "g": 160, 1367 | "b": 172 1368 | }, 1369 | "hsl": { 1370 | "h": 350.4, 1371 | "s": 0.6521739130434779, 1372 | "l": 0.7745098039215685 1373 | }, 1374 | "accent": true 1375 | }, 1376 | "peach": { 1377 | "name": "Peach", 1378 | "order": 6, 1379 | "hex": "#fab387", 1380 | "rgb": { 1381 | "r": 250, 1382 | "g": 179, 1383 | "b": 135 1384 | }, 1385 | "hsl": { 1386 | "h": 22.95652173913043, 1387 | "s": 0.92, 1388 | "l": 0.7549019607843137 1389 | }, 1390 | "accent": true 1391 | }, 1392 | "yellow": { 1393 | "name": "Yellow", 1394 | "order": 7, 1395 | "hex": "#f9e2af", 1396 | "rgb": { 1397 | "r": 249, 1398 | "g": 226, 1399 | "b": 175 1400 | }, 1401 | "hsl": { 1402 | "h": 41.35135135135135, 1403 | "s": 0.8604651162790699, 1404 | "l": 0.8313725490196078 1405 | }, 1406 | "accent": true 1407 | }, 1408 | "green": { 1409 | "name": "Green", 1410 | "order": 8, 1411 | "hex": "#a6e3a1", 1412 | "rgb": { 1413 | "r": 166, 1414 | "g": 227, 1415 | "b": 161 1416 | }, 1417 | "hsl": { 1418 | "h": 115.45454545454544, 1419 | "s": 0.5409836065573769, 1420 | "l": 0.7607843137254902 1421 | }, 1422 | "accent": true 1423 | }, 1424 | "teal": { 1425 | "name": "Teal", 1426 | "order": 9, 1427 | "hex": "#94e2d5", 1428 | "rgb": { 1429 | "r": 148, 1430 | "g": 226, 1431 | "b": 213 1432 | }, 1433 | "hsl": { 1434 | "h": 170.00000000000003, 1435 | "s": 0.5735294117647057, 1436 | "l": 0.7333333333333334 1437 | }, 1438 | "accent": true 1439 | }, 1440 | "sky": { 1441 | "name": "Sky", 1442 | "order": 10, 1443 | "hex": "#89dceb", 1444 | "rgb": { 1445 | "r": 137, 1446 | "g": 220, 1447 | "b": 235 1448 | }, 1449 | "hsl": { 1450 | "h": 189.18367346938774, 1451 | "s": 0.7101449275362316, 1452 | "l": 0.7294117647058823 1453 | }, 1454 | "accent": true 1455 | }, 1456 | "sapphire": { 1457 | "name": "Sapphire", 1458 | "order": 11, 1459 | "hex": "#74c7ec", 1460 | "rgb": { 1461 | "r": 116, 1462 | "g": 199, 1463 | "b": 236 1464 | }, 1465 | "hsl": { 1466 | "h": 198.5, 1467 | "s": 0.759493670886076, 1468 | "l": 0.6901960784313725 1469 | }, 1470 | "accent": true 1471 | }, 1472 | "blue": { 1473 | "name": "Blue", 1474 | "order": 12, 1475 | "hex": "#89b4fa", 1476 | "rgb": { 1477 | "r": 137, 1478 | "g": 180, 1479 | "b": 250 1480 | }, 1481 | "hsl": { 1482 | "h": 217.1681415929203, 1483 | "s": 0.9186991869918699, 1484 | "l": 0.7588235294117647 1485 | }, 1486 | "accent": true 1487 | }, 1488 | "lavender": { 1489 | "name": "Lavender", 1490 | "order": 13, 1491 | "hex": "#b4befe", 1492 | "rgb": { 1493 | "r": 180, 1494 | "g": 190, 1495 | "b": 254 1496 | }, 1497 | "hsl": { 1498 | "h": 231.89189189189187, 1499 | "s": 0.9736842105263159, 1500 | "l": 0.8509803921568628 1501 | }, 1502 | "accent": true 1503 | }, 1504 | "text": { 1505 | "name": "Text", 1506 | "order": 14, 1507 | "hex": "#cdd6f4", 1508 | "rgb": { 1509 | "r": 205, 1510 | "g": 214, 1511 | "b": 244 1512 | }, 1513 | "hsl": { 1514 | "h": 226.15384615384616, 1515 | "s": 0.6393442622950825, 1516 | "l": 0.8803921568627451 1517 | }, 1518 | "accent": false 1519 | }, 1520 | "subtext1": { 1521 | "name": "Subtext 1", 1522 | "order": 15, 1523 | "hex": "#bac2de", 1524 | "rgb": { 1525 | "r": 186, 1526 | "g": 194, 1527 | "b": 222 1528 | }, 1529 | "hsl": { 1530 | "h": 226.66666666666669, 1531 | "s": 0.35294117647058837, 1532 | "l": 0.8 1533 | }, 1534 | "accent": false 1535 | }, 1536 | "subtext0": { 1537 | "name": "Subtext 0", 1538 | "order": 16, 1539 | "hex": "#a6adc8", 1540 | "rgb": { 1541 | "r": 166, 1542 | "g": 173, 1543 | "b": 200 1544 | }, 1545 | "hsl": { 1546 | "h": 227.6470588235294, 1547 | "s": 0.23611111111111102, 1548 | "l": 0.7176470588235294 1549 | }, 1550 | "accent": false 1551 | }, 1552 | "overlay2": { 1553 | "name": "Overlay 2", 1554 | "order": 17, 1555 | "hex": "#9399b2", 1556 | "rgb": { 1557 | "r": 147, 1558 | "g": 153, 1559 | "b": 178 1560 | }, 1561 | "hsl": { 1562 | "h": 228.38709677419354, 1563 | "s": 0.16756756756756758, 1564 | "l": 0.6372549019607843 1565 | }, 1566 | "accent": false 1567 | }, 1568 | "overlay1": { 1569 | "name": "Overlay 1", 1570 | "order": 18, 1571 | "hex": "#7f849c", 1572 | "rgb": { 1573 | "r": 127, 1574 | "g": 132, 1575 | "b": 156 1576 | }, 1577 | "hsl": { 1578 | "h": 229.65517241379308, 1579 | "s": 0.12775330396475776, 1580 | "l": 0.5549019607843138 1581 | }, 1582 | "accent": false 1583 | }, 1584 | "overlay0": { 1585 | "name": "Overlay 0", 1586 | "order": 19, 1587 | "hex": "#6c7086", 1588 | "rgb": { 1589 | "r": 108, 1590 | "g": 112, 1591 | "b": 134 1592 | }, 1593 | "hsl": { 1594 | "h": 230.7692307692308, 1595 | "s": 0.10743801652892565, 1596 | "l": 0.4745098039215686 1597 | }, 1598 | "accent": false 1599 | }, 1600 | "surface2": { 1601 | "name": "Surface 2", 1602 | "order": 20, 1603 | "hex": "#585b70", 1604 | "rgb": { 1605 | "r": 88, 1606 | "g": 91, 1607 | "b": 112 1608 | }, 1609 | "hsl": { 1610 | "h": 232.5, 1611 | "s": 0.12, 1612 | "l": 0.39215686274509803 1613 | }, 1614 | "accent": false 1615 | }, 1616 | "surface1": { 1617 | "name": "Surface 1", 1618 | "order": 21, 1619 | "hex": "#45475a", 1620 | "rgb": { 1621 | "r": 69, 1622 | "g": 71, 1623 | "b": 90 1624 | }, 1625 | "hsl": { 1626 | "h": 234.2857142857143, 1627 | "s": 0.13207547169811326, 1628 | "l": 0.31176470588235294 1629 | }, 1630 | "accent": false 1631 | }, 1632 | "surface0": { 1633 | "name": "Surface 0", 1634 | "order": 22, 1635 | "hex": "#313244", 1636 | "rgb": { 1637 | "r": 49, 1638 | "g": 50, 1639 | "b": 68 1640 | }, 1641 | "hsl": { 1642 | "h": 236.84210526315792, 1643 | "s": 0.16239316239316234, 1644 | "l": 0.22941176470588237 1645 | }, 1646 | "accent": false 1647 | }, 1648 | "base": { 1649 | "name": "Base", 1650 | "order": 23, 1651 | "hex": "#1e1e2e", 1652 | "rgb": { 1653 | "r": 30, 1654 | "g": 30, 1655 | "b": 46 1656 | }, 1657 | "hsl": { 1658 | "h": 240, 1659 | "s": 0.21052631578947367, 1660 | "l": 0.14901960784313725 1661 | }, 1662 | "accent": false 1663 | }, 1664 | "mantle": { 1665 | "name": "Mantle", 1666 | "order": 24, 1667 | "hex": "#181825", 1668 | "rgb": { 1669 | "r": 24, 1670 | "g": 24, 1671 | "b": 37 1672 | }, 1673 | "hsl": { 1674 | "h": 240, 1675 | "s": 0.2131147540983607, 1676 | "l": 0.11960784313725491 1677 | }, 1678 | "accent": false 1679 | }, 1680 | "crust": { 1681 | "name": "Crust", 1682 | "order": 25, 1683 | "hex": "#11111b", 1684 | "rgb": { 1685 | "r": 17, 1686 | "g": 17, 1687 | "b": 27 1688 | }, 1689 | "hsl": { 1690 | "h": 240, 1691 | "s": 0.22727272727272727, 1692 | "l": 0.08627450980392157 1693 | }, 1694 | "accent": false 1695 | } 1696 | } 1697 | } 1698 | } -------------------------------------------------------------------------------- /palette/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | catppuccin-java 7 | com.catppuccin 8 | 2.0.3 9 | 10 | 11 | jar 12 | catppuccin-palette 13 | 2.0.3 14 | catppuccin-palette 15 | 16 | 17 | UTF-8 18 | 1.8 19 | 1.8 20 | 21 | 22 | 23 | 24 | com.catppuccin 25 | catppuccin-processing 26 | 1.0.2 27 | 28 | 29 | org.junit.jupiter 30 | junit-jupiter-api 31 | 5.12.0 32 | test 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | maven-compiler-plugin 41 | 3.14.0 42 | 43 | 44 | 45 | com.catppuccin 46 | catppuccin-processing 47 | 1.0.2 48 | 49 | 50 | 51 | com.catppuccin.PaletteProcessor 52 | 53 | 54 | -ApalettePath=${project.basedir}/palette.json 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /palette/src/main/java/com/catppuccin/Color.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | /** 4 | * This class provides utility methods to provide different representations of the RGB color data. 5 | */ 6 | public class Color { 7 | private final int r; 8 | private final int g; 9 | private final int b; 10 | 11 | /** 12 | * Generate a Color based on the provided RGB values 13 | * @param r the red value 14 | * @param g the green value 15 | * @param b the blue value 16 | */ 17 | public Color(int r, int g, int b) { 18 | this.r = r; 19 | this.g = g; 20 | this.b = b; 21 | } 22 | 23 | /** 24 | * @return the red component 25 | */ 26 | public int r() { 27 | return this.r; 28 | } 29 | 30 | /** 31 | * @return the green component 32 | */ 33 | public int g() { 34 | return this.g; 35 | } 36 | 37 | /** 38 | * @return the blue component 39 | */ 40 | public int b() { 41 | return this.b; 42 | } 43 | 44 | /** 45 | * @return the color, as a hex string 46 | */ 47 | public String hex() { 48 | return String.format("%02x%02x%02x", this.r(), this.g(), this.b()); 49 | } 50 | 51 | /** 52 | * @return the components of the color as a 3 element array 53 | */ 54 | public int[] components() { 55 | return new int[]{ 56 | r(), 57 | g(), 58 | b() 59 | }; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "Color{" + 65 | "r=" + r + 66 | ", g=" + g + 67 | ", b=" + b + 68 | '}'; 69 | } 70 | 71 | @Override 72 | public boolean equals(Object obj) { 73 | if (this == obj) { 74 | return true; 75 | } 76 | 77 | if (!(obj instanceof Color)) { 78 | return false; 79 | } 80 | 81 | Color other = (Color) obj; 82 | return this.r == other.r && this.g == other.g && this.b == other.b; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /palette/src/main/java/com/catppuccin/Flavor.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | import java.util.List; 4 | 5 | public interface Flavor { 6 | 7 | /** 8 | * @return the name of the flavour (latte, frappe, macchiato or mocha) 9 | */ 10 | String name(); 11 | 12 | /** 13 | * @return the emoji that represents the flavor 14 | */ 15 | String emoji(); 16 | 17 | /** 18 | * @return whether this flavor is a designed for light mode 19 | */ 20 | boolean isLight(); 21 | 22 | /** 23 | * @return whether this flavor is a designed for dark mode 24 | */ 25 | boolean isDark(); 26 | 27 | /** 28 | * A convenience method to take all the colours and return them in an 29 | * iterable 30 | * {@link java.util.List}{@code <}{@link com.catppuccin.Pair}{@code <}{@link String}, {@link com.catppuccin.Color}{@code >>} 31 | * 32 | * @return 33 | * {@link java.util.List}{@code <}{@link com.catppuccin.Pair}{@code <}{@link String}, {@link com.catppuccin.Color}{@code >>} 34 | */ 35 | List> toList(); 36 | 37 | /** 38 | * @return {@link com.catppuccin.Color} 39 | */ 40 | Color rosewater(); 41 | 42 | /** 43 | * @return {@link com.catppuccin.Color} 44 | */ 45 | Color flamingo(); 46 | 47 | /** 48 | * @return {@link com.catppuccin.Color} 49 | */ 50 | Color pink(); 51 | 52 | /** 53 | * @return {@link com.catppuccin.Color} 54 | */ 55 | Color mauve(); 56 | 57 | /** 58 | * @return {@link com.catppuccin.Color} 59 | */ 60 | Color red(); 61 | 62 | /** 63 | * @return {@link com.catppuccin.Color} 64 | */ 65 | Color maroon(); 66 | 67 | /** 68 | * @return {@link com.catppuccin.Color} 69 | */ 70 | Color peach(); 71 | 72 | /** 73 | * @return {@link com.catppuccin.Color} 74 | */ 75 | Color yellow(); 76 | 77 | /** 78 | * @return {@link com.catppuccin.Color} 79 | */ 80 | Color green(); 81 | 82 | /** 83 | * @return {@link com.catppuccin.Color} 84 | */ 85 | Color teal(); 86 | 87 | /** 88 | * @return {@link com.catppuccin.Color} 89 | */ 90 | Color sky(); 91 | 92 | /** 93 | * @return {@link com.catppuccin.Color} 94 | */ 95 | /** 96 | * 97 | * @return {@link com.catppuccin.Color} 98 | */ 99 | Color sapphire(); 100 | 101 | /** 102 | * 103 | * @return {@link com.catppuccin.Color} 104 | */ 105 | Color blue(); 106 | 107 | /** 108 | * 109 | * @return {@link com.catppuccin.Color} 110 | */ 111 | Color lavender(); 112 | 113 | /** 114 | * 115 | * @return {@link com.catppuccin.Color} 116 | */ 117 | Color text(); 118 | 119 | /** 120 | * 121 | * @return {@link com.catppuccin.Color} 122 | */ 123 | Color subtext1(); 124 | 125 | /** 126 | * 127 | * @return {@link com.catppuccin.Color} 128 | */ 129 | Color subtext0(); 130 | 131 | /** 132 | * 133 | * @return {@link com.catppuccin.Color} 134 | */ 135 | Color overlay2(); 136 | 137 | /** 138 | * 139 | * @return {@link com.catppuccin.Color} 140 | */ 141 | Color overlay1(); 142 | 143 | /** 144 | * 145 | * @return {@link com.catppuccin.Color} 146 | */ 147 | Color overlay0(); 148 | 149 | /** 150 | * 151 | * @return {@link com.catppuccin.Color} 152 | */ 153 | Color surface2(); 154 | 155 | /** 156 | * 157 | * @return {@link com.catppuccin.Color} 158 | */ 159 | Color surface1(); 160 | 161 | /** 162 | * 163 | * @return {@link com.catppuccin.Color} 164 | */ 165 | Color surface0(); 166 | 167 | /** 168 | * 169 | * @return {@link com.catppuccin.Color} 170 | */ 171 | Color base(); 172 | 173 | /** 174 | * 175 | * @return {@link com.catppuccin.Color} 176 | */ 177 | Color mantle(); 178 | 179 | /** 180 | * @return {@link com.catppuccin.Color} 181 | */ 182 | Color crust(); 183 | } 184 | -------------------------------------------------------------------------------- /palette/src/main/java/com/catppuccin/Pair.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | import java.util.Objects; 4 | 5 | public final class Pair { 6 | private final T key; 7 | private final U value; 8 | 9 | Pair(T key, U value) { 10 | this.key = key; 11 | this.value = value; 12 | } 13 | 14 | public T key() { 15 | return this.key; 16 | } 17 | 18 | public U value() { 19 | return this.value; 20 | } 21 | 22 | @Override 23 | public boolean equals(Object obj) { 24 | if (obj == this) return true; 25 | if (obj == null || obj.getClass() != this.getClass()) return false; 26 | Pair that = (Pair) obj; 27 | return Objects.equals(this.key, that.key) && 28 | Objects.equals(this.value, that.value); 29 | } 30 | 31 | @Override 32 | public int hashCode() { 33 | return Objects.hash(key, value); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "Pair[" + 39 | "key=" + key + ", " + 40 | "value=" + value + ']'; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /palette/src/main/java/com/catppuccin/Palette.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * This class represents the entirety of the Catppuccin v0.2.0 palette. 8 | */ 9 | @GeneratedPalette(target="com.catppuccin.BuiltinPalettes") 10 | public class Palette 11 | { 12 | /** 13 | * Mocha flavored Catppuccin 14 | */ 15 | public static final Flavor MOCHA = com.catppuccin.BuiltinPalettes.MOCHA; 16 | 17 | /** 18 | * Macchiato flavored Catppuccin 19 | */ 20 | public static final Flavor MACCHIATO = com.catppuccin.BuiltinPalettes.MACCHIATO; 21 | 22 | /** 23 | * Frappe flavored Catppuccin 24 | */ 25 | public static final Flavor FRAPPE = com.catppuccin.BuiltinPalettes.FRAPPE; 26 | 27 | /** 28 | * Latte flavored Catppuccin 29 | */ 30 | public static final Flavor LATTE = com.catppuccin.BuiltinPalettes.LATTE; 31 | 32 | /** 33 | * @return all the flavors, in one list, for convenience 34 | */ 35 | public List toList() { 36 | List out = new ArrayList<>(); 37 | 38 | out.add(MOCHA); 39 | out.add(MACCHIATO); 40 | out.add(FRAPPE); 41 | out.add(LATTE); 42 | 43 | return out; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /palette/src/test/java/com/catppuccin/PaletteTests.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class Oled extends BuiltinPalettes.Mocha { 8 | @Override 9 | public Color base() { 10 | return new Color(0, 0, 0); 11 | } 12 | } 13 | 14 | public class PaletteTests { 15 | @Test 16 | public void mochaExistsAndReturnsCorrectDetails() { 17 | Flavor mocha = Palette.MOCHA; 18 | assertEquals("mocha", mocha.name(), "mocha to have the correct name"); 19 | assertEquals(mocha.base().hex(), "1e1e2e"); 20 | assertEquals(mocha.base().r(), 30); 21 | assertEquals(mocha.base().g(), 30); 22 | assertEquals(mocha.base().b(), 46); 23 | assertArrayEquals(mocha.base().components(), new int[]{30, 30, 46}); 24 | } 25 | 26 | @Test 27 | public void frappeExistsAndReturnsCorrectDetails() { 28 | assertEquals("frappe", Palette.FRAPPE.name(), "frappe to have the correct name"); 29 | } 30 | 31 | @Test 32 | public void macchiatoExistsAndReturnsCorrectDetails() { 33 | assertEquals("macchiato", Palette.MACCHIATO.name(), "macchiato to have the correct name"); 34 | } 35 | 36 | @Test 37 | public void latteExistsAndReturnsCorrectDetails() { 38 | assertEquals("latte", Palette.LATTE.name(), "latte to have the correct name"); 39 | } 40 | 41 | @Test 42 | public void oledOverridesProperly() { 43 | Flavor mocha = Palette.MOCHA; 44 | Flavor oled = new Oled(); 45 | 46 | assertEquals(mocha.red(), oled.red(), "oled red and mocha red to be the same"); 47 | assertEquals(new Color(0, 0, 0), oled.base(), "oled base is 0, 0, 0"); 48 | assertNotEquals(mocha.base(), oled.base(), "oled base and mocha base to not be the same"); 49 | } 50 | 51 | @Test 52 | public void darkLightSet() { 53 | assertTrue(Palette.MOCHA.isDark(), "mocha to be dark"); 54 | assertFalse(Palette.MOCHA.isLight(), "mocha to be not light"); 55 | 56 | assertTrue(Palette.MACCHIATO.isDark(), "macchiato to be dark"); 57 | assertFalse(Palette.MACCHIATO.isLight(), "macchiato to be not light"); 58 | 59 | assertTrue(Palette.FRAPPE.isDark(), "frappe to be dark"); 60 | assertFalse(Palette.FRAPPE.isLight(), "frappe to be not light"); 61 | 62 | assertTrue(Palette.LATTE.isLight(), "latte to be light"); 63 | assertFalse(Palette.LATTE.isDark(), "latte to be not dark"); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.catppuccin 7 | catppuccin-java 8 | 2.0.3 9 | pom 10 | catppuccin-java 11 | Soothing pastel library for Catppuccin 12 | https://github.com/catppuccin/java 13 | 14 | 15 | UTF-8 16 | 1.8 17 | 1.8 18 | 19 | 20 | 21 | scm:git:https://github.com/catppuccin/java.git 22 | scm:git:git@github.com:catppuccin/java.git 23 | https://github.com/catppuccin/java 24 | 25 | 26 | 27 | 28 | sgoudham 29 | Goudham Suresh 30 | sgoudham@gmail.com 31 | Catppuccin 32 | https://github.com/catppuccin 33 | 34 | 35 | nullishamy 36 | Amy Erskine 37 | contact@amyerskine.me 38 | Catppuccin 39 | https://github.com/catppuccin 40 | 41 | 42 | 43 | 44 | GitHub Actions 45 | https://github.com/catppuccin/java/actions 46 | 47 | 48 | 49 | 50 | MIT License 51 | https://www.opensource.org/licenses/mit-license.php 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | com.catppuccin 60 | catppuccin-processing 61 | 1.0.2 62 | 63 | 64 | 65 | 66 | 67 | 68 | ossrh 69 | https://s01.oss.sonatype.org/content/repositories/snapshots 70 | 71 | 72 | ossrh 73 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 74 | 75 | 76 | 77 | 78 | 79 | 80 | org.apache.maven.plugins 81 | maven-gpg-plugin 82 | 3.2.7 83 | 84 | 85 | sign-artifacts 86 | verify 87 | 88 | sign 89 | 90 | 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-javadoc-plugin 96 | 3.11.2 97 | 98 | 99 | attach-javadocs 100 | 101 | jar 102 | 103 | 104 | 105 | 106 | 1.8 107 | 108 | 109 | 110 | org.sonatype.plugins 111 | nexus-staging-maven-plugin 112 | 1.7.0 113 | true 114 | 115 | ossrh 116 | https://s01.oss.sonatype.org/ 117 | false 118 | 119 | 120 | 121 | org.apache.maven.plugins 122 | maven-source-plugin 123 | 3.3.1 124 | 125 | 126 | attach-sources 127 | 128 | jar-no-fork 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | processing 138 | palette 139 | 140 | 141 | -------------------------------------------------------------------------------- /processing/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | catppuccin-java 7 | com.catppuccin 8 | 2.0.3 9 | 10 | 11 | jar 12 | catppuccin-processing 13 | 1.0.2 14 | catppuccin-processing 15 | Soothing pastel code generator for Catppuccin 16 | https://github.com/catppuccin/java 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | com.squareup 27 | javapoet 28 | 1.13.0 29 | 30 | 31 | com.google.code.gson 32 | gson 33 | 2.12.1 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /processing/src/main/java/com/catppuccin/GeneratedPalette.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.TYPE) 9 | @Retention(RetentionPolicy.SOURCE) 10 | public @interface GeneratedPalette { 11 | String target(); 12 | } 13 | -------------------------------------------------------------------------------- /processing/src/main/java/com/catppuccin/POJO.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | import java.util.Map; 4 | 5 | public class POJO { 6 | public static class Root { 7 | public Flavor latte; 8 | public Flavor frappe; 9 | public Flavor macchiato; 10 | public Flavor mocha; 11 | 12 | @Override 13 | public String toString() { 14 | return "Root{" + 15 | "latte=" + latte + 16 | ", frappe=" + frappe + 17 | ", macchiato=" + macchiato + 18 | ", mocha=" + mocha + 19 | '}'; 20 | } 21 | } 22 | 23 | public class Flavor { 24 | private String name; 25 | private long order; 26 | private String emoji; 27 | private boolean dark; 28 | private Map colors; 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public String getEmoji() { 35 | return emoji; 36 | } 37 | 38 | public void setName(String value) { 39 | this.name = value; 40 | } 41 | 42 | public long getOrder() { 43 | return order; 44 | } 45 | 46 | public void setOrder(long value) { 47 | this.order = value; 48 | } 49 | 50 | public boolean isDark() { 51 | return dark; 52 | } 53 | 54 | public boolean isLight() { 55 | return !isDark(); 56 | } 57 | 58 | public void setDark(boolean value) { 59 | this.dark = value; 60 | } 61 | 62 | public Map getColors() { 63 | return colors; 64 | } 65 | 66 | public void setColors(Map value) { 67 | this.colors = value; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "Flavor{" + 73 | "name='" + name + '\'' + 74 | "emoji='" + emoji + '\'' + 75 | ", order=" + order + 76 | ", dark=" + dark + 77 | ", colors=" + colors + 78 | '}'; 79 | } 80 | } 81 | 82 | public class Color { 83 | private String name; 84 | private long order; 85 | private String hex; 86 | private RGB rgb; 87 | private Hsl hsl; 88 | private boolean accent; 89 | 90 | public String getName() { 91 | return name; 92 | } 93 | 94 | public void setName(String value) { 95 | this.name = value; 96 | } 97 | 98 | public long getOrder() { 99 | return order; 100 | } 101 | 102 | public void setOrder(long value) { 103 | this.order = value; 104 | } 105 | 106 | public String getHex() { 107 | return hex; 108 | } 109 | 110 | public void setHex(String value) { 111 | this.hex = value; 112 | } 113 | 114 | public RGB getRGB() { 115 | return rgb; 116 | } 117 | 118 | public void setRGB(RGB value) { 119 | this.rgb = value; 120 | } 121 | 122 | public Hsl getHsl() { 123 | return hsl; 124 | } 125 | 126 | public void setHsl(Hsl value) { 127 | this.hsl = value; 128 | } 129 | 130 | public boolean getAccent() { 131 | return accent; 132 | } 133 | 134 | public void setAccent(boolean value) { 135 | this.accent = value; 136 | } 137 | 138 | @Override 139 | public String toString() { 140 | return "Color{" + 141 | "name='" + name + '\'' + 142 | ", order=" + order + 143 | ", hex='" + hex + '\'' + 144 | ", rgb=" + rgb + 145 | ", hsl=" + hsl + 146 | ", accent=" + accent + 147 | '}'; 148 | } 149 | } 150 | 151 | public class Hsl { 152 | private double h; 153 | private double s; 154 | private double l; 155 | 156 | public double getH() { 157 | return h; 158 | } 159 | 160 | public void setH(double value) { 161 | this.h = value; 162 | } 163 | 164 | public double getS() { 165 | return s; 166 | } 167 | 168 | public void setS(double value) { 169 | this.s = value; 170 | } 171 | 172 | public double getL() { 173 | return l; 174 | } 175 | 176 | public void setL(double value) { 177 | this.l = value; 178 | } 179 | 180 | @Override 181 | public String toString() { 182 | return "Hsl{" + 183 | "h=" + h + 184 | ", s=" + s + 185 | ", l=" + l + 186 | '}'; 187 | } 188 | } 189 | 190 | public class RGB { 191 | private int r; 192 | private int g; 193 | private int b; 194 | 195 | public int getR() { 196 | return r; 197 | } 198 | 199 | public void setR(int value) { 200 | this.r = value; 201 | } 202 | 203 | public int getG() { 204 | return g; 205 | } 206 | 207 | public void setG(int value) { 208 | this.g = value; 209 | } 210 | 211 | public int getB() { 212 | return b; 213 | } 214 | 215 | public void setB(int value) { 216 | this.b = value; 217 | } 218 | 219 | @Override 220 | public String toString() { 221 | return "RGB{" + 222 | "r=" + r + 223 | ", g=" + g + 224 | ", b=" + b + 225 | '}'; 226 | } 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /processing/src/main/java/com/catppuccin/PaletteProcessor.java: -------------------------------------------------------------------------------- 1 | package com.catppuccin; 2 | 3 | import java.io.IOException; 4 | import java.io.Writer; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | import java.util.Map.Entry; 9 | import java.util.Set; 10 | 11 | import javax.annotation.processing.AbstractProcessor; 12 | import javax.annotation.processing.RoundEnvironment; 13 | import javax.annotation.processing.SupportedAnnotationTypes; 14 | import javax.annotation.processing.SupportedSourceVersion; 15 | import javax.lang.model.SourceVersion; 16 | import javax.lang.model.element.Element; 17 | import javax.lang.model.element.ElementKind; 18 | import javax.lang.model.element.Modifier; 19 | import javax.lang.model.element.TypeElement; 20 | import javax.tools.Diagnostic; 21 | import javax.tools.JavaFileObject; 22 | 23 | import com.google.gson.Gson; 24 | import com.squareup.javapoet.ClassName; 25 | import com.squareup.javapoet.FieldSpec; 26 | import com.squareup.javapoet.JavaFile; 27 | import com.squareup.javapoet.MethodSpec; 28 | import com.squareup.javapoet.ParameterizedTypeName; 29 | import com.squareup.javapoet.TypeName; 30 | import com.squareup.javapoet.TypeSpec; 31 | 32 | @SupportedAnnotationTypes( 33 | {"com.catppuccin.GeneratedPalette"} 34 | ) 35 | @SupportedSourceVersion(SourceVersion.RELEASE_8) 36 | public class PaletteProcessor extends AbstractProcessor { 37 | 38 | private static final String ROOT_PKG = "com.catppuccin"; 39 | private static final ClassName FLAVOR_CLASS = ClassName.get(ROOT_PKG, "Flavor"); 40 | private static final ClassName COLOR_CLASS = ClassName.get(ROOT_PKG, "Color"); 41 | private static final TypeName TO_LIST_RET 42 | = ParameterizedTypeName.get( 43 | ClassName.get("java.util", "List"), 44 | ParameterizedTypeName.get(ClassName.get(ROOT_PKG, "Pair"), 45 | ClassName.get("java.lang", "String"), ClassName.get(ROOT_PKG, "Color") 46 | ) 47 | ); 48 | 49 | private enum Flavor { 50 | MOCHA("mocha", "Mocha", "MOCHA", "new Mocha()", true), 51 | MACCHIATO("macchiato", "Macchiato", "MACCHIATO", "new Macchiato()", true), 52 | FRAPPE("frappe", "Frappe", "FRAPPE", "new Frappe()", true), 53 | LATTE("latte", "Latte", "LATTE", "new Latte()", false); 54 | 55 | private final String displayName; 56 | private final String generatedClassName; 57 | private final String fieldName; 58 | private final String initialiser; 59 | private final boolean isDark; 60 | 61 | Flavor(String displayName, String generatedClassName, String fieldName, String initialiser, boolean isDark) { 62 | this.displayName = displayName; 63 | this.generatedClassName = generatedClassName; 64 | this.fieldName = fieldName; 65 | this.initialiser = initialiser; 66 | this.isDark = isDark; 67 | } 68 | } 69 | 70 | private static TypeSpec.Builder attachPalette(POJO.Flavor flavor, TypeSpec.Builder spec) { 71 | for (Entry entry : flavor.getColors().entrySet()) { 72 | POJO.Color color = entry.getValue(); 73 | POJO.RGB rgb = color.getRGB(); 74 | 75 | MethodSpec method = MethodSpec 76 | .methodBuilder(entry.getKey()) 77 | .addModifiers(Modifier.PUBLIC) 78 | .addCode("return new Color($L, $L, $L);", rgb.getR(), rgb.getG(), rgb.getB()) 79 | .addJavadoc("@return {@link com.catppuccin.Color}") 80 | .addAnnotation(Override.class) 81 | .returns(COLOR_CLASS) 82 | .build(); 83 | 84 | spec.addMethod(method); 85 | } 86 | 87 | return spec; 88 | } 89 | 90 | private static MethodSpec toListImpl(POJO.Flavor flavor) { 91 | MethodSpec.Builder builder = MethodSpec 92 | .methodBuilder("toList") 93 | .addModifiers(Modifier.PUBLIC) 94 | .addAnnotation(Override.class) 95 | .addJavadoc("A convenience method to take all the colours and return them in an " 96 | + "iterable {@link java.util.List}{@code <}{@link com.catppuccin.Pair}{@code <}{@link String}, {@link com.catppuccin.Color}{@code >>}" 97 | + "\n" 98 | + "@return {@link java.util.List}{@code <}{@link com.catppuccin.Pair}{@code <}{@link String}, {@link com.catppuccin.Color}{@code >>}" 99 | ) 100 | .addStatement("List> out = new java.util.ArrayList<>()") 101 | .returns(TO_LIST_RET); 102 | 103 | for (Entry entry : flavor.getColors().entrySet()) { 104 | POJO.Color color = entry.getValue(); 105 | POJO.RGB rgb = color.getRGB(); 106 | builder.addStatement("out.add(new com.catppuccin.Pair<>($S, new Color($L, $L, $L)))", entry.getKey(), rgb.getR(), rgb.getG(), rgb.getB()); 107 | } 108 | 109 | builder.addStatement("return out"); 110 | 111 | return builder.build(); 112 | } 113 | 114 | private static TypeSpec buildStoredPalette(POJO.Flavor pflavor, Flavor flavor) { 115 | return attachPalette(pflavor, TypeSpec 116 | .classBuilder(flavor.generatedClassName) 117 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC) 118 | .addSuperinterface(FLAVOR_CLASS) 119 | .addMethod(MethodSpec 120 | .methodBuilder("name") 121 | .addModifiers(Modifier.PUBLIC) 122 | .addCode("return $S;", flavor.displayName) 123 | .addJavadoc("@return the name of the flavour (latte, frappe, macchiato or mocha)") 124 | .addAnnotation(Override.class) 125 | .returns(String.class) 126 | .build() 127 | ) 128 | .addMethod(MethodSpec 129 | .methodBuilder("emoji") 130 | .addModifiers(Modifier.PUBLIC) 131 | .addCode("return $S;", pflavor.getEmoji()) 132 | .addJavadoc("@return the emoji that represents the flavor") 133 | .addAnnotation(Override.class) 134 | .returns(String.class) 135 | .build() 136 | ) 137 | .addMethod(MethodSpec 138 | .methodBuilder("isLight") 139 | .addModifiers(Modifier.PUBLIC) 140 | .addCode("return $L;", !flavor.isDark) 141 | .addJavadoc("@return whether this flavor is a designed for light mode") 142 | .addAnnotation(Override.class) 143 | .returns(boolean.class) 144 | .build() 145 | ) 146 | .addMethod(MethodSpec 147 | .methodBuilder("isDark") 148 | .addModifiers(Modifier.PUBLIC) 149 | .addCode("return $L;", flavor.isDark) 150 | .addJavadoc("@return whether this flavor is a designed for dark mode") 151 | .addAnnotation(Override.class) 152 | .returns(boolean.class) 153 | .build() 154 | )) 155 | .addJavadoc("An individual flavor for the Catppuccin v0.2.0 palette, generated from the palette.json.") 156 | .addMethod(toListImpl(pflavor)) 157 | .build(); 158 | } 159 | 160 | private static FieldSpec buildStoredField(Flavor flavor) { 161 | ClassName className = ClassName.get("", flavor.generatedClassName); 162 | return FieldSpec 163 | .builder(className, flavor.fieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) 164 | .initializer(flavor.initialiser) 165 | .build(); 166 | } 167 | 168 | private POJO.Root loadPalette() throws IOException { 169 | String palettePath = processingEnv.getOptions().get("palettePath"); 170 | Path path = Paths.get(palettePath); 171 | String jsonString = new String(Files.readAllBytes(path)); 172 | 173 | Gson gson = new Gson(); 174 | 175 | return gson.fromJson(jsonString, POJO.Root.class); 176 | } 177 | 178 | private void processElement(Element element) throws IOException { 179 | GeneratedPalette paletteAnnotation = element.getAnnotation(GeneratedPalette.class); 180 | 181 | if (element.getKind() != ElementKind.CLASS) { 182 | error("The annotation @GeneratedPalette can only be applied on class: ", element); 183 | return; 184 | } 185 | 186 | POJO.Root json = loadPalette(); 187 | 188 | ClassName holderClassName = ClassName.bestGuess(paletteAnnotation.target()); 189 | TypeSpec holderClass = TypeSpec.classBuilder(holderClassName.simpleName()) 190 | .addModifiers(Modifier.PUBLIC) 191 | .addType(buildStoredPalette(json.mocha, Flavor.MOCHA)) 192 | .addField(buildStoredField(Flavor.MOCHA)) 193 | .addType(buildStoredPalette(json.macchiato, Flavor.MACCHIATO)) 194 | .addField(buildStoredField(Flavor.MACCHIATO)) 195 | .addType(buildStoredPalette(json.frappe, Flavor.FRAPPE)) 196 | .addField(buildStoredField(Flavor.FRAPPE)) 197 | .addType(buildStoredPalette(json.latte, Flavor.LATTE)) 198 | .addField(buildStoredField(Flavor.LATTE)) 199 | .addJavadoc("All the flavours, as specified by the palette.json, and generated by the processing lib") 200 | .build(); 201 | 202 | JavaFile javaFile = JavaFile.builder(ROOT_PKG, holderClass).build(); 203 | JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(paletteAnnotation.target()); 204 | 205 | try (Writer writer = sourceFile.openWriter()) { 206 | writer.write(javaFile.toString()); 207 | } 208 | } 209 | 210 | private void error(String msg, Element e) { 211 | processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, e); 212 | } 213 | 214 | @Override 215 | public boolean process(Set annotations, RoundEnvironment roundEnv) { 216 | if (annotations.isEmpty()) { 217 | return false; 218 | } 219 | 220 | Set elements = roundEnv.getElementsAnnotatedWith(GeneratedPalette.class); 221 | 222 | for (Element element : elements) { 223 | 224 | try { 225 | processElement(element); 226 | } catch (IOException ex) { 227 | error(ex.toString(), null); 228 | return false; 229 | } 230 | } 231 | 232 | return true; 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "local>catppuccin/renovate-config" 5 | ] 6 | } 7 | --------------------------------------------------------------------------------