Merge branch 'dev-restructure' of https://gitlab.com/hanifsalafi/web-humas-polri into prod
This commit is contained in:
commit
5c57e4b6ed
|
|
@ -3,13 +3,14 @@ import PasswordForm from "@/components/form/settings/password";
|
||||||
import ProfileForm from "@/components/form/settings/profile";
|
import ProfileForm from "@/components/form/settings/profile";
|
||||||
import { close, loading } from "@/config/swal";
|
import { close, loading } from "@/config/swal";
|
||||||
import { getDetailMasterUsers, getProfile } from "@/services/master-user";
|
import { getDetailMasterUsers, getProfile } from "@/services/master-user";
|
||||||
|
import { getCookiesDecrypt } from "@/utils/global";
|
||||||
import { Tab, Tabs } from "@heroui/react";
|
import { Tab, Tabs } from "@heroui/react";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
const [profile, setProfile] = useState<any>();
|
const [profile, setProfile] = useState<any>();
|
||||||
const uid = Cookies.get("uie");
|
const uid = getCookiesDecrypt("uie");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
initFetch();
|
initFetch();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function DocsLayout({
|
export default function DocsLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
import ListEnewsPolri from "@/components/table/tabel-emajalah-polri";
|
import ListEnewsPolri from "@/components/table/tabel-emajalah-polri";
|
||||||
|
|
||||||
export default function ListEnewsPage() {
|
export default function ListEnewsPage() {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function DetailEMajalahLayout({
|
export default function DetailEMajalahLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
import EMagazineDetail from "@/components/main/detail/e-magazine-detail";
|
import EMagazineDetail from "@/components/main/detail/e-magazine-detail";
|
||||||
import React, { Suspense, useEffect, useState } from "react";
|
import React, { Suspense, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function ApplicationLayout({
|
export default function ApplicationLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function KontakLayout({
|
export default function KontakLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,9 @@ import "@/styles/globals.css";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import { Providers } from "./providers";
|
import { Providers } from "./providers";
|
||||||
import LoadScript from "@/utils/global";
|
|
||||||
import { type ReactNode } from "react";
|
import { type ReactNode } from "react";
|
||||||
import LoadTawk from "@/components/ui/tawkto/load-tawk";
|
import LoadTawk from "@/components/ui/tawkto/load-tawk";
|
||||||
import Script from "next/script";
|
import LoadScript from "@/utils/loadsripct";
|
||||||
import dynamic from "next/dynamic";
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
// const Tawkto = dynamic(
|
// const Tawkto = dynamic(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
import ListNews from "@/components/main/detail/list-news";
|
import ListNews from "@/components/main/detail/list-news";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function ListNewsPage() {
|
export default function ListNewsPage() {
|
||||||
const [hasMounted, setHasMounted] = useState(false);
|
const [hasMounted, setHasMounted] = useState(false);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
import DetailPage from "@/components/main/detail/new-detail";
|
import DetailPage from "@/components/main/detail/new-detail";
|
||||||
import { getArticleById } from "@/services/article";
|
import { getArticleById } from "@/services/article";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import ListNews from "@/components/main/detail/list-news";
|
import ListNews from "@/components/main/detail/list-news";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function PoldaNewsPage() {
|
export default function PoldaNewsPage() {
|
||||||
// return <ListNews />;
|
// return <ListNews />;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import ListNews from "@/components/main/detail/list-news";
|
import ListNews from "@/components/main/detail/list-news";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function PoldaNewsPage() {
|
export default function PoldaNewsPage() {
|
||||||
// return <ListNews />;
|
// return <ListNews />;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function PropimLayout({
|
export default function PropimLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
import { getCustomStaticDetailBySlug } from "@/services/static-page-service";
|
import { getCustomStaticDetailBySlug } from "@/services/static-page-service";
|
||||||
import { Card, CircularProgress } from "@heroui/react";
|
import { Card, CircularProgress } from "@heroui/react";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function StrukturLayout({
|
export default function StrukturLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function AboutLayout({
|
export default function AboutLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function TaskLayout({
|
export default function TaskLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { HumasLayout } from "@/components/layout/humas-layout";
|
import HumasLayout from "@/components/layout/humas-layout";
|
||||||
|
|
||||||
export default function VisiMisiLayout({
|
export default function VisiMisiLayout({
|
||||||
children,
|
children,
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ import {
|
||||||
import GenerateSingleArticleForm from "./generate-ai-single-form";
|
import GenerateSingleArticleForm from "./generate-ai-single-form";
|
||||||
import {
|
import {
|
||||||
convertDateFormatNoTime,
|
convertDateFormatNoTime,
|
||||||
getUnixTimestamp,
|
getCookiesDecrypt,
|
||||||
htmlToString,
|
htmlToString,
|
||||||
} from "@/utils/global";
|
} from "@/utils/global";
|
||||||
import { close, error, loading, successToast } from "@/config/swal";
|
import { close, error, loading, successToast } from "@/config/swal";
|
||||||
|
|
@ -135,7 +135,7 @@ const renderPreview = (file: File) => {
|
||||||
|
|
||||||
export default function CreateArticleForm() {
|
export default function CreateArticleForm() {
|
||||||
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||||
const userLevel = Cookies.get("ulne");
|
const userLevel = getCookiesDecrypt("ulne");
|
||||||
const animatedComponents = makeAnimated();
|
const animatedComponents = makeAnimated();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ import {
|
||||||
convertDateFormatNoTime,
|
convertDateFormatNoTime,
|
||||||
getUnixTimestamp,
|
getUnixTimestamp,
|
||||||
formatMonthString,
|
formatMonthString,
|
||||||
|
getCookiesDecrypt,
|
||||||
htmlToString,
|
htmlToString,
|
||||||
} from "@/utils/global";
|
} from "@/utils/global";
|
||||||
import { close, error, loading } from "@/config/swal";
|
import { close, error, loading } from "@/config/swal";
|
||||||
|
|
@ -133,8 +134,8 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
|
||||||
const { isDetail } = props;
|
const { isDetail } = props;
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const id = params?.id;
|
const id = params?.id;
|
||||||
const username = Cookies.get("username");
|
const username = getCookiesDecrypt("username");
|
||||||
const userId = Cookies.get("uie");
|
const userId = getCookiesDecrypt("uie");
|
||||||
const animatedComponents = makeAnimated();
|
const animatedComponents = makeAnimated();
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import withReactContent from "sweetalert2-react-content";
|
||||||
import { saveActivity } from "@/services/activity-log";
|
import { saveActivity } from "@/services/activity-log";
|
||||||
import PasswordChecklist from "react-password-checklist";
|
import PasswordChecklist from "react-password-checklist";
|
||||||
import { Image, InputOtp } from "@heroui/react";
|
import { Image, InputOtp } from "@heroui/react";
|
||||||
import { getUnixTimestamp } from "@/utils/global";
|
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
const accessToken = Cookies.get("access_token");
|
const accessToken = Cookies.get("access_token");
|
||||||
|
|
@ -243,21 +242,28 @@ export default function Login() {
|
||||||
Cookies.set("profile_picture", profile?.profilePictureUrl, {
|
Cookies.set("profile_picture", profile?.profilePictureUrl, {
|
||||||
expires: 1,
|
expires: 1,
|
||||||
});
|
});
|
||||||
Cookies.set("uie", profile?.id, {
|
|
||||||
expires: 1,
|
setCookiesEncrypt("uie", profile?.id, { expires: 1 });
|
||||||
});
|
setCookiesEncrypt("ufne", profile?.fullname, { expires: 1 });
|
||||||
Cookies.set("ufne", profile?.fullname, {
|
setCookiesEncrypt("ulie", profile?.userLevelGroup, { expires: 1 });
|
||||||
expires: 1,
|
setCookiesEncrypt("username", profile?.username, { expires: 1 });
|
||||||
});
|
setCookiesEncrypt("urie", profile?.userRoleId, { expires: 1 });
|
||||||
Cookies.set("ulie", profile?.userLevelGroup, {
|
setCookiesEncrypt("ulne", profile?.userLevelId, { expires: 1 });
|
||||||
expires: 1,
|
setCookiesEncrypt("urce", profile?.roleCode, { expires: 1 });
|
||||||
});
|
setCookiesEncrypt("email", profile?.email, { expires: 1 });
|
||||||
Cookies.set("username", profile?.username, {
|
|
||||||
expires: 1,
|
// Cookies.set("ufne", profile?.fullname, {
|
||||||
});
|
// expires: 1,
|
||||||
Cookies.set("urie", profile?.userRoleId, {
|
// });
|
||||||
expires: 1,
|
// Cookies.set("ulie", profile?.userLevelGroup, {
|
||||||
});
|
// expires: 1,
|
||||||
|
// });
|
||||||
|
// Cookies.set("username", profile?.username, {
|
||||||
|
// expires: 1,
|
||||||
|
// });
|
||||||
|
// Cookies.set("urie", profile?.userRoleId, {
|
||||||
|
// expires: 1,
|
||||||
|
// });
|
||||||
// Cookies.set("roleName", profile?.roleName, {
|
// Cookies.set("roleName", profile?.roleName, {
|
||||||
// expires: 1,
|
// expires: 1,
|
||||||
// });
|
// });
|
||||||
|
|
@ -267,13 +273,13 @@ export default function Login() {
|
||||||
Cookies.set("ulne", profile?.userLevelId, {
|
Cookies.set("ulne", profile?.userLevelId, {
|
||||||
expires: 1,
|
expires: 1,
|
||||||
});
|
});
|
||||||
// Cookies.set("urce", profile?.data?.data?.roleCode, {
|
Cookies.set("urce", profile?.roleCode, {
|
||||||
// expires: 1,
|
expires: 1,
|
||||||
// });
|
});
|
||||||
Cookies.set("email", profile?.email, {
|
Cookies.set("email", profile?.email, {
|
||||||
expires: 1,
|
expires: 1,
|
||||||
});
|
});
|
||||||
router.push(`/admin/dashboard?timestamp=${getUnixTimestamp()}`);
|
router.push("/admin/dashboard");
|
||||||
Cookies.set("status", "login", {
|
Cookies.set("status", "login", {
|
||||||
expires: 1,
|
expires: 1,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,11 @@ import Cookies from "js-cookie";
|
||||||
|
|
||||||
export default function FooterNew(props: { margin?: boolean }) {
|
export default function FooterNew(props: { margin?: boolean }) {
|
||||||
const [emailValue, setEmailValue] = useState("");
|
const [emailValue, setEmailValue] = useState("");
|
||||||
const accessToken = Cookies.get("access_token");
|
const [accessToken, setAccessToken] = useState<any>();
|
||||||
|
useEffect(() => {
|
||||||
|
const accessToken = Cookies.get("access_token");
|
||||||
|
setAccessToken(accessToken);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const doSubscribe = async () => {
|
const doSubscribe = async () => {
|
||||||
const isValidEmail = (email: string): boolean => {
|
const isValidEmail = (email: string): boolean => {
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ import FooterNew from "../landing/footer-new";
|
||||||
interface Props {
|
interface Props {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
const HumasLayout = ({ children }: Props) => {
|
||||||
export const HumasLayout = ({ children }: Props) => {
|
|
||||||
const [hasMounted, setHasMounted] = useState(false);
|
const [hasMounted, setHasMounted] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -32,3 +31,5 @@ export const HumasLayout = ({ children }: Props) => {
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default HumasLayout;
|
||||||
|
|
|
||||||
|
|
@ -61,19 +61,16 @@ export default function NavbarHumas(props: { size: string }) {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
// const t = useTranslations("Navbar");
|
// const t = useTranslations("Navbar");
|
||||||
const token = Cookies.get("access_token");
|
|
||||||
const isAuthenticated = Cookies.get("is_authenticated");
|
|
||||||
const [isScrolled, setIsScrolled] = useState(false);
|
const [isScrolled, setIsScrolled] = useState(false);
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
const [token, setToken] = useState<any>();
|
||||||
const language = storedLanguage((state) => state.locale);
|
const language = storedLanguage((state) => state.locale);
|
||||||
const setLanguage = storedLanguage((state) => state.setLocale);
|
const setLanguage = storedLanguage((state) => state.setLocale);
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// if (!isAuthenticated) {
|
const token = Cookies.get("access_token");
|
||||||
// onLogout();
|
setToken(token);
|
||||||
// }
|
}, []);
|
||||||
// }, [token]);
|
|
||||||
|
|
||||||
const onLogout = () => {
|
const onLogout = () => {
|
||||||
Object.keys(Cookies.get()).forEach((cookieName) => {
|
Object.keys(Cookies.get()).forEach((cookieName) => {
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import { SidebarMenu } from "./sidebar-menu";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import { SettingsIcon, UserProfileIcon } from "@/components/icons/globals";
|
import { SettingsIcon, UserProfileIcon } from "@/components/icons/globals";
|
||||||
import { getUnixTimestamp } from "@/utils/global";
|
import { getCookiesDecrypt } from "@/utils/global";
|
||||||
|
|
||||||
interface SubMenuItems {
|
interface SubMenuItems {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -577,10 +577,10 @@ const SidebarMobile: React.FC<SidebarProps> = ({ updateSidebarData }) => {
|
||||||
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
|
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
|
||||||
const { isOpen, toggleSidebar } = useSidebar();
|
const { isOpen, toggleSidebar } = useSidebar();
|
||||||
const token = Cookies.get("access_token");
|
const token = Cookies.get("access_token");
|
||||||
const username = Cookies.get("username");
|
const username = getCookiesDecrypt("username");
|
||||||
const isAuthenticated = Cookies.get("is_authenticated");
|
const isAuthenticated = Cookies.get("is_authenticated");
|
||||||
const roles = Cookies.get("ulie");
|
const roles = getCookiesDecrypt("ulie");
|
||||||
const rolesId = Cookies.get("urie");
|
const rolesId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import { SidebarMenu } from "./sidebar-menu";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import { SettingsIcon, UserProfileIcon } from "@/components/icons/globals";
|
import { SettingsIcon, UserProfileIcon } from "@/components/icons/globals";
|
||||||
import { getUnixTimestamp, textEllipsis } from "@/utils/global";
|
import { getCookiesDecrypt, textEllipsis } from "@/utils/global";
|
||||||
|
|
||||||
interface SubMenuItems {
|
interface SubMenuItems {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -577,10 +577,10 @@ const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
|
||||||
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
|
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
|
||||||
const { isOpen, toggleSidebar } = useSidebar();
|
const { isOpen, toggleSidebar } = useSidebar();
|
||||||
const token = Cookies.get("access_token");
|
const token = Cookies.get("access_token");
|
||||||
const username = Cookies.get("username");
|
const username = getCookiesDecrypt("username");
|
||||||
const isAuthenticated = Cookies.get("is_authenticated");
|
const isAuthenticated = Cookies.get("is_authenticated");
|
||||||
const roles = Cookies.get("ulie");
|
const roles = getCookiesDecrypt("ulie");
|
||||||
const rolesId = Cookies.get("urie");
|
const rolesId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export default function PieChartLoginBrowser() {
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [selectedLabel, setSelectedLabel] = useState<string>("");
|
const [selectedLabel, setSelectedLabel] = useState<string>("");
|
||||||
|
|
||||||
const [visitorBrowserDate, setVisitorBrowserDate] = useState({
|
const [visitorBrowserDate, setVisitorBrowserDate] = useState<any>({
|
||||||
startDate: parseDate(
|
startDate: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ import {
|
||||||
convertDateFormat,
|
convertDateFormat,
|
||||||
convertDateFormatNoTime,
|
convertDateFormatNoTime,
|
||||||
convertDateFormatNoTimeV2,
|
convertDateFormatNoTimeV2,
|
||||||
getUnixTimestamp,
|
getCookiesDecrypt,
|
||||||
textEllipsis,
|
textEllipsis,
|
||||||
} from "@/utils/global";
|
} from "@/utils/global";
|
||||||
import {
|
import {
|
||||||
|
|
@ -122,8 +122,8 @@ const months = [
|
||||||
export default function DashboardContainer() {
|
export default function DashboardContainer() {
|
||||||
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||||
|
|
||||||
const username = Cookies.get("username");
|
const username = getCookiesDecrypt("username");
|
||||||
const fullname = Cookies.get("ufne");
|
const fullname = getCookiesDecrypt("ufne");
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [totalPage, setTotalPage] = useState(1);
|
const [totalPage, setTotalPage] = useState(1);
|
||||||
const [topPagespage, setTopPagesPage] = useState(1);
|
const [topPagespage, setTopPagesPage] = useState(1);
|
||||||
|
|
@ -139,7 +139,7 @@ export default function DashboardContainer() {
|
||||||
parseDate(convertDateFormatNoTimeV2(new Date()))
|
parseDate(convertDateFormatNoTimeV2(new Date()))
|
||||||
);
|
);
|
||||||
|
|
||||||
const [postContentDate, setPostContentDate] = useState({
|
const [postContentDate, setPostContentDate] = useState<any>({
|
||||||
start: parseZonedDateTime(
|
start: parseZonedDateTime(
|
||||||
`${convertDateFormatNoTimeV2(
|
`${convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
@ -150,7 +150,7 @@ export default function DashboardContainer() {
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
const [topContentDate, setTopContentDate] = useState({
|
const [topContentDate, setTopContentDate] = useState<any>({
|
||||||
startDate: parseDate(
|
startDate: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
@ -170,7 +170,7 @@ export default function DashboardContainer() {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
}>();
|
}>();
|
||||||
const roleId = Cookies.get("urie");
|
const roleId = getCookiesDecrypt("urie");
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const [chartVisitorTotal, setChartVisitorTotal] = useState(0);
|
const [chartVisitorTotal, setChartVisitorTotal] = useState(0);
|
||||||
const [recapArticlePage, setRecapArticlePage] = useState(1);
|
const [recapArticlePage, setRecapArticlePage] = useState(1);
|
||||||
|
|
@ -179,7 +179,7 @@ export default function DashboardContainer() {
|
||||||
const [typeDate, setTypeDate] = useState("daily");
|
const [typeDate, setTypeDate] = useState("daily");
|
||||||
const [year, setYear] = useState(today.getFullYear());
|
const [year, setYear] = useState(today.getFullYear());
|
||||||
const [selectedMonth, setSelectedMonth] = useState<Date | null>(today);
|
const [selectedMonth, setSelectedMonth] = useState<Date | null>(today);
|
||||||
const [viewsDailyDate, setViewsDailyDate] = useState({
|
const [viewsDailyDate, setViewsDailyDate] = useState<any>({
|
||||||
start: parseDate(
|
start: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
@ -193,7 +193,7 @@ export default function DashboardContainer() {
|
||||||
const [visitorSelectedMonth, setVisitorSelectedMonth] = useState<Date | null>(
|
const [visitorSelectedMonth, setVisitorSelectedMonth] = useState<Date | null>(
|
||||||
today
|
today
|
||||||
);
|
);
|
||||||
const [visitorDailyDate, setVisitorDailyDate] = useState({
|
const [visitorDailyDate, setVisitorDailyDate] = useState<any>({
|
||||||
start: parseDate(
|
start: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
@ -204,10 +204,8 @@ export default function DashboardContainer() {
|
||||||
|
|
||||||
const [typeDateUsers, setTypeDateUsers] = useState("daily");
|
const [typeDateUsers, setTypeDateUsers] = useState("daily");
|
||||||
const [usersYear, setUsersYear] = useState(today.getFullYear());
|
const [usersYear, setUsersYear] = useState(today.getFullYear());
|
||||||
const [usersSelectedMonth, setUsersSelectedMonth] = useState<Date | null>(
|
const [usersSelectedMonth, setUsersSelectedMonth] = useState<any>(today);
|
||||||
today
|
const [usersDailyDate, setUsersDailyDate] = useState<any>({
|
||||||
);
|
|
||||||
const [usersDailyDate, setUsersDailyDate] = useState({
|
|
||||||
start: parseDate(
|
start: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import {
|
||||||
} from "@/services/master-user";
|
} from "@/services/master-user";
|
||||||
import { error } from "@/config/swal";
|
import { error } from "@/config/swal";
|
||||||
import { UserProfileIcon } from "@/components/icons/globals";
|
import { UserProfileIcon } from "@/components/icons/globals";
|
||||||
import { convertDateFormat } from "@/utils/global";
|
import { convertDateFormat, getCookiesDecrypt } from "@/utils/global";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import OTPInput from "react-otp-input";
|
import OTPInput from "react-otp-input";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
|
|
@ -23,9 +23,6 @@ import { SendIcon, TimesIcon } from "@/components/icons";
|
||||||
import { saveActivity } from "@/services/activity-log";
|
import { saveActivity } from "@/services/activity-log";
|
||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
|
|
||||||
const userId = Cookies.get("uie");
|
|
||||||
const token = Cookies.get("access_token");
|
|
||||||
|
|
||||||
const commentSchema = z.object({
|
const commentSchema = z.object({
|
||||||
name: z.string().min(1, {
|
name: z.string().min(1, {
|
||||||
message: "Judul harus diisi",
|
message: "Judul harus diisi",
|
||||||
|
|
@ -54,6 +51,16 @@ export default function Comment(props: { id: string | null }) {
|
||||||
const [editCommentId, setEditCommentId] = useState(0);
|
const [editCommentId, setEditCommentId] = useState(0);
|
||||||
const [replyValue, setReplyValue] = useState("");
|
const [replyValue, setReplyValue] = useState("");
|
||||||
const [editValue, setEditValue] = useState("");
|
const [editValue, setEditValue] = useState("");
|
||||||
|
|
||||||
|
const [userId, setUserId] = useState<any>();
|
||||||
|
const [token, setToken] = useState<any>();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const userId = getCookiesDecrypt("uie");
|
||||||
|
const token = Cookies.get("access_token");
|
||||||
|
setUserId(userId);
|
||||||
|
setToken(token);
|
||||||
|
}, []);
|
||||||
const formOptions = {
|
const formOptions = {
|
||||||
resolver: zodResolver(commentSchema),
|
resolver: zodResolver(commentSchema),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,7 @@ import { close, loading } from "@/config/swal";
|
||||||
import { saveActivity } from "@/services/activity-log";
|
import { saveActivity } from "@/services/activity-log";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
import { getCookiesDecrypt } from "@/utils/global";
|
||||||
const token = Cookies.get("access_token");
|
|
||||||
const uid = Cookies.get("uie");
|
|
||||||
|
|
||||||
export default function NewsDetailPage(props: { datas: any }) {
|
export default function NewsDetailPage(props: { datas: any }) {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
|
@ -22,7 +20,12 @@ export default function NewsDetailPage(props: { datas: any }) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const [detailArticle, setDetailArticle] = useState<any>();
|
const [detailArticle, setDetailArticle] = useState<any>();
|
||||||
const [articles, setArticles] = useState<any>([]);
|
const [articles, setArticles] = useState<any>([]);
|
||||||
|
const [uid, setUid] = useState<any>("");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const uid = getCookiesDecrypt("uie");
|
||||||
|
setUid(uid);
|
||||||
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getArticles();
|
getArticles();
|
||||||
sendActivity();
|
sendActivity();
|
||||||
|
|
@ -42,6 +45,7 @@ export default function NewsDetailPage(props: { datas: any }) {
|
||||||
if (uid) {
|
if (uid) {
|
||||||
req.userId = Number(uid);
|
req.userId = Number(uid);
|
||||||
}
|
}
|
||||||
|
const token = Cookies.get("access_token");
|
||||||
|
|
||||||
const resActivity = await saveActivity(req, token);
|
const resActivity = await saveActivity(req, token);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import {
|
||||||
convertDateFormat,
|
convertDateFormat,
|
||||||
formatMonthString,
|
formatMonthString,
|
||||||
formatTextToHtmlTag,
|
formatTextToHtmlTag,
|
||||||
|
getCookiesDecrypt,
|
||||||
} from "@/utils/global";
|
} from "@/utils/global";
|
||||||
import {
|
import {
|
||||||
CalendarIcon,
|
CalendarIcon,
|
||||||
|
|
@ -27,9 +28,6 @@ import Cookies from "js-cookie";
|
||||||
import { saveActivity } from "@/services/activity-log";
|
import { saveActivity } from "@/services/activity-log";
|
||||||
import { Accordion, AccordionItem, Image } from "@heroui/react";
|
import { Accordion, AccordionItem, Image } from "@heroui/react";
|
||||||
|
|
||||||
const token = Cookies.get("access_token");
|
|
||||||
const uid = Cookies.get("uie");
|
|
||||||
|
|
||||||
export default function DetailNews(props: { data: any; listArticle: any }) {
|
export default function DetailNews(props: { data: any; listArticle: any }) {
|
||||||
const { data, listArticle } = props;
|
const { data, listArticle } = props;
|
||||||
const [prevArticle, setPrevArticle] = useState("");
|
const [prevArticle, setPrevArticle] = useState("");
|
||||||
|
|
@ -39,32 +37,15 @@ export default function DetailNews(props: { data: any; listArticle: any }) {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const id: any = params?.id;
|
const id: any = params?.id;
|
||||||
const shareText = "Humas Polri";
|
const shareText = "Humas Polri";
|
||||||
const [filteredFiles, setFilteredFiles] = useState<any>([]);
|
const [uid, setUid] = useState<any>("");
|
||||||
|
const [token, setToken] = useState<any>("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUniqueBaseFiles(data?.files);
|
const token = Cookies.get("access_token");
|
||||||
}, [data]);
|
const uid = getCookiesDecrypt("uie");
|
||||||
|
setToken(token);
|
||||||
function extractBaseName(fileName: string): string {
|
setUid(uid);
|
||||||
const match = fileName.match(/^(.+?)_\w+\.(jpg|jpeg|png|webp)$/i);
|
}, []);
|
||||||
return match ? match[1] : fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getUniqueBaseFiles = (files: any) => {
|
|
||||||
if (files && files.length > 0) {
|
|
||||||
const seen = new Set<string>();
|
|
||||||
const result: any = [];
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
const baseName = extractBaseName(file.file_name);
|
|
||||||
if (!seen.has(baseName)) {
|
|
||||||
seen.add(baseName);
|
|
||||||
result.push(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setFilteredFiles(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleShare = async (platform: string) => {
|
const handleShare = async (platform: string) => {
|
||||||
let shareLink = "";
|
let shareLink = "";
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ export default function RelatedNews(props: { categories: any }) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getArticle() {
|
async function getArticle() {
|
||||||
console.log("categories", categories);
|
|
||||||
const idString = categories.map((item: any) => item.id).join(",");
|
const idString = categories.map((item: any) => item.id).join(",");
|
||||||
|
|
||||||
const req = {
|
const req = {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import {
|
||||||
convertDateFormat,
|
convertDateFormat,
|
||||||
convertDateFormatNoTime,
|
convertDateFormatNoTime,
|
||||||
convertDateFormatNoTimeV2,
|
convertDateFormatNoTimeV2,
|
||||||
getUnixTimestamp,
|
getCookiesDecrypt,
|
||||||
} from "@/utils/global";
|
} from "@/utils/global";
|
||||||
import { Button } from "@heroui/button";
|
import { Button } from "@heroui/button";
|
||||||
import {
|
import {
|
||||||
|
|
@ -94,10 +94,10 @@ type ArticleData = Article & {
|
||||||
|
|
||||||
export default function ArticleTable() {
|
export default function ArticleTable() {
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const username = Cookies.get("username");
|
const username = getCookiesDecrypt("username");
|
||||||
const userId = Cookies.get("uie");
|
const userId = getCookiesDecrypt("uie");
|
||||||
const animatedComponents = makeAnimated();
|
const animatedComponents = makeAnimated();
|
||||||
const roleId = Cookies.get("urie");
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [totalPage, setTotalPage] = useState(1);
|
const [totalPage, setTotalPage] = useState(1);
|
||||||
|
|
@ -115,10 +115,7 @@ export default function ArticleTable() {
|
||||||
|
|
||||||
const [selectedArticles, setSelectedArticles] = useState<any>(new Set([]));
|
const [selectedArticles, setSelectedArticles] = useState<any>(new Set([]));
|
||||||
|
|
||||||
const [articleDate, setArticleDate] = useState<{
|
const [articleDate, setArticleDate] = useState<any>({
|
||||||
startDate: any;
|
|
||||||
endDate: any;
|
|
||||||
}>({
|
|
||||||
startDate: parseDate(
|
startDate: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ export default function DashboardVisitorsTable() {
|
||||||
const [totalPage, setTotalPage] = useState(1);
|
const [totalPage, setTotalPage] = useState(1);
|
||||||
const [showData, setShowData] = useState("10");
|
const [showData, setShowData] = useState("10");
|
||||||
const [tableVisitorData, setTableVisitorData] = useState<any>([]);
|
const [tableVisitorData, setTableVisitorData] = useState<any>([]);
|
||||||
const [visitorBrowserDate, setVisitorBrowserDate] = useState({
|
const [visitorBrowserDate, setVisitorBrowserDate] = useState<any>({
|
||||||
startDate: parseDate(
|
startDate: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ export default function SuggestionsTable() {
|
||||||
const [isReply, setIsReply] = useState(false);
|
const [isReply, setIsReply] = useState(false);
|
||||||
const [replyValue, setReplyValue] = useState("");
|
const [replyValue, setReplyValue] = useState("");
|
||||||
const [totalData, setTotalData] = useState(0);
|
const [totalData, setTotalData] = useState(0);
|
||||||
const [feedbackDate, setFeedbackDate] = useState({
|
const [feedbackDate, setFeedbackDate] = useState<any>({
|
||||||
startDate: parseDate(
|
startDate: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
@ -353,7 +353,7 @@ export default function SuggestionsTable() {
|
||||||
initState();
|
initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
const [startDateValue, setStartDateValue] = useState(
|
const [startDateValue, setStartDateValue] = useState<any>(
|
||||||
parseDate(convertDateFormatNoTimeV2(new Date()))
|
parseDate(convertDateFormatNoTimeV2(new Date()))
|
||||||
);
|
);
|
||||||
const [typeDate, setTypeDate] = useState("monthly");
|
const [typeDate, setTypeDate] = useState("monthly");
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ const IndonesiaMap = () => {
|
||||||
const [typeDate, setTypeDate] = useState("daily");
|
const [typeDate, setTypeDate] = useState("daily");
|
||||||
const [year, setYear] = useState(today.getFullYear());
|
const [year, setYear] = useState(today.getFullYear());
|
||||||
const [selectedMonth, setSelectedMonth] = useState<Date | null>(today);
|
const [selectedMonth, setSelectedMonth] = useState<Date | null>(today);
|
||||||
const [viewsDailyDate, setViewsDailyDate] = useState({
|
const [viewsDailyDate, setViewsDailyDate] = useState<any>({
|
||||||
start: parseDate(
|
start: parseDate(
|
||||||
convertDateFormatNoTimeV2(
|
convertDateFormatNoTimeV2(
|
||||||
new Date(new Date().setDate(new Date().getDate() - 7))
|
new Date(new Date().setDate(new Date().getDate() - 7))
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -26,9 +26,10 @@
|
||||||
"@hookform/resolvers": "^3.3.4",
|
"@hookform/resolvers": "^3.3.4",
|
||||||
"@react-aria/ssr": "^3.8.0",
|
"@react-aria/ssr": "^3.8.0",
|
||||||
"@react-aria/visually-hidden": "^3.8.6",
|
"@react-aria/visually-hidden": "^3.8.6",
|
||||||
"@tawk.to/tawk-messenger-react": "^2.0.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
"@types/echarts": "^5.0.0",
|
"@types/echarts": "^5.0.0",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
|
"@types/minimatch": "^6.0.0",
|
||||||
"@types/node": "^20.5.7",
|
"@types/node": "^20.5.7",
|
||||||
"@types/react": "19.1.2",
|
"@types/react": "19.1.2",
|
||||||
"@types/react-datepicker": "^6.0.1",
|
"@types/react-datepicker": "^6.0.1",
|
||||||
|
|
@ -39,6 +40,7 @@
|
||||||
"axios": "^1.6.8",
|
"axios": "^1.6.8",
|
||||||
"ckeditor5-custom-build": "file:vendor/ckeditor5",
|
"ckeditor5-custom-build": "file:vendor/ckeditor5",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"docx": "^9.3.0",
|
"docx": "^9.3.0",
|
||||||
"dompurify": "^3.2.0",
|
"dompurify": "^3.2.0",
|
||||||
|
|
@ -51,6 +53,7 @@
|
||||||
"intl-messageformat": "^10.5.0",
|
"intl-messageformat": "^10.5.0",
|
||||||
"jodit-react": "^4.0.25",
|
"jodit-react": "^4.0.25",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
|
"minimatch": "^10.0.3",
|
||||||
"next": "15.3.0",
|
"next": "15.3.0",
|
||||||
"next-intl": "^3.26.0",
|
"next-intl": "^3.26.0",
|
||||||
"next-themes": "^0.2.1",
|
"next-themes": "^0.2.1",
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ import {
|
||||||
} from "./http-config/axios-base-service";
|
} from "./http-config/axios-base-service";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import axiosBaseInstance from "./http-config/http-base-instance";
|
import axiosBaseInstance from "./http-config/http-base-instance";
|
||||||
|
import { getCookiesDecrypt } from "@/utils/global";
|
||||||
|
|
||||||
const token = Cookies.get("access_token");
|
const token = Cookies.get("access_token");
|
||||||
const id = Cookies.get("uie");
|
const id = getCookiesDecrypt("uie");
|
||||||
|
|
||||||
export async function listMasterUsers(data: any) {
|
export async function listMasterUsers(data: any) {
|
||||||
const headers = {
|
const headers = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"use client";
|
import Cookies from "js-cookie";
|
||||||
import { useEffect } from "react";
|
import CryptoJS from "crypto-js";
|
||||||
|
|
||||||
export function convertDateFormat(dateString: string) {
|
export function convertDateFormat(dateString: string) {
|
||||||
var date = new Date(dateString);
|
var date = new Date(dateString);
|
||||||
|
|
@ -70,26 +70,6 @@ export function formatTextToHtmlTag(text: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoadScript = () => {
|
|
||||||
useEffect(() => {
|
|
||||||
const script = document.createElement("script");
|
|
||||||
script.src = "https://cdn.userway.org/widget.js";
|
|
||||||
script.setAttribute("data-account", "X36s1DpjqB");
|
|
||||||
script.async = true;
|
|
||||||
|
|
||||||
document.head.appendChild(script);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
// Cleanup if needed
|
|
||||||
document.head.removeChild(script);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return null; // Tidak perlu merender apa-apa
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LoadScript;
|
|
||||||
|
|
||||||
export function delay(ms: number) {
|
export function delay(ms: number) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +138,35 @@ export function formatMonthString(dateString: string) {
|
||||||
return `${day} ${month} ${year}`;
|
return `${day} ${month} ${year}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUnixTimestamp() {
|
export function setCookiesEncrypt(
|
||||||
const unixTimestampInSeconds: number = Math.floor(Date.now() / 1000);
|
param: string,
|
||||||
return unixTimestampInSeconds;
|
data: any,
|
||||||
|
options?: Cookies.CookieAttributes
|
||||||
|
) {
|
||||||
|
// Enkripsi data
|
||||||
|
const cookiesEncrypt = CryptoJS.AES.encrypt(
|
||||||
|
JSON.stringify(data),
|
||||||
|
`${param}_EncryptKey@humas`
|
||||||
|
).toString(); // Tambahkan .toString() di sini
|
||||||
|
|
||||||
|
// Simpan data terenkripsi di cookie
|
||||||
|
Cookies.set(param, cookiesEncrypt, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCookiesDecrypt(param: any) {
|
||||||
|
const cookiesEncrypt = Cookies.get(param);
|
||||||
|
try {
|
||||||
|
if (cookiesEncrypt != undefined) {
|
||||||
|
const output = CryptoJS.AES.decrypt(
|
||||||
|
cookiesEncrypt.toString(),
|
||||||
|
`${param}_EncryptKey@humas`
|
||||||
|
).toString(CryptoJS.enc.Utf8);
|
||||||
|
if (output.startsWith('"')) {
|
||||||
|
return output.slice(1, -1);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
//console.log("Error", cookiesEncrypt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
"use client";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
const LoadScript = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.src = "https://cdn.userway.org/widget.js";
|
||||||
|
script.setAttribute("data-account", "X36s1DpjqB");
|
||||||
|
script.async = true;
|
||||||
|
|
||||||
|
document.head.appendChild(script);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// Cleanup if needed
|
||||||
|
document.head.removeChild(script);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return null; // Tidak perlu merender apa-apa
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoadScript;
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
# 1.0.0 - 2016-01-07
|
||||||
|
|
||||||
|
- Removed: unused speed test
|
||||||
|
- Added: Automatic routing between previously unsupported conversions
|
||||||
|
([#27](https://github.com/Qix-/color-convert/pull/27))
|
||||||
|
- Removed: `xxx2xxx()` and `xxx2xxxRaw()` functions
|
||||||
|
([#27](https://github.com/Qix-/color-convert/pull/27))
|
||||||
|
- Removed: `convert()` class
|
||||||
|
([#27](https://github.com/Qix-/color-convert/pull/27))
|
||||||
|
- Changed: all functions to lookup dictionary
|
||||||
|
([#27](https://github.com/Qix-/color-convert/pull/27))
|
||||||
|
- Changed: `ansi` to `ansi256`
|
||||||
|
([#27](https://github.com/Qix-/color-convert/pull/27))
|
||||||
|
- Fixed: argument grouping for functions requiring only one argument
|
||||||
|
([#27](https://github.com/Qix-/color-convert/pull/27))
|
||||||
|
|
||||||
|
# 0.6.0 - 2015-07-23
|
||||||
|
|
||||||
|
- Added: methods to handle
|
||||||
|
[ANSI](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) 16/256 colors:
|
||||||
|
- rgb2ansi16
|
||||||
|
- rgb2ansi
|
||||||
|
- hsl2ansi16
|
||||||
|
- hsl2ansi
|
||||||
|
- hsv2ansi16
|
||||||
|
- hsv2ansi
|
||||||
|
- hwb2ansi16
|
||||||
|
- hwb2ansi
|
||||||
|
- cmyk2ansi16
|
||||||
|
- cmyk2ansi
|
||||||
|
- keyword2ansi16
|
||||||
|
- keyword2ansi
|
||||||
|
- ansi162rgb
|
||||||
|
- ansi162hsl
|
||||||
|
- ansi162hsv
|
||||||
|
- ansi162hwb
|
||||||
|
- ansi162cmyk
|
||||||
|
- ansi162keyword
|
||||||
|
- ansi2rgb
|
||||||
|
- ansi2hsl
|
||||||
|
- ansi2hsv
|
||||||
|
- ansi2hwb
|
||||||
|
- ansi2cmyk
|
||||||
|
- ansi2keyword
|
||||||
|
([#18](https://github.com/harthur/color-convert/pull/18))
|
||||||
|
|
||||||
|
# 0.5.3 - 2015-06-02
|
||||||
|
|
||||||
|
- Fixed: hsl2hsv does not return `NaN` anymore when using `[0,0,0]`
|
||||||
|
([#15](https://github.com/harthur/color-convert/issues/15))
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Check out commit logs for older releases
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
Copyright (c) 2011-2016 Heather Arthur <fayearthur@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
# color-convert
|
||||||
|
|
||||||
|
[](https://travis-ci.org/Qix-/color-convert)
|
||||||
|
|
||||||
|
Color-convert is a color conversion library for JavaScript and node.
|
||||||
|
It converts all ways between `rgb`, `hsl`, `hsv`, `hwb`, `cmyk`, `ansi`, `ansi16`, `hex` strings, and CSS `keyword`s (will round to closest):
|
||||||
|
|
||||||
|
```js
|
||||||
|
var convert = require('color-convert');
|
||||||
|
|
||||||
|
convert.rgb.hsl(140, 200, 100); // [96, 48, 59]
|
||||||
|
convert.keyword.rgb('blue'); // [0, 0, 255]
|
||||||
|
|
||||||
|
var rgbChannels = convert.rgb.channels; // 3
|
||||||
|
var cmykChannels = convert.cmyk.channels; // 4
|
||||||
|
var ansiChannels = convert.ansi16.channels; // 1
|
||||||
|
```
|
||||||
|
|
||||||
|
# Install
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ npm install color-convert
|
||||||
|
```
|
||||||
|
|
||||||
|
# API
|
||||||
|
|
||||||
|
Simply get the property of the _from_ and _to_ conversion that you're looking for.
|
||||||
|
|
||||||
|
All functions have a rounded and unrounded variant. By default, return values are rounded. To get the unrounded (raw) results, simply tack on `.raw` to the function.
|
||||||
|
|
||||||
|
All 'from' functions have a hidden property called `.channels` that indicates the number of channels the function expects (not including alpha).
|
||||||
|
|
||||||
|
```js
|
||||||
|
var convert = require('color-convert');
|
||||||
|
|
||||||
|
// Hex to LAB
|
||||||
|
convert.hex.lab('DEADBF'); // [ 76, 21, -2 ]
|
||||||
|
convert.hex.lab.raw('DEADBF'); // [ 75.56213190997677, 20.653827952644754, -2.290532499330533 ]
|
||||||
|
|
||||||
|
// RGB to CMYK
|
||||||
|
convert.rgb.cmyk(167, 255, 4); // [ 35, 0, 98, 0 ]
|
||||||
|
convert.rgb.cmyk.raw(167, 255, 4); // [ 34.509803921568626, 0, 98.43137254901961, 0 ]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arrays
|
||||||
|
All functions that accept multiple arguments also support passing an array.
|
||||||
|
|
||||||
|
Note that this does **not** apply to functions that convert from a color that only requires one value (e.g. `keyword`, `ansi256`, `hex`, etc.)
|
||||||
|
|
||||||
|
```js
|
||||||
|
var convert = require('color-convert');
|
||||||
|
|
||||||
|
convert.rgb.hex(123, 45, 67); // '7B2D43'
|
||||||
|
convert.rgb.hex([123, 45, 67]); // '7B2D43'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Routing
|
||||||
|
|
||||||
|
Conversions that don't have an _explicitly_ defined conversion (in [conversions.js](conversions.js)), but can be converted by means of sub-conversions (e.g. XYZ -> **RGB** -> CMYK), are automatically routed together. This allows just about any color model supported by `color-convert` to be converted to any other model, so long as a sub-conversion path exists. This is also true for conversions requiring more than one step in between (e.g. LCH -> **LAB** -> **XYZ** -> **RGB** -> Hex).
|
||||||
|
|
||||||
|
Keep in mind that extensive conversions _may_ result in a loss of precision, and exist only to be complete. For a list of "direct" (single-step) conversions, see [conversions.js](conversions.js).
|
||||||
|
|
||||||
|
# Contribute
|
||||||
|
|
||||||
|
If there is a new model you would like to support, or want to add a direct conversion between two existing models, please send us a pull request.
|
||||||
|
|
||||||
|
# License
|
||||||
|
Copyright © 2011-2016, Heather Arthur and Josh Junon. Licensed under the [MIT License](LICENSE).
|
||||||
|
|
@ -0,0 +1,839 @@
|
||||||
|
/* MIT license */
|
||||||
|
/* eslint-disable no-mixed-operators */
|
||||||
|
const cssKeywords = require('color-name');
|
||||||
|
|
||||||
|
// NOTE: conversions should only return primitive values (i.e. arrays, or
|
||||||
|
// values that give correct `typeof` results).
|
||||||
|
// do not use box values types (i.e. Number(), String(), etc.)
|
||||||
|
|
||||||
|
const reverseKeywords = {};
|
||||||
|
for (const key of Object.keys(cssKeywords)) {
|
||||||
|
reverseKeywords[cssKeywords[key]] = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
const convert = {
|
||||||
|
rgb: {channels: 3, labels: 'rgb'},
|
||||||
|
hsl: {channels: 3, labels: 'hsl'},
|
||||||
|
hsv: {channels: 3, labels: 'hsv'},
|
||||||
|
hwb: {channels: 3, labels: 'hwb'},
|
||||||
|
cmyk: {channels: 4, labels: 'cmyk'},
|
||||||
|
xyz: {channels: 3, labels: 'xyz'},
|
||||||
|
lab: {channels: 3, labels: 'lab'},
|
||||||
|
lch: {channels: 3, labels: 'lch'},
|
||||||
|
hex: {channels: 1, labels: ['hex']},
|
||||||
|
keyword: {channels: 1, labels: ['keyword']},
|
||||||
|
ansi16: {channels: 1, labels: ['ansi16']},
|
||||||
|
ansi256: {channels: 1, labels: ['ansi256']},
|
||||||
|
hcg: {channels: 3, labels: ['h', 'c', 'g']},
|
||||||
|
apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
|
||||||
|
gray: {channels: 1, labels: ['gray']}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = convert;
|
||||||
|
|
||||||
|
// Hide .channels and .labels properties
|
||||||
|
for (const model of Object.keys(convert)) {
|
||||||
|
if (!('channels' in convert[model])) {
|
||||||
|
throw new Error('missing channels property: ' + model);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!('labels' in convert[model])) {
|
||||||
|
throw new Error('missing channel labels property: ' + model);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (convert[model].labels.length !== convert[model].channels) {
|
||||||
|
throw new Error('channel and label counts mismatch: ' + model);
|
||||||
|
}
|
||||||
|
|
||||||
|
const {channels, labels} = convert[model];
|
||||||
|
delete convert[model].channels;
|
||||||
|
delete convert[model].labels;
|
||||||
|
Object.defineProperty(convert[model], 'channels', {value: channels});
|
||||||
|
Object.defineProperty(convert[model], 'labels', {value: labels});
|
||||||
|
}
|
||||||
|
|
||||||
|
convert.rgb.hsl = function (rgb) {
|
||||||
|
const r = rgb[0] / 255;
|
||||||
|
const g = rgb[1] / 255;
|
||||||
|
const b = rgb[2] / 255;
|
||||||
|
const min = Math.min(r, g, b);
|
||||||
|
const max = Math.max(r, g, b);
|
||||||
|
const delta = max - min;
|
||||||
|
let h;
|
||||||
|
let s;
|
||||||
|
|
||||||
|
if (max === min) {
|
||||||
|
h = 0;
|
||||||
|
} else if (r === max) {
|
||||||
|
h = (g - b) / delta;
|
||||||
|
} else if (g === max) {
|
||||||
|
h = 2 + (b - r) / delta;
|
||||||
|
} else if (b === max) {
|
||||||
|
h = 4 + (r - g) / delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = Math.min(h * 60, 360);
|
||||||
|
|
||||||
|
if (h < 0) {
|
||||||
|
h += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
const l = (min + max) / 2;
|
||||||
|
|
||||||
|
if (max === min) {
|
||||||
|
s = 0;
|
||||||
|
} else if (l <= 0.5) {
|
||||||
|
s = delta / (max + min);
|
||||||
|
} else {
|
||||||
|
s = delta / (2 - max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [h, s * 100, l * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.hsv = function (rgb) {
|
||||||
|
let rdif;
|
||||||
|
let gdif;
|
||||||
|
let bdif;
|
||||||
|
let h;
|
||||||
|
let s;
|
||||||
|
|
||||||
|
const r = rgb[0] / 255;
|
||||||
|
const g = rgb[1] / 255;
|
||||||
|
const b = rgb[2] / 255;
|
||||||
|
const v = Math.max(r, g, b);
|
||||||
|
const diff = v - Math.min(r, g, b);
|
||||||
|
const diffc = function (c) {
|
||||||
|
return (v - c) / 6 / diff + 1 / 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (diff === 0) {
|
||||||
|
h = 0;
|
||||||
|
s = 0;
|
||||||
|
} else {
|
||||||
|
s = diff / v;
|
||||||
|
rdif = diffc(r);
|
||||||
|
gdif = diffc(g);
|
||||||
|
bdif = diffc(b);
|
||||||
|
|
||||||
|
if (r === v) {
|
||||||
|
h = bdif - gdif;
|
||||||
|
} else if (g === v) {
|
||||||
|
h = (1 / 3) + rdif - bdif;
|
||||||
|
} else if (b === v) {
|
||||||
|
h = (2 / 3) + gdif - rdif;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h < 0) {
|
||||||
|
h += 1;
|
||||||
|
} else if (h > 1) {
|
||||||
|
h -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
h * 360,
|
||||||
|
s * 100,
|
||||||
|
v * 100
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.hwb = function (rgb) {
|
||||||
|
const r = rgb[0];
|
||||||
|
const g = rgb[1];
|
||||||
|
let b = rgb[2];
|
||||||
|
const h = convert.rgb.hsl(rgb)[0];
|
||||||
|
const w = 1 / 255 * Math.min(r, Math.min(g, b));
|
||||||
|
|
||||||
|
b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
|
||||||
|
|
||||||
|
return [h, w * 100, b * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.cmyk = function (rgb) {
|
||||||
|
const r = rgb[0] / 255;
|
||||||
|
const g = rgb[1] / 255;
|
||||||
|
const b = rgb[2] / 255;
|
||||||
|
|
||||||
|
const k = Math.min(1 - r, 1 - g, 1 - b);
|
||||||
|
const c = (1 - r - k) / (1 - k) || 0;
|
||||||
|
const m = (1 - g - k) / (1 - k) || 0;
|
||||||
|
const y = (1 - b - k) / (1 - k) || 0;
|
||||||
|
|
||||||
|
return [c * 100, m * 100, y * 100, k * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
function comparativeDistance(x, y) {
|
||||||
|
/*
|
||||||
|
See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
|
||||||
|
*/
|
||||||
|
return (
|
||||||
|
((x[0] - y[0]) ** 2) +
|
||||||
|
((x[1] - y[1]) ** 2) +
|
||||||
|
((x[2] - y[2]) ** 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
convert.rgb.keyword = function (rgb) {
|
||||||
|
const reversed = reverseKeywords[rgb];
|
||||||
|
if (reversed) {
|
||||||
|
return reversed;
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentClosestDistance = Infinity;
|
||||||
|
let currentClosestKeyword;
|
||||||
|
|
||||||
|
for (const keyword of Object.keys(cssKeywords)) {
|
||||||
|
const value = cssKeywords[keyword];
|
||||||
|
|
||||||
|
// Compute comparative distance
|
||||||
|
const distance = comparativeDistance(rgb, value);
|
||||||
|
|
||||||
|
// Check if its less, if so set as closest
|
||||||
|
if (distance < currentClosestDistance) {
|
||||||
|
currentClosestDistance = distance;
|
||||||
|
currentClosestKeyword = keyword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentClosestKeyword;
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.keyword.rgb = function (keyword) {
|
||||||
|
return cssKeywords[keyword];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.xyz = function (rgb) {
|
||||||
|
let r = rgb[0] / 255;
|
||||||
|
let g = rgb[1] / 255;
|
||||||
|
let b = rgb[2] / 255;
|
||||||
|
|
||||||
|
// Assume sRGB
|
||||||
|
r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92);
|
||||||
|
g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92);
|
||||||
|
b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92);
|
||||||
|
|
||||||
|
const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
|
||||||
|
const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
|
||||||
|
const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
|
||||||
|
|
||||||
|
return [x * 100, y * 100, z * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.lab = function (rgb) {
|
||||||
|
const xyz = convert.rgb.xyz(rgb);
|
||||||
|
let x = xyz[0];
|
||||||
|
let y = xyz[1];
|
||||||
|
let z = xyz[2];
|
||||||
|
|
||||||
|
x /= 95.047;
|
||||||
|
y /= 100;
|
||||||
|
z /= 108.883;
|
||||||
|
|
||||||
|
x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);
|
||||||
|
y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);
|
||||||
|
z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);
|
||||||
|
|
||||||
|
const l = (116 * y) - 16;
|
||||||
|
const a = 500 * (x - y);
|
||||||
|
const b = 200 * (y - z);
|
||||||
|
|
||||||
|
return [l, a, b];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hsl.rgb = function (hsl) {
|
||||||
|
const h = hsl[0] / 360;
|
||||||
|
const s = hsl[1] / 100;
|
||||||
|
const l = hsl[2] / 100;
|
||||||
|
let t2;
|
||||||
|
let t3;
|
||||||
|
let val;
|
||||||
|
|
||||||
|
if (s === 0) {
|
||||||
|
val = l * 255;
|
||||||
|
return [val, val, val];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l < 0.5) {
|
||||||
|
t2 = l * (1 + s);
|
||||||
|
} else {
|
||||||
|
t2 = l + s - l * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
const t1 = 2 * l - t2;
|
||||||
|
|
||||||
|
const rgb = [0, 0, 0];
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
t3 = h + 1 / 3 * -(i - 1);
|
||||||
|
if (t3 < 0) {
|
||||||
|
t3++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t3 > 1) {
|
||||||
|
t3--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (6 * t3 < 1) {
|
||||||
|
val = t1 + (t2 - t1) * 6 * t3;
|
||||||
|
} else if (2 * t3 < 1) {
|
||||||
|
val = t2;
|
||||||
|
} else if (3 * t3 < 2) {
|
||||||
|
val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
|
||||||
|
} else {
|
||||||
|
val = t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb[i] = val * 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rgb;
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hsl.hsv = function (hsl) {
|
||||||
|
const h = hsl[0];
|
||||||
|
let s = hsl[1] / 100;
|
||||||
|
let l = hsl[2] / 100;
|
||||||
|
let smin = s;
|
||||||
|
const lmin = Math.max(l, 0.01);
|
||||||
|
|
||||||
|
l *= 2;
|
||||||
|
s *= (l <= 1) ? l : 2 - l;
|
||||||
|
smin *= lmin <= 1 ? lmin : 2 - lmin;
|
||||||
|
const v = (l + s) / 2;
|
||||||
|
const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
|
||||||
|
|
||||||
|
return [h, sv * 100, v * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hsv.rgb = function (hsv) {
|
||||||
|
const h = hsv[0] / 60;
|
||||||
|
const s = hsv[1] / 100;
|
||||||
|
let v = hsv[2] / 100;
|
||||||
|
const hi = Math.floor(h) % 6;
|
||||||
|
|
||||||
|
const f = h - Math.floor(h);
|
||||||
|
const p = 255 * v * (1 - s);
|
||||||
|
const q = 255 * v * (1 - (s * f));
|
||||||
|
const t = 255 * v * (1 - (s * (1 - f)));
|
||||||
|
v *= 255;
|
||||||
|
|
||||||
|
switch (hi) {
|
||||||
|
case 0:
|
||||||
|
return [v, t, p];
|
||||||
|
case 1:
|
||||||
|
return [q, v, p];
|
||||||
|
case 2:
|
||||||
|
return [p, v, t];
|
||||||
|
case 3:
|
||||||
|
return [p, q, v];
|
||||||
|
case 4:
|
||||||
|
return [t, p, v];
|
||||||
|
case 5:
|
||||||
|
return [v, p, q];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hsv.hsl = function (hsv) {
|
||||||
|
const h = hsv[0];
|
||||||
|
const s = hsv[1] / 100;
|
||||||
|
const v = hsv[2] / 100;
|
||||||
|
const vmin = Math.max(v, 0.01);
|
||||||
|
let sl;
|
||||||
|
let l;
|
||||||
|
|
||||||
|
l = (2 - s) * v;
|
||||||
|
const lmin = (2 - s) * vmin;
|
||||||
|
sl = s * vmin;
|
||||||
|
sl /= (lmin <= 1) ? lmin : 2 - lmin;
|
||||||
|
sl = sl || 0;
|
||||||
|
l /= 2;
|
||||||
|
|
||||||
|
return [h, sl * 100, l * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
|
||||||
|
convert.hwb.rgb = function (hwb) {
|
||||||
|
const h = hwb[0] / 360;
|
||||||
|
let wh = hwb[1] / 100;
|
||||||
|
let bl = hwb[2] / 100;
|
||||||
|
const ratio = wh + bl;
|
||||||
|
let f;
|
||||||
|
|
||||||
|
// Wh + bl cant be > 1
|
||||||
|
if (ratio > 1) {
|
||||||
|
wh /= ratio;
|
||||||
|
bl /= ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
const i = Math.floor(6 * h);
|
||||||
|
const v = 1 - bl;
|
||||||
|
f = 6 * h - i;
|
||||||
|
|
||||||
|
if ((i & 0x01) !== 0) {
|
||||||
|
f = 1 - f;
|
||||||
|
}
|
||||||
|
|
||||||
|
const n = wh + f * (v - wh); // Linear interpolation
|
||||||
|
|
||||||
|
let r;
|
||||||
|
let g;
|
||||||
|
let b;
|
||||||
|
/* eslint-disable max-statements-per-line,no-multi-spaces */
|
||||||
|
switch (i) {
|
||||||
|
default:
|
||||||
|
case 6:
|
||||||
|
case 0: r = v; g = n; b = wh; break;
|
||||||
|
case 1: r = n; g = v; b = wh; break;
|
||||||
|
case 2: r = wh; g = v; b = n; break;
|
||||||
|
case 3: r = wh; g = n; b = v; break;
|
||||||
|
case 4: r = n; g = wh; b = v; break;
|
||||||
|
case 5: r = v; g = wh; b = n; break;
|
||||||
|
}
|
||||||
|
/* eslint-enable max-statements-per-line,no-multi-spaces */
|
||||||
|
|
||||||
|
return [r * 255, g * 255, b * 255];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.cmyk.rgb = function (cmyk) {
|
||||||
|
const c = cmyk[0] / 100;
|
||||||
|
const m = cmyk[1] / 100;
|
||||||
|
const y = cmyk[2] / 100;
|
||||||
|
const k = cmyk[3] / 100;
|
||||||
|
|
||||||
|
const r = 1 - Math.min(1, c * (1 - k) + k);
|
||||||
|
const g = 1 - Math.min(1, m * (1 - k) + k);
|
||||||
|
const b = 1 - Math.min(1, y * (1 - k) + k);
|
||||||
|
|
||||||
|
return [r * 255, g * 255, b * 255];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.xyz.rgb = function (xyz) {
|
||||||
|
const x = xyz[0] / 100;
|
||||||
|
const y = xyz[1] / 100;
|
||||||
|
const z = xyz[2] / 100;
|
||||||
|
let r;
|
||||||
|
let g;
|
||||||
|
let b;
|
||||||
|
|
||||||
|
r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
|
||||||
|
g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
|
||||||
|
b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
|
||||||
|
|
||||||
|
// Assume sRGB
|
||||||
|
r = r > 0.0031308
|
||||||
|
? ((1.055 * (r ** (1.0 / 2.4))) - 0.055)
|
||||||
|
: r * 12.92;
|
||||||
|
|
||||||
|
g = g > 0.0031308
|
||||||
|
? ((1.055 * (g ** (1.0 / 2.4))) - 0.055)
|
||||||
|
: g * 12.92;
|
||||||
|
|
||||||
|
b = b > 0.0031308
|
||||||
|
? ((1.055 * (b ** (1.0 / 2.4))) - 0.055)
|
||||||
|
: b * 12.92;
|
||||||
|
|
||||||
|
r = Math.min(Math.max(0, r), 1);
|
||||||
|
g = Math.min(Math.max(0, g), 1);
|
||||||
|
b = Math.min(Math.max(0, b), 1);
|
||||||
|
|
||||||
|
return [r * 255, g * 255, b * 255];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.xyz.lab = function (xyz) {
|
||||||
|
let x = xyz[0];
|
||||||
|
let y = xyz[1];
|
||||||
|
let z = xyz[2];
|
||||||
|
|
||||||
|
x /= 95.047;
|
||||||
|
y /= 100;
|
||||||
|
z /= 108.883;
|
||||||
|
|
||||||
|
x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);
|
||||||
|
y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);
|
||||||
|
z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);
|
||||||
|
|
||||||
|
const l = (116 * y) - 16;
|
||||||
|
const a = 500 * (x - y);
|
||||||
|
const b = 200 * (y - z);
|
||||||
|
|
||||||
|
return [l, a, b];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.lab.xyz = function (lab) {
|
||||||
|
const l = lab[0];
|
||||||
|
const a = lab[1];
|
||||||
|
const b = lab[2];
|
||||||
|
let x;
|
||||||
|
let y;
|
||||||
|
let z;
|
||||||
|
|
||||||
|
y = (l + 16) / 116;
|
||||||
|
x = a / 500 + y;
|
||||||
|
z = y - b / 200;
|
||||||
|
|
||||||
|
const y2 = y ** 3;
|
||||||
|
const x2 = x ** 3;
|
||||||
|
const z2 = z ** 3;
|
||||||
|
y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
|
||||||
|
x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
|
||||||
|
z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
|
||||||
|
|
||||||
|
x *= 95.047;
|
||||||
|
y *= 100;
|
||||||
|
z *= 108.883;
|
||||||
|
|
||||||
|
return [x, y, z];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.lab.lch = function (lab) {
|
||||||
|
const l = lab[0];
|
||||||
|
const a = lab[1];
|
||||||
|
const b = lab[2];
|
||||||
|
let h;
|
||||||
|
|
||||||
|
const hr = Math.atan2(b, a);
|
||||||
|
h = hr * 360 / 2 / Math.PI;
|
||||||
|
|
||||||
|
if (h < 0) {
|
||||||
|
h += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
const c = Math.sqrt(a * a + b * b);
|
||||||
|
|
||||||
|
return [l, c, h];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.lch.lab = function (lch) {
|
||||||
|
const l = lch[0];
|
||||||
|
const c = lch[1];
|
||||||
|
const h = lch[2];
|
||||||
|
|
||||||
|
const hr = h / 360 * 2 * Math.PI;
|
||||||
|
const a = c * Math.cos(hr);
|
||||||
|
const b = c * Math.sin(hr);
|
||||||
|
|
||||||
|
return [l, a, b];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.ansi16 = function (args, saturation = null) {
|
||||||
|
const [r, g, b] = args;
|
||||||
|
let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization
|
||||||
|
|
||||||
|
value = Math.round(value / 50);
|
||||||
|
|
||||||
|
if (value === 0) {
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ansi = 30
|
||||||
|
+ ((Math.round(b / 255) << 2)
|
||||||
|
| (Math.round(g / 255) << 1)
|
||||||
|
| Math.round(r / 255));
|
||||||
|
|
||||||
|
if (value === 2) {
|
||||||
|
ansi += 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ansi;
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hsv.ansi16 = function (args) {
|
||||||
|
// Optimization here; we already know the value and don't need to get
|
||||||
|
// it converted for us.
|
||||||
|
return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.ansi256 = function (args) {
|
||||||
|
const r = args[0];
|
||||||
|
const g = args[1];
|
||||||
|
const b = args[2];
|
||||||
|
|
||||||
|
// We use the extended greyscale palette here, with the exception of
|
||||||
|
// black and white. normal palette only has 4 greyscale shades.
|
||||||
|
if (r === g && g === b) {
|
||||||
|
if (r < 8) {
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r > 248) {
|
||||||
|
return 231;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.round(((r - 8) / 247) * 24) + 232;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ansi = 16
|
||||||
|
+ (36 * Math.round(r / 255 * 5))
|
||||||
|
+ (6 * Math.round(g / 255 * 5))
|
||||||
|
+ Math.round(b / 255 * 5);
|
||||||
|
|
||||||
|
return ansi;
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.ansi16.rgb = function (args) {
|
||||||
|
let color = args % 10;
|
||||||
|
|
||||||
|
// Handle greyscale
|
||||||
|
if (color === 0 || color === 7) {
|
||||||
|
if (args > 50) {
|
||||||
|
color += 3.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = color / 10.5 * 255;
|
||||||
|
|
||||||
|
return [color, color, color];
|
||||||
|
}
|
||||||
|
|
||||||
|
const mult = (~~(args > 50) + 1) * 0.5;
|
||||||
|
const r = ((color & 1) * mult) * 255;
|
||||||
|
const g = (((color >> 1) & 1) * mult) * 255;
|
||||||
|
const b = (((color >> 2) & 1) * mult) * 255;
|
||||||
|
|
||||||
|
return [r, g, b];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.ansi256.rgb = function (args) {
|
||||||
|
// Handle greyscale
|
||||||
|
if (args >= 232) {
|
||||||
|
const c = (args - 232) * 10 + 8;
|
||||||
|
return [c, c, c];
|
||||||
|
}
|
||||||
|
|
||||||
|
args -= 16;
|
||||||
|
|
||||||
|
let rem;
|
||||||
|
const r = Math.floor(args / 36) / 5 * 255;
|
||||||
|
const g = Math.floor((rem = args % 36) / 6) / 5 * 255;
|
||||||
|
const b = (rem % 6) / 5 * 255;
|
||||||
|
|
||||||
|
return [r, g, b];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.hex = function (args) {
|
||||||
|
const integer = ((Math.round(args[0]) & 0xFF) << 16)
|
||||||
|
+ ((Math.round(args[1]) & 0xFF) << 8)
|
||||||
|
+ (Math.round(args[2]) & 0xFF);
|
||||||
|
|
||||||
|
const string = integer.toString(16).toUpperCase();
|
||||||
|
return '000000'.substring(string.length) + string;
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hex.rgb = function (args) {
|
||||||
|
const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
|
||||||
|
if (!match) {
|
||||||
|
return [0, 0, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
let colorString = match[0];
|
||||||
|
|
||||||
|
if (match[0].length === 3) {
|
||||||
|
colorString = colorString.split('').map(char => {
|
||||||
|
return char + char;
|
||||||
|
}).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
const integer = parseInt(colorString, 16);
|
||||||
|
const r = (integer >> 16) & 0xFF;
|
||||||
|
const g = (integer >> 8) & 0xFF;
|
||||||
|
const b = integer & 0xFF;
|
||||||
|
|
||||||
|
return [r, g, b];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.hcg = function (rgb) {
|
||||||
|
const r = rgb[0] / 255;
|
||||||
|
const g = rgb[1] / 255;
|
||||||
|
const b = rgb[2] / 255;
|
||||||
|
const max = Math.max(Math.max(r, g), b);
|
||||||
|
const min = Math.min(Math.min(r, g), b);
|
||||||
|
const chroma = (max - min);
|
||||||
|
let grayscale;
|
||||||
|
let hue;
|
||||||
|
|
||||||
|
if (chroma < 1) {
|
||||||
|
grayscale = min / (1 - chroma);
|
||||||
|
} else {
|
||||||
|
grayscale = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chroma <= 0) {
|
||||||
|
hue = 0;
|
||||||
|
} else
|
||||||
|
if (max === r) {
|
||||||
|
hue = ((g - b) / chroma) % 6;
|
||||||
|
} else
|
||||||
|
if (max === g) {
|
||||||
|
hue = 2 + (b - r) / chroma;
|
||||||
|
} else {
|
||||||
|
hue = 4 + (r - g) / chroma;
|
||||||
|
}
|
||||||
|
|
||||||
|
hue /= 6;
|
||||||
|
hue %= 1;
|
||||||
|
|
||||||
|
return [hue * 360, chroma * 100, grayscale * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hsl.hcg = function (hsl) {
|
||||||
|
const s = hsl[1] / 100;
|
||||||
|
const l = hsl[2] / 100;
|
||||||
|
|
||||||
|
const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l));
|
||||||
|
|
||||||
|
let f = 0;
|
||||||
|
if (c < 1.0) {
|
||||||
|
f = (l - 0.5 * c) / (1.0 - c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [hsl[0], c * 100, f * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hsv.hcg = function (hsv) {
|
||||||
|
const s = hsv[1] / 100;
|
||||||
|
const v = hsv[2] / 100;
|
||||||
|
|
||||||
|
const c = s * v;
|
||||||
|
let f = 0;
|
||||||
|
|
||||||
|
if (c < 1.0) {
|
||||||
|
f = (v - c) / (1 - c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [hsv[0], c * 100, f * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hcg.rgb = function (hcg) {
|
||||||
|
const h = hcg[0] / 360;
|
||||||
|
const c = hcg[1] / 100;
|
||||||
|
const g = hcg[2] / 100;
|
||||||
|
|
||||||
|
if (c === 0.0) {
|
||||||
|
return [g * 255, g * 255, g * 255];
|
||||||
|
}
|
||||||
|
|
||||||
|
const pure = [0, 0, 0];
|
||||||
|
const hi = (h % 1) * 6;
|
||||||
|
const v = hi % 1;
|
||||||
|
const w = 1 - v;
|
||||||
|
let mg = 0;
|
||||||
|
|
||||||
|
/* eslint-disable max-statements-per-line */
|
||||||
|
switch (Math.floor(hi)) {
|
||||||
|
case 0:
|
||||||
|
pure[0] = 1; pure[1] = v; pure[2] = 0; break;
|
||||||
|
case 1:
|
||||||
|
pure[0] = w; pure[1] = 1; pure[2] = 0; break;
|
||||||
|
case 2:
|
||||||
|
pure[0] = 0; pure[1] = 1; pure[2] = v; break;
|
||||||
|
case 3:
|
||||||
|
pure[0] = 0; pure[1] = w; pure[2] = 1; break;
|
||||||
|
case 4:
|
||||||
|
pure[0] = v; pure[1] = 0; pure[2] = 1; break;
|
||||||
|
default:
|
||||||
|
pure[0] = 1; pure[1] = 0; pure[2] = w;
|
||||||
|
}
|
||||||
|
/* eslint-enable max-statements-per-line */
|
||||||
|
|
||||||
|
mg = (1.0 - c) * g;
|
||||||
|
|
||||||
|
return [
|
||||||
|
(c * pure[0] + mg) * 255,
|
||||||
|
(c * pure[1] + mg) * 255,
|
||||||
|
(c * pure[2] + mg) * 255
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hcg.hsv = function (hcg) {
|
||||||
|
const c = hcg[1] / 100;
|
||||||
|
const g = hcg[2] / 100;
|
||||||
|
|
||||||
|
const v = c + g * (1.0 - c);
|
||||||
|
let f = 0;
|
||||||
|
|
||||||
|
if (v > 0.0) {
|
||||||
|
f = c / v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [hcg[0], f * 100, v * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hcg.hsl = function (hcg) {
|
||||||
|
const c = hcg[1] / 100;
|
||||||
|
const g = hcg[2] / 100;
|
||||||
|
|
||||||
|
const l = g * (1.0 - c) + 0.5 * c;
|
||||||
|
let s = 0;
|
||||||
|
|
||||||
|
if (l > 0.0 && l < 0.5) {
|
||||||
|
s = c / (2 * l);
|
||||||
|
} else
|
||||||
|
if (l >= 0.5 && l < 1.0) {
|
||||||
|
s = c / (2 * (1 - l));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [hcg[0], s * 100, l * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hcg.hwb = function (hcg) {
|
||||||
|
const c = hcg[1] / 100;
|
||||||
|
const g = hcg[2] / 100;
|
||||||
|
const v = c + g * (1.0 - c);
|
||||||
|
return [hcg[0], (v - c) * 100, (1 - v) * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.hwb.hcg = function (hwb) {
|
||||||
|
const w = hwb[1] / 100;
|
||||||
|
const b = hwb[2] / 100;
|
||||||
|
const v = 1 - b;
|
||||||
|
const c = v - w;
|
||||||
|
let g = 0;
|
||||||
|
|
||||||
|
if (c < 1) {
|
||||||
|
g = (v - c) / (1 - c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [hwb[0], c * 100, g * 100];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.apple.rgb = function (apple) {
|
||||||
|
return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.apple = function (rgb) {
|
||||||
|
return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.gray.rgb = function (args) {
|
||||||
|
return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.gray.hsl = function (args) {
|
||||||
|
return [0, 0, args[0]];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.gray.hsv = convert.gray.hsl;
|
||||||
|
|
||||||
|
convert.gray.hwb = function (gray) {
|
||||||
|
return [0, 100, gray[0]];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.gray.cmyk = function (gray) {
|
||||||
|
return [0, 0, 0, gray[0]];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.gray.lab = function (gray) {
|
||||||
|
return [gray[0], 0, 0];
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.gray.hex = function (gray) {
|
||||||
|
const val = Math.round(gray[0] / 100 * 255) & 0xFF;
|
||||||
|
const integer = (val << 16) + (val << 8) + val;
|
||||||
|
|
||||||
|
const string = integer.toString(16).toUpperCase();
|
||||||
|
return '000000'.substring(string.length) + string;
|
||||||
|
};
|
||||||
|
|
||||||
|
convert.rgb.gray = function (rgb) {
|
||||||
|
const val = (rgb[0] + rgb[1] + rgb[2]) / 3;
|
||||||
|
return [val / 255 * 100];
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
const conversions = require('./conversions');
|
||||||
|
const route = require('./route');
|
||||||
|
|
||||||
|
const convert = {};
|
||||||
|
|
||||||
|
const models = Object.keys(conversions);
|
||||||
|
|
||||||
|
function wrapRaw(fn) {
|
||||||
|
const wrappedFn = function (...args) {
|
||||||
|
const arg0 = args[0];
|
||||||
|
if (arg0 === undefined || arg0 === null) {
|
||||||
|
return arg0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg0.length > 1) {
|
||||||
|
args = arg0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fn(args);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Preserve .conversion property if there is one
|
||||||
|
if ('conversion' in fn) {
|
||||||
|
wrappedFn.conversion = fn.conversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrappedFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapRounded(fn) {
|
||||||
|
const wrappedFn = function (...args) {
|
||||||
|
const arg0 = args[0];
|
||||||
|
|
||||||
|
if (arg0 === undefined || arg0 === null) {
|
||||||
|
return arg0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg0.length > 1) {
|
||||||
|
args = arg0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = fn(args);
|
||||||
|
|
||||||
|
// We're assuming the result is an array here.
|
||||||
|
// see notice in conversions.js; don't use box types
|
||||||
|
// in conversion functions.
|
||||||
|
if (typeof result === 'object') {
|
||||||
|
for (let len = result.length, i = 0; i < len; i++) {
|
||||||
|
result[i] = Math.round(result[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Preserve .conversion property if there is one
|
||||||
|
if ('conversion' in fn) {
|
||||||
|
wrappedFn.conversion = fn.conversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrappedFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
models.forEach(fromModel => {
|
||||||
|
convert[fromModel] = {};
|
||||||
|
|
||||||
|
Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
|
||||||
|
Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
|
||||||
|
|
||||||
|
const routes = route(fromModel);
|
||||||
|
const routeModels = Object.keys(routes);
|
||||||
|
|
||||||
|
routeModels.forEach(toModel => {
|
||||||
|
const fn = routes[toModel];
|
||||||
|
|
||||||
|
convert[fromModel][toModel] = wrapRounded(fn);
|
||||||
|
convert[fromModel][toModel].raw = wrapRaw(fn);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = convert;
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"name": "color-convert",
|
||||||
|
"description": "Plain color conversion functions",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"author": "Heather Arthur <fayearthur@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "Qix-/color-convert",
|
||||||
|
"scripts": {
|
||||||
|
"pretest": "xo",
|
||||||
|
"test": "node test/basic.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=7.0.0"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"color",
|
||||||
|
"colour",
|
||||||
|
"convert",
|
||||||
|
"converter",
|
||||||
|
"conversion",
|
||||||
|
"rgb",
|
||||||
|
"hsl",
|
||||||
|
"hsv",
|
||||||
|
"hwb",
|
||||||
|
"cmyk",
|
||||||
|
"ansi",
|
||||||
|
"ansi16"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"index.js",
|
||||||
|
"conversions.js",
|
||||||
|
"route.js"
|
||||||
|
],
|
||||||
|
"xo": {
|
||||||
|
"rules": {
|
||||||
|
"default-case": 0,
|
||||||
|
"no-inline-comments": 0,
|
||||||
|
"operator-linebreak": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"chalk": "^2.4.2",
|
||||||
|
"xo": "^0.24.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
const conversions = require('./conversions');
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function routes a model to all other models.
|
||||||
|
|
||||||
|
all functions that are routed have a property `.conversion` attached
|
||||||
|
to the returned synthetic function. This property is an array
|
||||||
|
of strings, each with the steps in between the 'from' and 'to'
|
||||||
|
color models (inclusive).
|
||||||
|
|
||||||
|
conversions that are not possible simply are not included.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function buildGraph() {
|
||||||
|
const graph = {};
|
||||||
|
// https://jsperf.com/object-keys-vs-for-in-with-closure/3
|
||||||
|
const models = Object.keys(conversions);
|
||||||
|
|
||||||
|
for (let len = models.length, i = 0; i < len; i++) {
|
||||||
|
graph[models[i]] = {
|
||||||
|
// http://jsperf.com/1-vs-infinity
|
||||||
|
// micro-opt, but this is simple.
|
||||||
|
distance: -1,
|
||||||
|
parent: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Breadth-first_search
|
||||||
|
function deriveBFS(fromModel) {
|
||||||
|
const graph = buildGraph();
|
||||||
|
const queue = [fromModel]; // Unshift -> queue -> pop
|
||||||
|
|
||||||
|
graph[fromModel].distance = 0;
|
||||||
|
|
||||||
|
while (queue.length) {
|
||||||
|
const current = queue.pop();
|
||||||
|
const adjacents = Object.keys(conversions[current]);
|
||||||
|
|
||||||
|
for (let len = adjacents.length, i = 0; i < len; i++) {
|
||||||
|
const adjacent = adjacents[i];
|
||||||
|
const node = graph[adjacent];
|
||||||
|
|
||||||
|
if (node.distance === -1) {
|
||||||
|
node.distance = graph[current].distance + 1;
|
||||||
|
node.parent = current;
|
||||||
|
queue.unshift(adjacent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
function link(from, to) {
|
||||||
|
return function (args) {
|
||||||
|
return to(from(args));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapConversion(toModel, graph) {
|
||||||
|
const path = [graph[toModel].parent, toModel];
|
||||||
|
let fn = conversions[graph[toModel].parent][toModel];
|
||||||
|
|
||||||
|
let cur = graph[toModel].parent;
|
||||||
|
while (graph[cur].parent) {
|
||||||
|
path.unshift(graph[cur].parent);
|
||||||
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
||||||
|
cur = graph[cur].parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn.conversion = path;
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (fromModel) {
|
||||||
|
const graph = deriveBFS(fromModel);
|
||||||
|
const conversion = {};
|
||||||
|
|
||||||
|
const models = Object.keys(graph);
|
||||||
|
for (let len = models.length, i = 0; i < len; i++) {
|
||||||
|
const toModel = models[i];
|
||||||
|
const node = graph[toModel];
|
||||||
|
|
||||||
|
if (node.parent === null) {
|
||||||
|
// No possible conversion, or this node is the source model.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
conversion[toModel] = wrapConversion(toModel, graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
return conversion;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
Copyright (c) 2015 Dmitry Ivanov
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
A JSON with color names and its values. Based on http://dev.w3.org/csswg/css-color/#named-colors.
|
||||||
|
|
||||||
|
[](https://nodei.co/npm/color-name/)
|
||||||
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
var colors = require('color-name');
|
||||||
|
colors.red //[255,0,0]
|
||||||
|
```
|
||||||
|
|
||||||
|
<a href="LICENSE"><img src="https://upload.wikimedia.org/wikipedia/commons/0/0c/MIT_logo.svg" width="120"/></a>
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
"aliceblue": [240, 248, 255],
|
||||||
|
"antiquewhite": [250, 235, 215],
|
||||||
|
"aqua": [0, 255, 255],
|
||||||
|
"aquamarine": [127, 255, 212],
|
||||||
|
"azure": [240, 255, 255],
|
||||||
|
"beige": [245, 245, 220],
|
||||||
|
"bisque": [255, 228, 196],
|
||||||
|
"black": [0, 0, 0],
|
||||||
|
"blanchedalmond": [255, 235, 205],
|
||||||
|
"blue": [0, 0, 255],
|
||||||
|
"blueviolet": [138, 43, 226],
|
||||||
|
"brown": [165, 42, 42],
|
||||||
|
"burlywood": [222, 184, 135],
|
||||||
|
"cadetblue": [95, 158, 160],
|
||||||
|
"chartreuse": [127, 255, 0],
|
||||||
|
"chocolate": [210, 105, 30],
|
||||||
|
"coral": [255, 127, 80],
|
||||||
|
"cornflowerblue": [100, 149, 237],
|
||||||
|
"cornsilk": [255, 248, 220],
|
||||||
|
"crimson": [220, 20, 60],
|
||||||
|
"cyan": [0, 255, 255],
|
||||||
|
"darkblue": [0, 0, 139],
|
||||||
|
"darkcyan": [0, 139, 139],
|
||||||
|
"darkgoldenrod": [184, 134, 11],
|
||||||
|
"darkgray": [169, 169, 169],
|
||||||
|
"darkgreen": [0, 100, 0],
|
||||||
|
"darkgrey": [169, 169, 169],
|
||||||
|
"darkkhaki": [189, 183, 107],
|
||||||
|
"darkmagenta": [139, 0, 139],
|
||||||
|
"darkolivegreen": [85, 107, 47],
|
||||||
|
"darkorange": [255, 140, 0],
|
||||||
|
"darkorchid": [153, 50, 204],
|
||||||
|
"darkred": [139, 0, 0],
|
||||||
|
"darksalmon": [233, 150, 122],
|
||||||
|
"darkseagreen": [143, 188, 143],
|
||||||
|
"darkslateblue": [72, 61, 139],
|
||||||
|
"darkslategray": [47, 79, 79],
|
||||||
|
"darkslategrey": [47, 79, 79],
|
||||||
|
"darkturquoise": [0, 206, 209],
|
||||||
|
"darkviolet": [148, 0, 211],
|
||||||
|
"deeppink": [255, 20, 147],
|
||||||
|
"deepskyblue": [0, 191, 255],
|
||||||
|
"dimgray": [105, 105, 105],
|
||||||
|
"dimgrey": [105, 105, 105],
|
||||||
|
"dodgerblue": [30, 144, 255],
|
||||||
|
"firebrick": [178, 34, 34],
|
||||||
|
"floralwhite": [255, 250, 240],
|
||||||
|
"forestgreen": [34, 139, 34],
|
||||||
|
"fuchsia": [255, 0, 255],
|
||||||
|
"gainsboro": [220, 220, 220],
|
||||||
|
"ghostwhite": [248, 248, 255],
|
||||||
|
"gold": [255, 215, 0],
|
||||||
|
"goldenrod": [218, 165, 32],
|
||||||
|
"gray": [128, 128, 128],
|
||||||
|
"green": [0, 128, 0],
|
||||||
|
"greenyellow": [173, 255, 47],
|
||||||
|
"grey": [128, 128, 128],
|
||||||
|
"honeydew": [240, 255, 240],
|
||||||
|
"hotpink": [255, 105, 180],
|
||||||
|
"indianred": [205, 92, 92],
|
||||||
|
"indigo": [75, 0, 130],
|
||||||
|
"ivory": [255, 255, 240],
|
||||||
|
"khaki": [240, 230, 140],
|
||||||
|
"lavender": [230, 230, 250],
|
||||||
|
"lavenderblush": [255, 240, 245],
|
||||||
|
"lawngreen": [124, 252, 0],
|
||||||
|
"lemonchiffon": [255, 250, 205],
|
||||||
|
"lightblue": [173, 216, 230],
|
||||||
|
"lightcoral": [240, 128, 128],
|
||||||
|
"lightcyan": [224, 255, 255],
|
||||||
|
"lightgoldenrodyellow": [250, 250, 210],
|
||||||
|
"lightgray": [211, 211, 211],
|
||||||
|
"lightgreen": [144, 238, 144],
|
||||||
|
"lightgrey": [211, 211, 211],
|
||||||
|
"lightpink": [255, 182, 193],
|
||||||
|
"lightsalmon": [255, 160, 122],
|
||||||
|
"lightseagreen": [32, 178, 170],
|
||||||
|
"lightskyblue": [135, 206, 250],
|
||||||
|
"lightslategray": [119, 136, 153],
|
||||||
|
"lightslategrey": [119, 136, 153],
|
||||||
|
"lightsteelblue": [176, 196, 222],
|
||||||
|
"lightyellow": [255, 255, 224],
|
||||||
|
"lime": [0, 255, 0],
|
||||||
|
"limegreen": [50, 205, 50],
|
||||||
|
"linen": [250, 240, 230],
|
||||||
|
"magenta": [255, 0, 255],
|
||||||
|
"maroon": [128, 0, 0],
|
||||||
|
"mediumaquamarine": [102, 205, 170],
|
||||||
|
"mediumblue": [0, 0, 205],
|
||||||
|
"mediumorchid": [186, 85, 211],
|
||||||
|
"mediumpurple": [147, 112, 219],
|
||||||
|
"mediumseagreen": [60, 179, 113],
|
||||||
|
"mediumslateblue": [123, 104, 238],
|
||||||
|
"mediumspringgreen": [0, 250, 154],
|
||||||
|
"mediumturquoise": [72, 209, 204],
|
||||||
|
"mediumvioletred": [199, 21, 133],
|
||||||
|
"midnightblue": [25, 25, 112],
|
||||||
|
"mintcream": [245, 255, 250],
|
||||||
|
"mistyrose": [255, 228, 225],
|
||||||
|
"moccasin": [255, 228, 181],
|
||||||
|
"navajowhite": [255, 222, 173],
|
||||||
|
"navy": [0, 0, 128],
|
||||||
|
"oldlace": [253, 245, 230],
|
||||||
|
"olive": [128, 128, 0],
|
||||||
|
"olivedrab": [107, 142, 35],
|
||||||
|
"orange": [255, 165, 0],
|
||||||
|
"orangered": [255, 69, 0],
|
||||||
|
"orchid": [218, 112, 214],
|
||||||
|
"palegoldenrod": [238, 232, 170],
|
||||||
|
"palegreen": [152, 251, 152],
|
||||||
|
"paleturquoise": [175, 238, 238],
|
||||||
|
"palevioletred": [219, 112, 147],
|
||||||
|
"papayawhip": [255, 239, 213],
|
||||||
|
"peachpuff": [255, 218, 185],
|
||||||
|
"peru": [205, 133, 63],
|
||||||
|
"pink": [255, 192, 203],
|
||||||
|
"plum": [221, 160, 221],
|
||||||
|
"powderblue": [176, 224, 230],
|
||||||
|
"purple": [128, 0, 128],
|
||||||
|
"rebeccapurple": [102, 51, 153],
|
||||||
|
"red": [255, 0, 0],
|
||||||
|
"rosybrown": [188, 143, 143],
|
||||||
|
"royalblue": [65, 105, 225],
|
||||||
|
"saddlebrown": [139, 69, 19],
|
||||||
|
"salmon": [250, 128, 114],
|
||||||
|
"sandybrown": [244, 164, 96],
|
||||||
|
"seagreen": [46, 139, 87],
|
||||||
|
"seashell": [255, 245, 238],
|
||||||
|
"sienna": [160, 82, 45],
|
||||||
|
"silver": [192, 192, 192],
|
||||||
|
"skyblue": [135, 206, 235],
|
||||||
|
"slateblue": [106, 90, 205],
|
||||||
|
"slategray": [112, 128, 144],
|
||||||
|
"slategrey": [112, 128, 144],
|
||||||
|
"snow": [255, 250, 250],
|
||||||
|
"springgreen": [0, 255, 127],
|
||||||
|
"steelblue": [70, 130, 180],
|
||||||
|
"tan": [210, 180, 140],
|
||||||
|
"teal": [0, 128, 128],
|
||||||
|
"thistle": [216, 191, 216],
|
||||||
|
"tomato": [255, 99, 71],
|
||||||
|
"turquoise": [64, 224, 208],
|
||||||
|
"violet": [238, 130, 238],
|
||||||
|
"wheat": [245, 222, 179],
|
||||||
|
"white": [255, 255, 255],
|
||||||
|
"whitesmoke": [245, 245, 245],
|
||||||
|
"yellow": [255, 255, 0],
|
||||||
|
"yellowgreen": [154, 205, 50]
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "color-name",
|
||||||
|
"version": "1.1.4",
|
||||||
|
"description": "A list of color names and its values",
|
||||||
|
"main": "index.js",
|
||||||
|
"files": [
|
||||||
|
"index.js"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@github.com:colorjs/color-name.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"color-name",
|
||||||
|
"color",
|
||||||
|
"color-keyword",
|
||||||
|
"keyword"
|
||||||
|
],
|
||||||
|
"author": "DY <dfcreative@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/colorjs/color-name/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/colorjs/color-name"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "stable"
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Dmitry Ivanov
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
/**
|
||||||
|
* @module color-parse
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
var names = require('color-name')
|
||||||
|
|
||||||
|
module.exports = parse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base hues
|
||||||
|
* http://dev.w3.org/csswg/css-color/#typedef-named-hue
|
||||||
|
*/
|
||||||
|
//FIXME: use external hue detector
|
||||||
|
var baseHues = {
|
||||||
|
red: 0,
|
||||||
|
orange: 60,
|
||||||
|
yellow: 120,
|
||||||
|
green: 180,
|
||||||
|
blue: 240,
|
||||||
|
purple: 300
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse color from the string passed
|
||||||
|
*
|
||||||
|
* @return {Object} A space indicator `space`, an array `values` and `alpha`
|
||||||
|
*/
|
||||||
|
function parse (cstr) {
|
||||||
|
var m, parts = [], alpha = 1, space
|
||||||
|
|
||||||
|
if (typeof cstr === 'string') {
|
||||||
|
//keyword
|
||||||
|
if (names[cstr]) {
|
||||||
|
parts = names[cstr].slice()
|
||||||
|
space = 'rgb'
|
||||||
|
}
|
||||||
|
|
||||||
|
//reserved words
|
||||||
|
else if (cstr === 'transparent') {
|
||||||
|
alpha = 0
|
||||||
|
space = 'rgb'
|
||||||
|
parts = [0,0,0]
|
||||||
|
}
|
||||||
|
|
||||||
|
//hex
|
||||||
|
else if (/^#[A-Fa-f0-9]+$/.test(cstr)) {
|
||||||
|
var base = cstr.slice(1)
|
||||||
|
var size = base.length
|
||||||
|
var isShort = size <= 4
|
||||||
|
alpha = 1
|
||||||
|
|
||||||
|
if (isShort) {
|
||||||
|
parts = [
|
||||||
|
parseInt(base[0] + base[0], 16),
|
||||||
|
parseInt(base[1] + base[1], 16),
|
||||||
|
parseInt(base[2] + base[2], 16)
|
||||||
|
]
|
||||||
|
if (size === 4) {
|
||||||
|
alpha = parseInt(base[3] + base[3], 16) / 255
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parts = [
|
||||||
|
parseInt(base[0] + base[1], 16),
|
||||||
|
parseInt(base[2] + base[3], 16),
|
||||||
|
parseInt(base[4] + base[5], 16)
|
||||||
|
]
|
||||||
|
if (size === 8) {
|
||||||
|
alpha = parseInt(base[6] + base[7], 16) / 255
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parts[0]) parts[0] = 0
|
||||||
|
if (!parts[1]) parts[1] = 0
|
||||||
|
if (!parts[2]) parts[2] = 0
|
||||||
|
|
||||||
|
space = 'rgb'
|
||||||
|
}
|
||||||
|
|
||||||
|
//color space
|
||||||
|
else if (m = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(cstr)) {
|
||||||
|
var name = m[1]
|
||||||
|
var isRGB = name === 'rgb'
|
||||||
|
var base = name.replace(/a$/, '')
|
||||||
|
space = base
|
||||||
|
var size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3
|
||||||
|
parts = m[2].trim()
|
||||||
|
.split(/\s*[,\/]\s*|\s+/)
|
||||||
|
.map(function (x, i) {
|
||||||
|
//<percentage>
|
||||||
|
if (/%$/.test(x)) {
|
||||||
|
//alpha
|
||||||
|
if (i === size) return parseFloat(x) / 100
|
||||||
|
//rgb
|
||||||
|
if (base === 'rgb') return parseFloat(x) * 255 / 100
|
||||||
|
return parseFloat(x)
|
||||||
|
}
|
||||||
|
//hue
|
||||||
|
else if (base[i] === 'h') {
|
||||||
|
//<deg>
|
||||||
|
if (/deg$/.test(x)) {
|
||||||
|
return parseFloat(x)
|
||||||
|
}
|
||||||
|
//<base-hue>
|
||||||
|
else if (baseHues[x] !== undefined) {
|
||||||
|
return baseHues[x]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parseFloat(x)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (name === base) parts.push(1)
|
||||||
|
alpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]
|
||||||
|
parts = parts.slice(0, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
//named channels case
|
||||||
|
else if (cstr.length > 10 && /[0-9](?:\s|\/)/.test(cstr)) {
|
||||||
|
parts = cstr.match(/([0-9]+)/g).map(function (value) {
|
||||||
|
return parseFloat(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
space = cstr.match(/([a-z])/ig).join('').toLowerCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//numeric case
|
||||||
|
else if (!isNaN(cstr)) {
|
||||||
|
space = 'rgb'
|
||||||
|
parts = [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff]
|
||||||
|
}
|
||||||
|
|
||||||
|
//array-like
|
||||||
|
else if (Array.isArray(cstr) || cstr.length) {
|
||||||
|
parts = [cstr[0], cstr[1], cstr[2]]
|
||||||
|
space = 'rgb'
|
||||||
|
alpha = cstr.length === 4 ? cstr[3] : 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//object case - detects css cases of rgb and hsl
|
||||||
|
else if (cstr instanceof Object) {
|
||||||
|
if (cstr.r != null || cstr.red != null || cstr.R != null) {
|
||||||
|
space = 'rgb'
|
||||||
|
parts = [
|
||||||
|
cstr.r || cstr.red || cstr.R || 0,
|
||||||
|
cstr.g || cstr.green || cstr.G || 0,
|
||||||
|
cstr.b || cstr.blue || cstr.B || 0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
space = 'hsl'
|
||||||
|
parts = [
|
||||||
|
cstr.h || cstr.hue || cstr.H || 0,
|
||||||
|
cstr.s || cstr.saturation || cstr.S || 0,
|
||||||
|
cstr.l || cstr.lightness || cstr.L || cstr.b || cstr.brightness
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha = cstr.a || cstr.alpha || cstr.opacity || 1
|
||||||
|
|
||||||
|
if (cstr.opacity != null) alpha /= 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
space: space,
|
||||||
|
values: parts,
|
||||||
|
alpha: alpha
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
/**
|
||||||
|
* @module color-parse
|
||||||
|
*/
|
||||||
|
import names from 'color-name'
|
||||||
|
|
||||||
|
export default parse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base hues
|
||||||
|
* http://dev.w3.org/csswg/css-color/#typedef-named-hue
|
||||||
|
*/
|
||||||
|
//FIXME: use external hue detector
|
||||||
|
var baseHues = {
|
||||||
|
red: 0,
|
||||||
|
orange: 60,
|
||||||
|
yellow: 120,
|
||||||
|
green: 180,
|
||||||
|
blue: 240,
|
||||||
|
purple: 300
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse color from the string passed
|
||||||
|
*
|
||||||
|
* @return {Object} A space indicator `space`, an array `values` and `alpha`
|
||||||
|
*/
|
||||||
|
function parse (cstr) {
|
||||||
|
var m, parts = [], alpha = 1, space
|
||||||
|
|
||||||
|
if (typeof cstr === 'string') {
|
||||||
|
//keyword
|
||||||
|
if (names[cstr]) {
|
||||||
|
parts = names[cstr].slice()
|
||||||
|
space = 'rgb'
|
||||||
|
}
|
||||||
|
|
||||||
|
//reserved words
|
||||||
|
else if (cstr === 'transparent') {
|
||||||
|
alpha = 0
|
||||||
|
space = 'rgb'
|
||||||
|
parts = [0,0,0]
|
||||||
|
}
|
||||||
|
|
||||||
|
//hex
|
||||||
|
else if (/^#[A-Fa-f0-9]+$/.test(cstr)) {
|
||||||
|
var base = cstr.slice(1)
|
||||||
|
var size = base.length
|
||||||
|
var isShort = size <= 4
|
||||||
|
alpha = 1
|
||||||
|
|
||||||
|
if (isShort) {
|
||||||
|
parts = [
|
||||||
|
parseInt(base[0] + base[0], 16),
|
||||||
|
parseInt(base[1] + base[1], 16),
|
||||||
|
parseInt(base[2] + base[2], 16)
|
||||||
|
]
|
||||||
|
if (size === 4) {
|
||||||
|
alpha = parseInt(base[3] + base[3], 16) / 255
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parts = [
|
||||||
|
parseInt(base[0] + base[1], 16),
|
||||||
|
parseInt(base[2] + base[3], 16),
|
||||||
|
parseInt(base[4] + base[5], 16)
|
||||||
|
]
|
||||||
|
if (size === 8) {
|
||||||
|
alpha = parseInt(base[6] + base[7], 16) / 255
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parts[0]) parts[0] = 0
|
||||||
|
if (!parts[1]) parts[1] = 0
|
||||||
|
if (!parts[2]) parts[2] = 0
|
||||||
|
|
||||||
|
space = 'rgb'
|
||||||
|
}
|
||||||
|
|
||||||
|
//color space
|
||||||
|
else if (m = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\s*\(([^\)]*)\)/.exec(cstr)) {
|
||||||
|
var name = m[1]
|
||||||
|
var isRGB = name === 'rgb'
|
||||||
|
var base = name.replace(/a$/, '')
|
||||||
|
space = base
|
||||||
|
var size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3
|
||||||
|
parts = m[2].trim()
|
||||||
|
.split(/\s*[,\/]\s*|\s+/)
|
||||||
|
.map(function (x, i) {
|
||||||
|
//<percentage>
|
||||||
|
if (/%$/.test(x)) {
|
||||||
|
//alpha
|
||||||
|
if (i === size) return parseFloat(x) / 100
|
||||||
|
//rgb
|
||||||
|
if (base === 'rgb') return parseFloat(x) * 255 / 100
|
||||||
|
return parseFloat(x)
|
||||||
|
}
|
||||||
|
//hue
|
||||||
|
else if (base[i] === 'h') {
|
||||||
|
//<deg>
|
||||||
|
if (/deg$/.test(x)) {
|
||||||
|
return parseFloat(x)
|
||||||
|
}
|
||||||
|
//<base-hue>
|
||||||
|
else if (baseHues[x] !== undefined) {
|
||||||
|
return baseHues[x]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parseFloat(x)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (name === base) parts.push(1)
|
||||||
|
alpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]
|
||||||
|
parts = parts.slice(0, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
//named channels case
|
||||||
|
else if (cstr.length > 10 && /[0-9](?:\s|\/)/.test(cstr)) {
|
||||||
|
parts = cstr.match(/([0-9]+)/g).map(function (value) {
|
||||||
|
return parseFloat(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
space = cstr.match(/([a-z])/ig).join('').toLowerCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//numeric case
|
||||||
|
else if (!isNaN(cstr)) {
|
||||||
|
space = 'rgb'
|
||||||
|
parts = [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff]
|
||||||
|
}
|
||||||
|
|
||||||
|
//array-like
|
||||||
|
else if (Array.isArray(cstr) || cstr.length) {
|
||||||
|
parts = [cstr[0], cstr[1], cstr[2]]
|
||||||
|
space = 'rgb'
|
||||||
|
alpha = cstr.length === 4 ? cstr[3] : 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//object case - detects css cases of rgb and hsl
|
||||||
|
else if (cstr instanceof Object) {
|
||||||
|
if (cstr.r != null || cstr.red != null || cstr.R != null) {
|
||||||
|
space = 'rgb'
|
||||||
|
parts = [
|
||||||
|
cstr.r || cstr.red || cstr.R || 0,
|
||||||
|
cstr.g || cstr.green || cstr.G || 0,
|
||||||
|
cstr.b || cstr.blue || cstr.B || 0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
space = 'hsl'
|
||||||
|
parts = [
|
||||||
|
cstr.h || cstr.hue || cstr.H || 0,
|
||||||
|
cstr.s || cstr.saturation || cstr.S || 0,
|
||||||
|
cstr.l || cstr.lightness || cstr.L || cstr.b || cstr.brightness
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha = cstr.a || cstr.alpha || cstr.opacity || 1
|
||||||
|
|
||||||
|
if (cstr.opacity != null) alpha /= 100
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
space: space,
|
||||||
|
values: parts,
|
||||||
|
alpha: alpha
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "color-parse",
|
||||||
|
"version": "1.4.2",
|
||||||
|
"description": "Color string parser",
|
||||||
|
"main": "index.js",
|
||||||
|
"browser": "index.js",
|
||||||
|
"module": "./index.mjs",
|
||||||
|
"exports": {
|
||||||
|
"require": "./index.js",
|
||||||
|
"import": "./index.mjs"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test.mjs"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/colorjs/color-parse"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"color",
|
||||||
|
"parse",
|
||||||
|
"color-parse",
|
||||||
|
"color-string"
|
||||||
|
],
|
||||||
|
"author": "Deema Ywanov <df.creative@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/colorjs/color-parse/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/colorjs/color-parse",
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "^1.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"tape": "^4.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
# color-parse [](https://travis-ci.org/colorjs/color-parse) [](https://bundlephobia.com/result?p=color-parse) 
|
||||||
|
|
||||||
|
Fast and compact color string parser.
|
||||||
|
|
||||||
|
`$ npm install color-parse`
|
||||||
|
|
||||||
|
```js
|
||||||
|
var parse = require('color-parse')
|
||||||
|
|
||||||
|
parse('hsla(12 10% 50% / .3)')
|
||||||
|
// { space: 'hsl', values: [12, 10, 50], alpha: 0.3 }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parsed strings
|
||||||
|
|
||||||
|
* [x] Color keywords: `red`, `green` etc., see [color-name](https://ghub.io/color-name)
|
||||||
|
* [x] `#RGB[A]`
|
||||||
|
* [x] `#RRGGBB[AA]`
|
||||||
|
* [x] `rgb[a](R, G, B[, A])`
|
||||||
|
* [x] `rgb[a](R G B[ / A])`
|
||||||
|
* [x] `hsl[a](H, S, L[, A])`, inc. [named hues](http://dev.w3.org/csswg/css-color/#simple-hues)
|
||||||
|
* [x] `hsl[a](H S L [ / A])`
|
||||||
|
* [x] `hwb(H, W, B)`
|
||||||
|
* [x] `cmyk(C, M, Y, K)`
|
||||||
|
* [x] `xyz(X, Y, Z)`
|
||||||
|
* [x] `lab(L, A, B)`
|
||||||
|
* [x] `lch(L, C, H)`
|
||||||
|
* [x] `luv(L, U, V)`
|
||||||
|
* [x] `R:10 G:20 B:30`
|
||||||
|
* [x] `(R10 / G20 / B30)`
|
||||||
|
* [x] `C100/M80/Y0/K35`
|
||||||
|
|
||||||
|
## Parsed not strings
|
||||||
|
|
||||||
|
* [x] `[10, 20, 20]` as RGB color space
|
||||||
|
* [x] `{r: 10, g: 20, b: 30}`
|
||||||
|
* [x] `{red: 10, green: 20, blue: 30}`
|
||||||
|
* [x] `{h: 10, s: 20, l: 30}`
|
||||||
|
* [x] `0x00ff00`, `0x0000ff` numbers
|
||||||
|
|
||||||
|
## Not parsed strings
|
||||||
|
|
||||||
|
* [x] `'yellowblue'` returns `null`
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
* [color-space](https://npmjs.org/package/color-space) — collection of color space conversions.
|
||||||
|
* [color-rgba](https://npmjs.org/package/color-rgba) — convert any color string to rgba array.
|
||||||
|
* [color-alpha](https://npmjs.org/package/color-alpha) — change alpha component of any color.
|
||||||
|
|
||||||
|
## Analogs
|
||||||
|
|
||||||
|
* [parse-color](http://npmjs.org/package/parse-color) — parser by @substack. Performs calculations to every possible space, which bloats size.
|
||||||
|
* [color-parser](http://npmjs.org/package/color-parser) — parser by @tjholowaychuk. Supports limited set of spaces.
|
||||||
|
* [color-string](http://npmjs.org/package/color-string) — parsing/serializing module by Heather Arthur. Has extensive API for parsing and serializing from any to any space.
|
||||||
|
|
||||||
|
|
||||||
|
[](https://nodei.co/npm/color-parse/)
|
||||||
|
|
@ -0,0 +1,444 @@
|
||||||
|
import parse from './index.mjs'
|
||||||
|
import t from 'tape'
|
||||||
|
|
||||||
|
/** parse-color tests */
|
||||||
|
|
||||||
|
t('#ffa500', function (t) {
|
||||||
|
t.deepEqual(parse('#ffa500'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [ 255, 165, 0 ],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('#333', function (t) {
|
||||||
|
t.deepEqual(parse('#333'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [ 51, 51, 51 ],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('#f98', function (t) {
|
||||||
|
t.deepEqual(parse('#f98'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [ 255, 153, 136 ],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('lime', function (t) {
|
||||||
|
t.deepEqual(parse('lime'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [ 0, 255, 0 ],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsl(210,50,50)', function (t) {
|
||||||
|
t.deepEqual(parse('hsl(210,50,50)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [ 210, 50, 50 ],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(153,50,204,60%)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(153,50,204,60%)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [ 153, 50, 204 ],
|
||||||
|
alpha: 0.6
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
t('#fef', function (t) {
|
||||||
|
t.deepEqual(parse('#fef'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [255, 238, 255],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('#fffFEF', function (t) {
|
||||||
|
t.deepEqual(parse('#fffFEF'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [255, 255, 239],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgb(244, 233, 100)', function (t) {
|
||||||
|
t.deepEqual(parse('rgb(244, 233, 100)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [244, 233, 100],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgb(100%, 30%, 90%)', function (t) {
|
||||||
|
t.deepEqual(parse('rgb(100%, 30%, 90%)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [255, 76.5, 229.5],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('transparent', function (t) {
|
||||||
|
t.deepEqual(parse('transparent'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [0, 0, 0],
|
||||||
|
alpha: 0
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsl(240, 100%, 50.5%)', function (t) {
|
||||||
|
t.deepEqual(parse('hsl(240, 100%, 50.5%)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [240, 100, 50.5],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsl(240deg, 100%, 50.5%)', function (t) {
|
||||||
|
t.deepEqual(parse('hsl(240deg, 100%, 50.5%)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [240, 100, 50.5],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hwb(240, 100%, 50.5%)', function (t) {
|
||||||
|
t.deepEqual(parse('hwb(240, 100%, 50.5%)'), {
|
||||||
|
space: 'hwb',
|
||||||
|
values: [240, 100, 50.5],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hwb(240deg, 100%, 50.5%)', function (t) {
|
||||||
|
t.deepEqual(parse('hwb(240deg, 100%, 50.5%)'), {
|
||||||
|
space: 'hwb',
|
||||||
|
values: [240, 100, 50.5],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('blue', function (t) {
|
||||||
|
t.deepEqual(parse('blue'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [0, 0, 255],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgb(244, 233, 100)', function (t) {
|
||||||
|
t.deepEqual(parse('rgb(244, 233, 100)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [244, 233, 100],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(244, 233, 100, 0.5)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(244, 233, 100, 0.5)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [244, 233, 100],
|
||||||
|
alpha: 0.5
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsla(244, 100%, 100%, 0.6)', function (t) {
|
||||||
|
t.deepEqual(parse('hsla(244, 100%, 100%, 0.6)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [244, 100, 100],
|
||||||
|
alpha: 0.6
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hwb(244, 100%, 100%, 0.6)', function (t) {
|
||||||
|
t.deepEqual(parse('hwb(244, 100%, 100%, 0.6)'), {
|
||||||
|
space: 'hwb',
|
||||||
|
values: [244, 100, 100],
|
||||||
|
alpha: 0.6
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hwb(244, 100%, 100%)', function (t) {
|
||||||
|
t.deepEqual(parse('hwb(244, 100%, 100%)'), {
|
||||||
|
space: 'hwb',
|
||||||
|
values: [244, 100, 100],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(200, 20, 233, 0.2)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(200, 20, 233, 0.2)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [200, 20, 233],
|
||||||
|
alpha: 0.2
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(200, 20, 233, 0)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(200, 20, 233, 0)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [200, 20, 233],
|
||||||
|
alpha: 0
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(100%, 30%, 90%, 0.2)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(100%, 30%, 90%, 0.2)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [255, 76.5, 229.5],
|
||||||
|
alpha: 0.2
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(200 20 233 / 0.2)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(200, 20, 233, 0.2)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [200, 20, 233],
|
||||||
|
alpha: 0.2
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(200 20 233 / 20%)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(200, 20, 233, 0.2)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [200, 20, 233],
|
||||||
|
alpha: 0.2
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsla(200, 20%, 33%, 0.2)', function (t) {
|
||||||
|
t.deepEqual(parse('hsla(200, 20%, 33%, 0.2)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [200, 20, 33],
|
||||||
|
alpha: 0.2
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hwb(200, 20%, 33%, 0.2)', function (t) {
|
||||||
|
t.deepEqual(parse('hwb(200, 20%, 33%, 0.2)'), {
|
||||||
|
space: 'hwb',
|
||||||
|
values: [200, 20, 33],
|
||||||
|
alpha: 0.2
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(200, 20, 233, 0.2)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(200, 20, 233, 0.2)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [200, 20, 233],
|
||||||
|
alpha: 0.2
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
t('rgba(300, 600, 100, 3)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(300, 600, 100, 3)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [300, 600, 100],
|
||||||
|
alpha: 3
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('rgba(8000%, 100%, 333%, 88)', function (t) {
|
||||||
|
t.deepEqual(parse('rgba(8000%, 100%, 333%, 88)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [20400, 255, 849.15],
|
||||||
|
alpha: 88
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsla(400, 10%, 200%, 10)', function (t) {
|
||||||
|
t.deepEqual(parse('hsla(400, 10%, 200%, 10)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [400, 10, 200],
|
||||||
|
alpha: 10
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hwb(400, 10%, 200%, 10)', function (t) {
|
||||||
|
t.deepEqual(parse('hwb(400, 10%, 200%, 10)'), {
|
||||||
|
space: 'hwb',
|
||||||
|
values: [400, 10, 200],
|
||||||
|
alpha: 10
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('yellowblue', function (t) {
|
||||||
|
t.deepEqual(parse('yellowblue'), {space: undefined, values: [], alpha: 1});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
t('hsla(101.12, 45.2%, 21.0%, 1.0)', function (t) {
|
||||||
|
t.deepEqual(parse('hsla(101.12, 45.2%, 21.0%, 1.0)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [101.12,45.2,21.0],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsla(101.12 45.2% 21.0% / 50%)', function (t) {
|
||||||
|
t.deepEqual(parse('hsla(101.12 45.2% 21.0% / 50%)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [101.12,45.2,21.0],
|
||||||
|
alpha: .5
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsl(red, 10%, 10%)', function (t) {
|
||||||
|
t.deepEqual(parse('hsl(red, 10%, 10%)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [0,10,10],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsl(red, 10%, 10%);', function (t) {
|
||||||
|
t.deepEqual(parse('hsl(red, 10%, 10%);'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [0,10,10],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('hsl(10deg, 10%, 10%)', function (t) {
|
||||||
|
t.deepEqual(parse('hsl(10deg, 10%, 10%)'), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [10,10,10],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('lch(5, 5, orange)', function (t) {
|
||||||
|
t.deepEqual(parse('lch(5, 5, orange)'), {
|
||||||
|
space: 'lch',
|
||||||
|
values: [5,5,60],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('#afd6', function (t) {
|
||||||
|
t.deepEqual(parse('#afd6'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [170,255,221],
|
||||||
|
alpha: 0.4
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('#AFD6', function (t) {
|
||||||
|
t.deepEqual(parse('#afd6'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [170,255,221],
|
||||||
|
alpha: 0.4
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('#aaffdd66', function (t) {
|
||||||
|
t.deepEqual(parse('#aaffdd66'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [170,255,221],
|
||||||
|
alpha: 0.4
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('#AAFFDD66', function (t) {
|
||||||
|
t.deepEqual(parse('#AAFFDD66'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [170,255,221],
|
||||||
|
alpha: 0.4
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('(R12 / G45 / B234)', function (t) {
|
||||||
|
t.deepEqual(parse('(R12 / G45 / B234)'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [12, 45, 234],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('R:12 G:45 B:234', function (t) {
|
||||||
|
t.deepEqual(parse('R:12 G:45 B:234'), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [12, 45, 234],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('C100/M80/Y0/K35', function (t) {
|
||||||
|
t.deepEqual(parse('C100/M80/Y0/K35'), {
|
||||||
|
space: 'cmyk',
|
||||||
|
values: [100, 80, 0, 35],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('Array', function (t) {
|
||||||
|
t.deepEqual(parse([1,2,3]), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [1,2,3],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('Object', function (t) {
|
||||||
|
t.deepEqual(parse({r:1,g:2,b:3}), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [1,2,3],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.deepEqual(parse({red:1,green:2,blue:3}), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [1,2,3],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.deepEqual(parse({h:1,s:2,l:3}), {
|
||||||
|
space: 'hsl',
|
||||||
|
values: [1,2,3],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
t('Number', function (t) {
|
||||||
|
t.deepEqual(parse(0xA141E), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [10,20,30],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.deepEqual(parse(0xff), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [0x00,0x00,0xff],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.deepEqual(parse(0xff0000), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [0xff,0x00,0x00],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.deepEqual(parse(0x0000ff), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [0x00,0x00,0xff],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.deepEqual(parse(new Number(0x0000ff)), {
|
||||||
|
space: 'rgb',
|
||||||
|
values: [0x00,0x00,0xff],
|
||||||
|
alpha: 1
|
||||||
|
});
|
||||||
|
t.end()
|
||||||
|
});
|
||||||
|
|
@ -9,11 +9,12 @@ These plugins can lint your CSS, support variables and mixins,
|
||||||
transpile future CSS syntax, inline images, and more.
|
transpile future CSS syntax, inline images, and more.
|
||||||
|
|
||||||
PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba,
|
PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba,
|
||||||
and JetBrains. The [Autoprefixer] and [Stylelint] PostCSS plugins is one of the most popular CSS tools.
|
and JetBrains. The [Autoprefixer] and [Stylelint] PostCSS plugins are some of the most popular CSS tools.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<img src="https://cdn.evilmartians.com/badges/logo-no-label.svg" alt="" width="22" height="16" /> Made at <b><a href="https://evilmartians.com/devtools?utm_source=postcss&utm_campaign=devtools-button&utm_medium=github">Evil Martians</a></b>, product consulting for <b>developer tools</b>.
|
<img src="https://cdn.evilmartians.com/badges/logo-no-label.svg" alt="" width="22" height="16" /> Built by
|
||||||
|
<b><a href="https://evilmartians.com/devtools?utm_source=postcss&utm_campaign=devtools-button&utm_medium=github">Evil Martians</a></b>, go-to agency for <b>developer tools</b>.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,17 @@ import AtRule from './at-rule.js'
|
||||||
import Comment from './comment.js'
|
import Comment from './comment.js'
|
||||||
import Declaration from './declaration.js'
|
import Declaration from './declaration.js'
|
||||||
import Node, { ChildNode, ChildProps, NodeProps } from './node.js'
|
import Node, { ChildNode, ChildProps, NodeProps } from './node.js'
|
||||||
|
import { Root } from './postcss.js'
|
||||||
import Rule from './rule.js'
|
import Rule from './rule.js'
|
||||||
|
|
||||||
declare namespace Container {
|
declare namespace Container {
|
||||||
export class ContainerWithChildren<
|
export type ContainerWithChildren<Child extends Node = ChildNode> = {
|
||||||
Child extends Node = ChildNode
|
|
||||||
> extends Container_<Child> {
|
|
||||||
nodes: Child[]
|
nodes: Child[]
|
||||||
}
|
} & (
|
||||||
|
| AtRule
|
||||||
|
| Root
|
||||||
|
| Rule
|
||||||
|
)
|
||||||
|
|
||||||
export interface ValueOptions {
|
export interface ValueOptions {
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,11 @@ declare namespace Input {
|
||||||
*/
|
*/
|
||||||
endLine?: number
|
endLine?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset of exclusive end position in source file.
|
||||||
|
*/
|
||||||
|
endOffset?: number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Absolute path to the source file.
|
* Absolute path to the source file.
|
||||||
*/
|
*/
|
||||||
|
|
@ -28,6 +33,11 @@ declare namespace Input {
|
||||||
*/
|
*/
|
||||||
line: number
|
line: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset of inclusive start position in source file.
|
||||||
|
*/
|
||||||
|
offset: number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source code.
|
* Source code.
|
||||||
*/
|
*/
|
||||||
|
|
@ -131,6 +141,9 @@ declare class Input_ {
|
||||||
*/
|
*/
|
||||||
constructor(css: string, opts?: ProcessOptions)
|
constructor(css: string, opts?: ProcessOptions)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `CssSyntaxError` with information about the error and its position.
|
||||||
|
*/
|
||||||
error(
|
error(
|
||||||
message: string,
|
message: string,
|
||||||
start:
|
start:
|
||||||
|
|
@ -151,9 +164,6 @@ declare class Input_ {
|
||||||
},
|
},
|
||||||
opts?: { plugin?: CssSyntaxError['plugin'] }
|
opts?: { plugin?: CssSyntaxError['plugin'] }
|
||||||
): CssSyntaxError
|
): CssSyntaxError
|
||||||
/**
|
|
||||||
* Returns `CssSyntaxError` with information about the error and its position.
|
|
||||||
*/
|
|
||||||
error(
|
error(
|
||||||
message: string,
|
message: string,
|
||||||
line: number,
|
line: number,
|
||||||
|
|
@ -165,12 +175,23 @@ declare class Input_ {
|
||||||
offset: number,
|
offset: number,
|
||||||
opts?: { plugin?: CssSyntaxError['plugin'] }
|
opts?: { plugin?: CssSyntaxError['plugin'] }
|
||||||
): CssSyntaxError
|
): CssSyntaxError
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts source line and column to offset.
|
||||||
|
*
|
||||||
|
* @param line Source line.
|
||||||
|
* @param column Source column.
|
||||||
|
* @return Source offset.
|
||||||
|
*/
|
||||||
|
fromLineAndColumn(line: number, column: number): number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts source offset to line and column.
|
* Converts source offset to line and column.
|
||||||
*
|
*
|
||||||
* @param offset Source offset.
|
* @param offset Source offset.
|
||||||
*/
|
*/
|
||||||
fromOffset(offset: number): { col: number; line: number } | null
|
fromOffset(offset: number): { col: number; line: number } | null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the input source map and returns a symbol position
|
* Reads the input source map and returns a symbol position
|
||||||
* in the input source (e.g., in a Sass file that was compiled
|
* in the input source (e.g., in a Sass file that was compiled
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,26 @@ let CssSyntaxError = require('./css-syntax-error')
|
||||||
let PreviousMap = require('./previous-map')
|
let PreviousMap = require('./previous-map')
|
||||||
let terminalHighlight = require('./terminal-highlight')
|
let terminalHighlight = require('./terminal-highlight')
|
||||||
|
|
||||||
let fromOffsetCache = Symbol('fromOffsetCache')
|
let lineToIndexCache = Symbol('lineToIndexCache')
|
||||||
|
|
||||||
let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator)
|
let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator)
|
||||||
let pathAvailable = Boolean(resolve && isAbsolute)
|
let pathAvailable = Boolean(resolve && isAbsolute)
|
||||||
|
|
||||||
|
function getLineToIndex(input) {
|
||||||
|
if (input[lineToIndexCache]) return input[lineToIndexCache]
|
||||||
|
let lines = input.css.split('\n')
|
||||||
|
let lineToIndex = new Array(lines.length)
|
||||||
|
let prevIndex = 0
|
||||||
|
|
||||||
|
for (let i = 0, l = lines.length; i < l; i++) {
|
||||||
|
lineToIndex[i] = prevIndex
|
||||||
|
prevIndex += lines[i].length + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
input[lineToIndexCache] = lineToIndex
|
||||||
|
return lineToIndex
|
||||||
|
}
|
||||||
|
|
||||||
class Input {
|
class Input {
|
||||||
get from() {
|
get from() {
|
||||||
return this.file || this.id
|
return this.file || this.id
|
||||||
|
|
@ -68,31 +83,38 @@ class Input {
|
||||||
}
|
}
|
||||||
|
|
||||||
error(message, line, column, opts = {}) {
|
error(message, line, column, opts = {}) {
|
||||||
let endColumn, endLine, result
|
let endColumn, endLine, endOffset, offset, result
|
||||||
|
|
||||||
if (line && typeof line === 'object') {
|
if (line && typeof line === 'object') {
|
||||||
let start = line
|
let start = line
|
||||||
let end = column
|
let end = column
|
||||||
if (typeof start.offset === 'number') {
|
if (typeof start.offset === 'number') {
|
||||||
let pos = this.fromOffset(start.offset)
|
offset = start.offset
|
||||||
|
let pos = this.fromOffset(offset)
|
||||||
line = pos.line
|
line = pos.line
|
||||||
column = pos.col
|
column = pos.col
|
||||||
} else {
|
} else {
|
||||||
line = start.line
|
line = start.line
|
||||||
column = start.column
|
column = start.column
|
||||||
|
offset = this.fromLineAndColumn(line, column)
|
||||||
}
|
}
|
||||||
if (typeof end.offset === 'number') {
|
if (typeof end.offset === 'number') {
|
||||||
let pos = this.fromOffset(end.offset)
|
endOffset = end.offset
|
||||||
|
let pos = this.fromOffset(endOffset)
|
||||||
endLine = pos.line
|
endLine = pos.line
|
||||||
endColumn = pos.col
|
endColumn = pos.col
|
||||||
} else {
|
} else {
|
||||||
endLine = end.line
|
endLine = end.line
|
||||||
endColumn = end.column
|
endColumn = end.column
|
||||||
|
endOffset = this.fromLineAndColumn(end.line, end.column)
|
||||||
}
|
}
|
||||||
} else if (!column) {
|
} else if (!column) {
|
||||||
let pos = this.fromOffset(line)
|
offset = line
|
||||||
|
let pos = this.fromOffset(offset)
|
||||||
line = pos.line
|
line = pos.line
|
||||||
column = pos.col
|
column = pos.col
|
||||||
|
} else {
|
||||||
|
offset = this.fromLineAndColumn(line, column)
|
||||||
}
|
}
|
||||||
|
|
||||||
let origin = this.origin(line, column, endLine, endColumn)
|
let origin = this.origin(line, column, endLine, endColumn)
|
||||||
|
|
@ -120,7 +142,7 @@ class Input {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.input = { column, endColumn, endLine, line, source: this.css }
|
result.input = { column, endColumn, endLine, endOffset, line, offset, source: this.css }
|
||||||
if (this.file) {
|
if (this.file) {
|
||||||
if (pathToFileURL) {
|
if (pathToFileURL) {
|
||||||
result.input.url = pathToFileURL(this.file).toString()
|
result.input.url = pathToFileURL(this.file).toString()
|
||||||
|
|
@ -131,23 +153,15 @@ class Input {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fromLineAndColumn(line, column) {
|
||||||
|
let lineToIndex = getLineToIndex(this)
|
||||||
|
let index = lineToIndex[line - 1]
|
||||||
|
return index + column - 1
|
||||||
|
}
|
||||||
|
|
||||||
fromOffset(offset) {
|
fromOffset(offset) {
|
||||||
let lastLine, lineToIndex
|
let lineToIndex = getLineToIndex(this)
|
||||||
if (!this[fromOffsetCache]) {
|
let lastLine = lineToIndex[lineToIndex.length - 1]
|
||||||
let lines = this.css.split('\n')
|
|
||||||
lineToIndex = new Array(lines.length)
|
|
||||||
let prevIndex = 0
|
|
||||||
|
|
||||||
for (let i = 0, l = lines.length; i < l; i++) {
|
|
||||||
lineToIndex[i] = prevIndex
|
|
||||||
prevIndex += lines[i].length + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
this[fromOffsetCache] = lineToIndex
|
|
||||||
} else {
|
|
||||||
lineToIndex = this[fromOffsetCache]
|
|
||||||
}
|
|
||||||
lastLine = lineToIndex[lineToIndex.length - 1]
|
|
||||||
|
|
||||||
let min = 0
|
let min = 0
|
||||||
if (offset >= lastLine) {
|
if (offset >= lastLine) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import AtRule = require('./at-rule.js')
|
import AtRule = require('./at-rule.js')
|
||||||
|
|
||||||
import { AtRuleProps } from './at-rule.js'
|
import { AtRuleProps } from './at-rule.js'
|
||||||
import Comment, { CommentProps } from './comment.js'
|
import Comment, { CommentProps } from './comment.js'
|
||||||
import Container, { NewChild } from './container.js'
|
import Container, { NewChild } from './container.js'
|
||||||
|
|
@ -66,6 +65,22 @@ declare namespace Node {
|
||||||
/**
|
/**
|
||||||
* The inclusive ending position for the source
|
* The inclusive ending position for the source
|
||||||
* code of a node.
|
* code of a node.
|
||||||
|
*
|
||||||
|
* However, `end.offset` of a non `Root` node is the exclusive position.
|
||||||
|
* See https://github.com/postcss/postcss/pull/1879 for details.
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* const root = postcss.parse('a { color: black }')
|
||||||
|
* const a = root.first
|
||||||
|
* const color = a.first
|
||||||
|
*
|
||||||
|
* // The offset of `Root` node is the inclusive position
|
||||||
|
* css.source.end // { line: 1, column: 19, offset: 18 }
|
||||||
|
*
|
||||||
|
* // The offset of non `Root` node is the exclusive position
|
||||||
|
* a.source.end // { line: 1, column: 18, offset: 18 }
|
||||||
|
* color.source.end // { line: 1, column: 16, offset: 16 }
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
end?: Position
|
end?: Position
|
||||||
|
|
||||||
|
|
@ -424,7 +439,7 @@ declare abstract class Node_ {
|
||||||
* @return Range.
|
* @return Range.
|
||||||
*/
|
*/
|
||||||
rangeBy(
|
rangeBy(
|
||||||
opts?: Pick<WarningOptions, 'endIndex' | 'index' | 'word'>
|
opts?: Pick<WarningOptions, 'end' | 'endIndex' | 'index' | 'start' | 'word'>
|
||||||
): Node.Range
|
): Node.Range
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,8 @@ function cloneNode(obj, parent) {
|
||||||
|
|
||||||
function sourceOffset(inputCSS, position) {
|
function sourceOffset(inputCSS, position) {
|
||||||
// Not all custom syntaxes support `offset` in `source.start` and `source.end`
|
// Not all custom syntaxes support `offset` in `source.start` and `source.end`
|
||||||
if (
|
if (position && typeof position.offset !== 'undefined') {
|
||||||
position &&
|
return position.offset
|
||||||
typeof position.offset !== 'undefined'
|
|
||||||
) {
|
|
||||||
return position.offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let column = 1
|
let column = 1
|
||||||
|
|
@ -208,14 +205,15 @@ class Node {
|
||||||
return this.parent.nodes[index + 1]
|
return this.parent.nodes[index + 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
positionBy(opts) {
|
positionBy(opts = {}) {
|
||||||
let pos = this.source.start
|
let pos = this.source.start
|
||||||
if (opts.index) {
|
if (opts.index) {
|
||||||
pos = this.positionInside(opts.index)
|
pos = this.positionInside(opts.index)
|
||||||
} else if (opts.word) {
|
} else if (opts.word) {
|
||||||
let inputString = ('document' in this.source.input)
|
let inputString =
|
||||||
? this.source.input.document
|
'document' in this.source.input
|
||||||
: this.source.input.css
|
? this.source.input.document
|
||||||
|
: this.source.input.css
|
||||||
let stringRepresentation = inputString.slice(
|
let stringRepresentation = inputString.slice(
|
||||||
sourceOffset(inputString, this.source.start),
|
sourceOffset(inputString, this.source.start),
|
||||||
sourceOffset(inputString, this.source.end)
|
sourceOffset(inputString, this.source.end)
|
||||||
|
|
@ -229,9 +227,10 @@ class Node {
|
||||||
positionInside(index) {
|
positionInside(index) {
|
||||||
let column = this.source.start.column
|
let column = this.source.start.column
|
||||||
let line = this.source.start.line
|
let line = this.source.start.line
|
||||||
let inputString = ('document' in this.source.input)
|
let inputString =
|
||||||
? this.source.input.document
|
'document' in this.source.input
|
||||||
: this.source.input.css
|
? this.source.input.document
|
||||||
|
: this.source.input.css
|
||||||
let offset = sourceOffset(inputString, this.source.start)
|
let offset = sourceOffset(inputString, this.source.start)
|
||||||
let end = offset + index
|
let end = offset + index
|
||||||
|
|
||||||
|
|
@ -244,7 +243,7 @@ class Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { column, line }
|
return { column, line, offset: end }
|
||||||
}
|
}
|
||||||
|
|
||||||
prev() {
|
prev() {
|
||||||
|
|
@ -253,25 +252,36 @@ class Node {
|
||||||
return this.parent.nodes[index - 1]
|
return this.parent.nodes[index - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
rangeBy(opts) {
|
rangeBy(opts = {}) {
|
||||||
|
let inputString =
|
||||||
|
'document' in this.source.input
|
||||||
|
? this.source.input.document
|
||||||
|
: this.source.input.css
|
||||||
let start = {
|
let start = {
|
||||||
column: this.source.start.column,
|
column: this.source.start.column,
|
||||||
line: this.source.start.line
|
line: this.source.start.line,
|
||||||
|
offset: sourceOffset(inputString, this.source.start)
|
||||||
}
|
}
|
||||||
let end = this.source.end
|
let end = this.source.end
|
||||||
? {
|
? {
|
||||||
column: this.source.end.column + 1,
|
column: this.source.end.column + 1,
|
||||||
line: this.source.end.line
|
line: this.source.end.line,
|
||||||
|
offset:
|
||||||
|
typeof this.source.end.offset === 'number'
|
||||||
|
? // `source.end.offset` is exclusive, so we don't need to add 1
|
||||||
|
this.source.end.offset
|
||||||
|
: // Since line/column in this.source.end is inclusive,
|
||||||
|
// the `sourceOffset(... , this.source.end)` returns an inclusive offset.
|
||||||
|
// So, we add 1 to convert it to exclusive.
|
||||||
|
sourceOffset(inputString, this.source.end) + 1
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
column: start.column + 1,
|
column: start.column + 1,
|
||||||
line: start.line
|
line: start.line,
|
||||||
|
offset: start.offset + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.word) {
|
if (opts.word) {
|
||||||
let inputString = ('document' in this.source.input)
|
|
||||||
? this.source.input.document
|
|
||||||
: this.source.input.css
|
|
||||||
let stringRepresentation = inputString.slice(
|
let stringRepresentation = inputString.slice(
|
||||||
sourceOffset(inputString, this.source.start),
|
sourceOffset(inputString, this.source.start),
|
||||||
sourceOffset(inputString, this.source.end)
|
sourceOffset(inputString, this.source.end)
|
||||||
|
|
@ -279,15 +289,14 @@ class Node {
|
||||||
let index = stringRepresentation.indexOf(opts.word)
|
let index = stringRepresentation.indexOf(opts.word)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
start = this.positionInside(index)
|
start = this.positionInside(index)
|
||||||
end = this.positionInside(
|
end = this.positionInside(index + opts.word.length)
|
||||||
index + opts.word.length,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (opts.start) {
|
if (opts.start) {
|
||||||
start = {
|
start = {
|
||||||
column: opts.start.column,
|
column: opts.start.column,
|
||||||
line: opts.start.line
|
line: opts.start.line,
|
||||||
|
offset: sourceOffset(inputString, opts.start)
|
||||||
}
|
}
|
||||||
} else if (opts.index) {
|
} else if (opts.index) {
|
||||||
start = this.positionInside(opts.index)
|
start = this.positionInside(opts.index)
|
||||||
|
|
@ -296,7 +305,8 @@ class Node {
|
||||||
if (opts.end) {
|
if (opts.end) {
|
||||||
end = {
|
end = {
|
||||||
column: opts.end.column,
|
column: opts.end.column,
|
||||||
line: opts.end.line
|
line: opts.end.line,
|
||||||
|
offset: sourceOffset(inputString, opts.end)
|
||||||
}
|
}
|
||||||
} else if (typeof opts.endIndex === 'number') {
|
} else if (typeof opts.endIndex === 'number') {
|
||||||
end = this.positionInside(opts.endIndex)
|
end = this.positionInside(opts.endIndex)
|
||||||
|
|
@ -309,7 +319,11 @@ class Node {
|
||||||
end.line < start.line ||
|
end.line < start.line ||
|
||||||
(end.line === start.line && end.column <= start.column)
|
(end.line === start.line && end.column <= start.column)
|
||||||
) {
|
) {
|
||||||
end = { column: start.column + 1, line: start.line }
|
end = {
|
||||||
|
column: start.column + 1,
|
||||||
|
line: start.line,
|
||||||
|
offset: start.offset + 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { end, start }
|
return { end, start }
|
||||||
|
|
@ -384,6 +398,7 @@ class Node {
|
||||||
} else if (typeof value === 'object' && value.toJSON) {
|
} else if (typeof value === 'object' && value.toJSON) {
|
||||||
fixed[name] = value.toJSON(null, inputs)
|
fixed[name] = value.toJSON(null, inputs)
|
||||||
} else if (name === 'source') {
|
} else if (name === 'source') {
|
||||||
|
if (value == null) continue
|
||||||
let inputId = inputs.get(value.input)
|
let inputId = inputs.get(value.input)
|
||||||
if (inputId == null) {
|
if (inputId == null) {
|
||||||
inputId = inputsNextIndex
|
inputId = inputsNextIndex
|
||||||
|
|
@ -423,7 +438,7 @@ class Node {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
warn(result, text, opts) {
|
warn(result, text, opts = {}) {
|
||||||
let data = { node: this }
|
let data = { node: this }
|
||||||
for (let i in opts) data[i] = opts[i]
|
for (let i in opts) data[i] = opts[i]
|
||||||
return result.warn(text, data)
|
return result.warn(text, data)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ let Root = require('./root')
|
||||||
|
|
||||||
class Processor {
|
class Processor {
|
||||||
constructor(plugins = []) {
|
constructor(plugins = []) {
|
||||||
this.version = '8.5.3'
|
this.version = '8.5.6'
|
||||||
this.plugins = this.normalize(plugins)
|
this.plugins = this.normalize(plugins)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class Result {
|
||||||
this.messages = []
|
this.messages = []
|
||||||
this.root = root
|
this.root = root
|
||||||
this.opts = opts
|
this.opts = opts
|
||||||
this.css = undefined
|
this.css = ''
|
||||||
this.map = undefined
|
this.map = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ declare class Stringifier_ {
|
||||||
comment(node: Comment): void
|
comment(node: Comment): void
|
||||||
decl(node: Declaration, semicolon?: boolean): void
|
decl(node: Declaration, semicolon?: boolean): void
|
||||||
document(node: Document): void
|
document(node: Document): void
|
||||||
raw(node: AnyNode, own: null | string, detect?: string): string
|
raw(node: AnyNode, own: null | string, detect?: string): boolean | string
|
||||||
rawBeforeClose(root: Root): string | undefined
|
rawBeforeClose(root: Root): string | undefined
|
||||||
rawBeforeComment(root: Root, node: Comment): string | undefined
|
rawBeforeComment(root: Root, node: Comment): string | undefined
|
||||||
rawBeforeDecl(root: Root, node: Declaration): string | undefined
|
rawBeforeDecl(root: Root, node: Declaration): string | undefined
|
||||||
|
|
@ -35,7 +35,7 @@ declare class Stringifier_ {
|
||||||
rawEmptyBody(root: Root): string | undefined
|
rawEmptyBody(root: Root): string | undefined
|
||||||
rawIndent(root: Root): string | undefined
|
rawIndent(root: Root): string | undefined
|
||||||
rawSemicolon(root: Root): boolean | undefined
|
rawSemicolon(root: Root): boolean | undefined
|
||||||
rawValue(node: AnyNode, prop: string): string
|
rawValue(node: AnyNode, prop: string): number | string
|
||||||
root(node: Root): void
|
root(node: Root): void
|
||||||
rule(node: Rule): void
|
rule(node: Rule): void
|
||||||
stringify(node: AnyNode, semicolon?: boolean): void
|
stringify(node: AnyNode, semicolon?: boolean): void
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
{
|
{
|
||||||
"name": "postcss",
|
"name": "postcss",
|
||||||
"version": "8.5.3",
|
"version": "8.5.6",
|
||||||
"description": "Tool for transforming styles with JS plugins",
|
"description": "Tool for transforming styles with JS plugins",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"require": "./lib/postcss.js",
|
"import": "./lib/postcss.mjs",
|
||||||
"import": "./lib/postcss.mjs"
|
"require": "./lib/postcss.js"
|
||||||
},
|
},
|
||||||
"./lib/at-rule": "./lib/at-rule.js",
|
"./lib/at-rule": "./lib/at-rule.js",
|
||||||
"./lib/comment": "./lib/comment.js",
|
"./lib/comment": "./lib/comment.js",
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
"url": "https://github.com/postcss/postcss/issues"
|
"url": "https://github.com/postcss/postcss/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.8",
|
"nanoid": "^3.3.11",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue