{"size": 3286, "ext": "js", "max_stars_repo_path": "src/helpers/color.js", "max_stars_repo_name": "adamjosefus/fast-average-color", "max_stars_repo_stars_event_min_datetime": "2018-08-05T17:32:47.000Z", "max_stars_repo_stars_event_max_datetime": "2022-03-30T18:46:11.000Z", "max_issues_repo_path": "src/helpers/color.js", "max_issues_repo_name": "adamjosefus/fast-average-color", "max_issues_repo_issues_event_min_datetime": "2018-08-09T08:50:44.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-26T12:13:38.000Z", "max_forks_repo_path": "src/helpers/color.js", "max_forks_repo_name": "adamjosefus/fast-average-color", "max_forks_repo_forks_event_min_datetime": "2018-08-05T18:41:35.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-22T10:04:28.000Z"}
{"max_stars_count": 683, "max_issues_count": 47, "max_forks_count": 50, "avg_line_length": 26.0793650794, "max_line_length": 77, "alphanum_fraction": 0.5800365186}
function toHex(num) {
    const str = num.toString(16);

    return str.length === 1 ? '0' + str : str;
}

export function arrayToHex(arr) {
    return '#' + arr.map(toHex).join('');
}

export function isDark(color) {
    // http://www.w3.org/TR/AERT#color-contrast
    const result = (color[0] * 299 + color[1] * 587 + color[2] * 114) / 1000;

    return result < 128;
}

export function prepareIgnoredColor(color) {
    if (!color) { return color; }

    if (Array.isArray(color)) {
        return typeof color[0] === 'number' ? [color.slice()] : color;
    }

    return [color];
}

export function isIgnoredColor(data, index, ignoredColor) {
    for (let i = 0; i < ignoredColor.length; i++) {
        if (isIgnoredColorAsNumbers(data, index, ignoredColor[i])) {
            return true;
        }
    }

    return false;
}

function isIgnoredColorAsNumbers(data, index, ignoredColor) {
    switch (ignoredColor.length) {
        case 3:
            // [red, green, blue]
            if (isIgnoredRGBColor(data, index, ignoredColor)) {
                return true;
            }

            break;
        case 4:
            // [red, green, blue, alpha]
            if (isIgnoredRGBAColor(data, index, ignoredColor)) {
                return true;
            }

            break;
        case 5:
            // [red, green, blue, alpha, threshold]
            if (isIgnoredRGBAColorWithThreshold(data, index, ignoredColor)) {
                return true;
            }

            break;
        default:
            return false;
    }
}

function isIgnoredRGBColor(data, index, ignoredColor) {
    // Ignore if the pixel are transparent.
    if (data[index + 3] !== 255) {
        return true;
    }

    if (data[index] === ignoredColor[0] &&
        data[index + 1] === ignoredColor[1] &&
        data[index + 2] === ignoredColor[2]
    ) {
        return true;
    }

    return false;
}

function isIgnoredRGBAColor(data, index, ignoredColor) {
    if (data[index + 3] && ignoredColor[3]) {
        return data[index] === ignoredColor[0] &&
            data[index + 1] === ignoredColor[1] &&
            data[index + 2] === ignoredColor[2] &&
            data[index + 3] === ignoredColor[3];
    }

    // Ignore rgb components if the pixel are fully transparent.
    return data[index + 3] === ignoredColor[3];
}

function inRange(colorComponent, ignoredColorComponent, value) {
    return colorComponent >= (ignoredColorComponent - value) &&
        colorComponent <= (ignoredColorComponent + value);
}

function isIgnoredRGBAColorWithThreshold(data, index, ignoredColor) {
    const redIgnored = ignoredColor[0];
    const greenIgnored = ignoredColor[1];
    const blueIgnored = ignoredColor[2];
    const alphaIgnored = ignoredColor[3];
    const threshold = ignoredColor[4];
    const alphaData = data[index + 3];

    const alphaInRange = inRange(alphaData, alphaIgnored, threshold);
    if (!alphaIgnored) {
        return alphaInRange;
    }

    if (!alphaData && alphaInRange) {
        return true;
    }

    if (inRange(data[index], redIgnored, threshold) &&
        inRange(data[index + 1], greenIgnored, threshold) &&
        inRange(data[index + 2], blueIgnored, threshold) &&
        alphaInRange
    ) {
        return true;
    }

    return false;
}
