// https://github.com/connorgr/d3-jnd Version 0.1.3. Copyright 2017 undefined.
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-color')) :
  typeof define === 'function' && define.amd ? define(['exports', 'd3-color'], factory) :
  (factory((global.d3 = global.d3 || {}),global.d3));
}(this, (function (exports,d3Color) { 'use strict';

// Implementation based on Maureen Stone, Danielle Albers Szafir, and Vidya
// Setlur's paper "An Engineering Model for Color Difference as a Function of
// Size" presented at the Color Imaging Conference, and can be found online at
// https://research.tableau.com/sites/default/files/2014CIC_48_Stone_v3.pdf
//
// Their paper examines target sizes (visual angle) ranging from 6 to 1/3
// degree, so note that extrapolations outside that range contain additional
// untesteed assumptions about color appearence.

// To calculate whether colors are noticeably different, colors are translated
// into CIELAB perceptual color space. Further, users must specifiy a visual
// angle for how large the colored elements are (e.g., bars in a bar chart)
// along their smallest dimension (e.g., width for 25px wide x 100px tall bars).

// Variable definitions:
// nd: noticeable difference
// p: a threshold defined as the percentage of observers who see two colors
//    separated by a particular color space interval (e.g., along L*) as
//    different.
// s: size, specified in degrees of visual angle

//----------------------------------------.
// PREDICTING DISCRIMINABILITY THRESHOLDS  \___________________________________
//=============================================================================|
// // p = V(s)*Delta_D + e (i.e., y=ax+b), where
//               s: size,
//      V(s) and D: vector values of L*, a*, b*
//               e: error term
//         Delta_D: a step in CIELAB space
//            V(s): a vector of three slopes, which differ along L*, a*, and b*
//
// Therefore, Delta_D = nd(p) = p / V(s)
//
// For calculating just noticeable differences (JND), we'll assume that p should
// be fixed at 50%, which then leaves size as the only free variable for
// calculating discriminability intervals along L*, a*, and b* color channels.
//
// ND(50, s) = C(50) + K(50)/s, where C and K are regression coefficients
//
// Stone et al. also provide a generalized formula that can support p and s both
// as free variables based on additional regressions (see paper):
//
// ND(p,s) = p(A+B/s), where
//               s: size,
//               p: % of observers who see colors as different ([0,1])
//         A and B: preset values that differ for each channel
//
function nd(p,s) {
  var A = {l: 10.16, a: 10.68, b: 10.70},
      B = {l:  1.50, a:  3.08, b:  5.74};

  return {
    l: p * (A.l + B.l / s),
    a: p * (A.a + B.a / s),
    b: p * (A.b + B.b / s)
  };
}

function jndLabInterval(p, s) {
  if(typeof s === "string") {
    if(s === "thin") s = 0.1;
    else if(s === "medium") s = 0.5;
    else if(s === "wide") s = 1.0;
    else s = 0.1;
  }
  if(typeof p === "string") {
    if(s === "conservative") p = 0.8;
    else p = 0.5;
  }
  return nd(p, s);
}

function noticeablyDifferent(c1, c2, s, p) {
  if(arguments.length < 3) s = 0.1;
  if(arguments.length < 4) p = 0.5;

  var jnd = jndLabInterval(p, s);
  c1 = d3Color.lab(c1);
  c2 = d3Color.lab(c2);

  return (Math.abs(c1.l-c2.l) >= jnd.l) || (Math.abs(c1.a-c2.a) >= jnd.a) || (Math.abs(c1.b-c2.b) >= jnd.b);
}

exports.jndLabInterval = jndLabInterval;
exports.noticeablyDifferent = noticeablyDifferent;

Object.defineProperty(exports, '__esModule', { value: true });

})));