text: "use strict";
  
  // Imports
  const parse = require("./parse.js");
  
  /**
   * Converts one color value to another 
   * @param {"cmyk"|"decimal"|"hex3"|"hex"|"hsl"|"hsv"|"rgb"} a Input type
   * @param {"cmyk"|"decimal"|"hex"|"hsl"|"hsv"|"rgb"} b Output type
   * @param  {...any} args Arguments
   * @returns {any}
   */
  function convert(a, b, ...args) {
      if([ a, b ].some(v => typeof v !== "string")) throw new TypeError("Argument is not a string");
      let pa = parse(a, ...args);
      if(a === b) return pa;
      let rgb = null;
      switch(a.toLowerCase()) {
          case "cmyk": {
              rgb = {
                  r: Math.max(Math.min(Math.round((1 - pa.c) * (1 - pa.k) * 255), 255), 0),
                  g: Math.max(Math.min(Math.round((1 - pa.m) * (1 - pa.k) * 255), 255), 0),
                  b: Math.max(Math.min(Math.round((1 - pa.y) * (1 - pa.k) * 255), 255), 0),
              };
              break;
          };
          case "decimal": {
              let h = pa.toString(16).padStart(6, "0");
              rgb = {
                  r: parseInt(h.slice(0, 2), 16),
                  g: parseInt(h.slice(2, 4), 16),
                  b: parseInt(h.slice(4, 6), 16)
              };
              break;
          };
          case "hex3": {
              rgb = {
                  r: parseInt(pa[0] + pa[0], 16),
                  g: parseInt(pa[1] + pa[1], 16),
                  b: parseInt(pa[2] + pa[2], 16),
              };
              break;
          };
          case "hex": {
              rgb = {
                  r: parseInt(pa.slice(0, 2), 16),
                  g: parseInt(pa.slice(2, 4), 16),
                  b: parseInt(pa.slice(4, 6), 16)
              };
              break;
          };
          case "hsl": {
              let c = (1 - Math.abs(2 * pa.l - 1)) * pa.s;
              let h = pa.h / 60;
              let x = c * (1 - Math.abs(h % 2 - 1));
              let prgb = null;
              if(h < 1) prgb = { r: c, g: x, b: 0 };
              else if(h < 2) prgb = { r: x, g: c, b: 0 };
              else if(h < 3) prgb = { r: 0, g: c, b: x };
              else if(h < 4) prgb = { r: 0, g: x, b: c };
              else if(h < 5) prgb = { r: x, g: 0, b: c };
              else if(h < 6) prgb = { r: c, g: 0, b: x };
              else prgb = { r: 0, g: 0, b: 0 };
              let m = pa.l - c / 2;
              rgb = {
                  r: Math.max(Math.min(Math.round((prgb.r + m) * 255), 255), 0),
                  g: Math.max(Math.min(Math.round((prgb.g + m) * 255), 255), 0),
                  b: Math.max(Math.min(Math.round((prgb.b + m) * 255), 255), 0),
              };
              break;
          };
          case "hsv": {
              let c = pa.v * pa.s;
              let h = pa.h / 60;
              let x = c * (1 - Math.abs(h % 2 - 1));
              let prgb = null;
              if(h <= 1) prgb = { r: c, g: x, b: 0 };
              else if(h <= 2) prgb = { r: x, g: c, b: 0 };
              else if(h <= 3) prgb = { r: 0, g: c, b: x };
              else if(h <= 4) prgb = { r: 0, g: x, b: c };
              else if(h <= 5) prgb = { r: x, g: 0, b: c };
              else if(h <= 6) prgb = { r: c, g: 0, b: x };
              let m = pa.v - c;
              rgb = {
                  r: Math.max(Math.min(Math.round((prgb.r + m) * 255), 255), 0),
                  g: Math.max(Math.min(Math.round((prgb.g + m) * 255), 255), 0),
                  b: Math.max(Math.min(Math.round((prgb.b + m) * 255), 255), 0),
              };
              break;
          };
          case "rgb": {
              rgb = pa;
              break;
          };
          default: throw new Error("Argument is not a valid type");
      };
      switch(b.toLowerCase()) {
          case "cmyk": {
              let r = rgb.r / 255;
              let g = rgb.g / 255;
              let b = rgb.b / 255;
              let k = 1 - Math.max(r, g, b);
              let c = (1 - r - k) / (1 - k);
              let m = (1 - g - k) / (1 - k);
              let y = (1 - b - k) / (1 - k);
              return {
                  c: Math.max(Math.min(parseFloat(parseFloat(c).toFixed(2)), 1), 0),
                  m: Math.max(Math.min(parseFloat(parseFloat(m).toFixed(2)), 1), 0),
                  y: Math.max(Math.min(parseFloat(parseFloat(y).toFixed(2)), 1), 0),
                  k: Math.max(Math.min(parseFloat(parseFloat(k).toFixed(2)), 1), 0),
              };
          };
          case "decimal": return rgb.r * 65536 + rgb.g * 256 + rgb.b;
          case "hex": {
              let pad = v => v.toString(16).padStart(2, "0");
              return pad(rgb.r) + pad(rgb.g) + pad(rgb.b);
          };
          case "hsl": {
              let r = rgb.r / 255;
              let g = rgb.g / 255;
              let b = rgb.b / 255;
              let xmax = Math.max(r, g, b);
              let xmin = Math.min(r, g, b);
              let c = xmax - xmin;
              let l = (xmax + xmin) / 2;
              let h = null;
              if(c === 0) h = 0;
              else if(xmax === r) h = 60 * ((g - b) / c + (g < b ? 6 : 0));
              else if(xmax === g) h = 60 * ((b - r) / c + 2);
              else if(xmax === b) h = 60 * ((r - g) / c + 4);
              else h = 0;
              let s = (l === 0 || l === 1) ? 0 : c / (1 - Math.abs(2 * xmax - c - 1));
              return {
                  h: Math.max(Math.min(Math.round(h), 360), 0),
                  s: Math.max(Math.min(parseFloat(parseFloat(s).toFixed(2)), 1), 0),
                  l: Math.max(Math.min(parseFloat(parseFloat(l).toFixed(2)), 1), 0),
              };
          };
          case "hsv": {
              let r = rgb.r / 255;
              let g = rgb.g / 255;
              let b = rgb.b / 255;
              let xmax = Math.max(r, g, b);
              let xmin = Math.min(r, g, b);
              let c = xmax - xmin;
              let h = null;
              if(c === 0) h = 0;
              else if(xmax === r) h = 60 * ((g - b) / c + (g < b ? 6 : 0));
              else if(xmax === g) h = 60 * ((b - r) / c + 2);
              else if(xmax === b) h = 60 * ((r - g) / c + 4);
              else h = 0;
              let s = xmax === 0 ? 0 : c / xmax;
              return {
                  h: Math.max(Math.min(Math.round(h), 360), 0),
                  s: Math.max(Math.min(parseFloat(parseFloat(s).toFixed(2)), 1), 0),
                  v: Math.max(Math.min(parseFloat(parseFloat(xmax).toFixed(2)), 1), 0),
              };
          };
          case "rgb": return rgb;
          default: throw new Error("Argument is not a valid type");
      };
  };
  
  // Exports
  module.exports = convert;