new THREE.Color('#000000')
new THREE.Color().fromArray([0,0,0])
set: function (value) {
        if (value && value.isColor) {
                this.copy(value);
        } else if (typeof value === 'number') {
                this.setHex(value);
        } else if (typeof value === 'string') {
                this.setStyle(value);
        return this;
setHex: function (hex) {
        hex = Math.floor(hex);
        this.r = ((hex >> 16) & 255) / 255;
        this.g = ((hex >> 8) & 255) / 255;
        this.b = (hex & 255) / 255;
        return this;
setRGB: function (r, g, b) {
        this.r = r;
        this.g = g;
        this.b = b;
        return this;
setHSL: function (h, s, l) {
        // h,s,l ranges are in 0.0 - 1.0
        h = MathUtils.euclideanModulo(h, 1);
        s = MathUtils.clamp(s, 0, 1);
        l = MathUtils.clamp(l, 0, 1);
        if (s === 0) {
                this.r = this.g = this.b = l;
        } else {
                const p = l <= 0.5 ? l * (1 + s) : l + s - l * s;
                const q = 2 * l - p;
                this.r = hue2rgb(q, p, h + 1 / 3);
                this.g = hue2rgb(q, p, h);
                this.b = hue2rgb(q, p, h - 1 / 3);
        return this;
setStyle: function (style) {
        function handleAlpha(string) {
                if (string === undefined) return;
                if (parseFloat(string) < 1) {
                        console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.');
        let m;
        if ((m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(style))) {
                // rgb / hsl
                let color;
                const name = m[1];
                const components = m[2];
                switch (name) {
                        case 'rgb':
                        case 'rgba':
                                if ((color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components))) {
                                        // rgb(255,0,0) rgba(255,0,0,0.5)
                                        this.r = Math.min(255, parseInt(color[1], 10)) / 255;
                                        this.g = Math.min(255, parseInt(color[2], 10)) / 255;
                                        this.b = Math.min(255, parseInt(color[3], 10)) / 255;
                                        handleAlpha(color[5]);
                                        return this;
                                        (color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(components))
                                        // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
                                        this.r = Math.min(100, parseInt(color[1], 10)) / 100;
                                        this.g = Math.min(100, parseInt(color[2], 10)) / 100;
                                        this.b = Math.min(100, parseInt(color[3], 10)) / 100;
                                        handleAlpha(color[5]);
                                        return this;
                                break;
                        case 'hsl':
                        case 'hsla':
                                        (color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(
                                                components
                                        // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
                                        const h = parseFloat(color[1]) / 360;
                                        const s = parseInt(color[2], 10) / 100;
                                        const l = parseInt(color[3], 10) / 100;
                                        handleAlpha(color[5]);
                                        return this.setHSL(h, s, l);
                                break;
        } else if ((m = /^\#([A-Fa-f0-9]+)$/.exec(style))) {
                // hex color
                const hex = m[1];
                const size = hex.length;
                if (size === 3) {
                        // #ff0
                        this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255;
                        this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255;
                        this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255;
                        return this;
                } else if (size === 6) {
                        // #ff0000
                        this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255;
                        this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255;
                        this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255;
                        return this;
        if (style && style.length > 0) {
                return this.setColorName(style);
        return this;
setColorName: function (style) {
        // color keywords
        const hex = _colorKeywords[style];
        if (hex !== undefined) {
                // red
                this.setHex(hex);
        } else {
                // unknown color
                console.warn('THREE.Color: Unknown color ' + style);
        return this;
clone: function () {
        return new this.constructor(this.r, this.g, this.b);
copy: function (color) {
        this.r = color.r;
        this.g = color.g;
        this.b = color.b;
        return this;
copyGammaToLinear: function (color, gammaFactor) {
        if (gammaFactor === undefined) gammaFactor = 2.0;
        this.r = Math.pow(color.r, gammaFactor);
        this.g = Math.pow(color.g, gammaFactor);
        this.b = Math.pow(color.b, gammaFactor);
        return this;
copyLinearToGamma: function (color, gammaFactor) {
        if (gammaFactor === undefined) gammaFactor = 2.0;
        const safeInverse = gammaFactor > 0 ? 1.0 / gammaFactor : 1.0;
        this.r = Math.pow(color.r, safeInverse);
        this.g = Math.pow(color.g, safeInverse);
        this.b = Math.pow(color.b, safeInverse);
        return this;
convertGammaToLinear: function (gammaFactor) {
        this.copyGammaToLinear(this, gammaFactor);
        return this;
convertLinearToGamma: function (gammaFactor) {
        this.copyLinearToGamma(this, gammaFactor);
        return this;
copySRGBToLinear: function (color) {
        this.r = SRGBToLinear(color.r);
        this.g = SRGBToLinear(color.g);
        this.b = SRGBToLinear(color.b);
        return this;
copyLinearToSRGB: function (color) {
        this.r = LinearToSRGB(color.r);
        this.g = LinearToSRGB(color.g);
        this.b = LinearToSRGB(color.b);
        return this;
convertSRGBToLinear: function () {
        this.copySRGBToLinear(this);
        return this;
convertLinearToSRGB: function () {
        this.copyLinearToSRGB(this);
        return this;
getHex: function () {
        return ((this.r * 255) << 16) ^ ((this.g * 255) << 8) ^ ((this.b * 255) << 0);
getHexString: function () {
        return ('000000' + this.getHex().toString(16)).slice(-6);
getHSL: function (target) {
        // h,s,l ranges are in 0.0 - 1.0
        if (target === undefined) {
                console.warn('THREE.Color: .getHSL() target is now required');
                target = { h: 0, s: 0, l: 0 };
        const r = this.r,
                g = this.g,
                b = this.b;
        const max = Math.max(r, g, b);
        const min = Math.min(r, g, b);
        let hue, saturation;
        const lightness = (min + max) / 2.0;
        if (min === max) {
                hue = 0;
                saturation = 0;
        } else {
                const delta = max - min;
                saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
                switch (max) {
                        case r:
                                hue = (g - b) / delta + (g < b ? 6 : 0);
                                break;
                        case g:
                                hue = (b - r) / delta + 2;
                                break;
                        case b:
                                hue = (r - g) / delta + 4;
                                break;
                hue /= 6;
        target.h = hue;
        target.s = saturation;
        target.l = lightness;
        return target;
getStyle: function () {
        return 'rgb(' + ((this.r * 255) | 0) + ',' + ((this.g * 255) | 0) + ',' + ((this.b * 255) | 0) + ')';
fromArray: function (array, offset) {
        if (offset === undefined) offset = 0;
        this.r = array[offset];
        this.g = array[offset + 1];
        this.b = array[offset + 2];
        return this;
toArray: function (array, offset) {
        if (array === undefined) array = [];
        if (offset === undefined) offset = 0;
        array[offset] = this.r;
        array[offset + 1] = this.g;
        array[offset + 2] = this.b;
        return array;