color_sort 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +78 -0
- data/Rakefile +6 -0
- data/color_sort.gemspec +27 -0
- data/lib/color_sort/color_space_converter.rb +8 -0
- data/lib/color_sort/distance.rb +16 -0
- data/lib/color_sort/ordering.rb +41 -0
- data/lib/color_sort/sorter.rb +35 -0
- data/lib/color_sort/version.rb +3 -0
- data/lib/color_sort.rb +11 -0
- data/spec/color_sort_spec.rb +13 -0
- data/spec/lib/color_space_converter_spec.rb +23 -0
- data/spec/lib/distance_spec.rb +24 -0
- data/spec/lib/ordering_spec.rb +77 -0
- data/spec/lib/sorter_spec.rb +20 -0
- data/spec/spec_helper.rb +3 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 81e0d767639e5bb6b4ffd6915f0b4607ce65b05d
|
4
|
+
data.tar.gz: b399a98a8bcede7671af2d587e08bc5593a93bc7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0c090a1934e79feb4dc86f608b0fc61da779f30de431fc5973aaa3eaafb2b0fd639505c9158e67577cefd79d3e20d67b2dba64f3e7a22d05a725bf6462bd6f82
|
7
|
+
data.tar.gz: 0ad0740c0cdca320c4f10c10c24abf10f5db10f20623437b47ba082c000a3d1d5031dca9cbb8c0fedefb4726bd9970b7cd939c65b4e197f6bf68b7c1e4406e7b
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Pip Taylor
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# ColorSort
|
2
|
+
|
3
|
+
ColorSort sorts an array of colors perceptually, using the
|
4
|
+
[CIEDE2000](http://en.wikipedia.org/wiki/Color_difference#CIEDE2000)
|
5
|
+
color distance function.
|
6
|
+
|
7
|
+
*Unsorted* | *Sorted*
|
8
|
+
---------- | --------
|
9
|
+
![200 unsorted lines of color](http://ms-digital-labs.github.io/unsorted.png) | ![200 sorted lines of color](http://ms-digital-labs.github.io/sorted.png)
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'color_sort'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install color_sort
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Call `ColorSort.sort` with an array of RGB colors in hex form (with or without preceeding #):
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
unsorted_colors = ["35c047", "7f40ed", "39ae1e", "5f9d4c", "94ec1e", "93e482"]
|
31
|
+
|
32
|
+
sorted_colors = ColorSort.sort(unsorted_colors)
|
33
|
+
# => ["94ec1e", "93e482", "39ae1e", "35c047", "5f9d4c", "7f40ed"]
|
34
|
+
```
|
35
|
+
|
36
|
+
## How it works
|
37
|
+
|
38
|
+
Often when dealing with colors on computers, we're working with the [RGB color model](http://en.wikipedia.org/wiki/Color_model#RGB_color_model). As each color has three components, we can think of it as a point in 3D space. This allows us to use the [Euclidean distance](http://en.wikipedia.org/wiki/Euclidean_distance) to see how far apart two colors are.
|
39
|
+
|
40
|
+
Unfortunately, the RGB color space doesn't model how people perceive colors, so a pair of colors that are close together in RGB space may actually look quite different, and vice-versa. We can solve this by using the [Lab color space](http://en.wikipedia.org/wiki/Lab_color_space) and [CIEDE2000 distance function](http://en.wikipedia.org/wiki/Color_difference#CIEDE2000). This color space and distance function are tuned to give a smaller distance for perceputally close colors.
|
41
|
+
|
42
|
+
Now we have a way of determining the perceptual distance between two colors, but we can't use this with a normal sorting algorithm because we can't define a [Total order](http://en.wikipedia.org/wiki/Total_order) over all colors. What we really need to do is find the shortest path through our colors in Lab color space, using the CIEDE2000 distance function.
|
43
|
+
|
44
|
+
This turns out to be the [Travelling salesman problem](http://en.wikipedia.org/wiki/Travelling_salesman_problem). We first tried the [Nearest neighbour](http://en.wikipedia.org/wiki/Nearest_neighbour_algorithm) heuristic, but found that it left ugly discontinuities in the sorted colors.
|
45
|
+
|
46
|
+
Next we tried [Simulated annealing](http://en.wikipedia.org/wiki/Simulated_annealing), but found that it didn't converge on a solution anywhere near quickly enough to be useful.
|
47
|
+
|
48
|
+
The solution we settled on was to iteratively build of a list of colors, inserting each one in to the list at the point at which it causes the lowest increase in the total distance between all the colors currently in the list. This allows us to sort a few hundred colors in a couple of seconds, and produces visually pleasing results.
|
49
|
+
|
50
|
+
#### Other approaches
|
51
|
+
|
52
|
+
Wikipedia lists [several other approaches for solving TSP](http://en.wikipedia.org/wiki/Travelling_salesman_problem#Computing_a_solution) - both exact solutions and approximate solutions. We didn't explore these because we couldn't find libraries that implemented them and didn't have the time to implement them ourselves.
|
53
|
+
|
54
|
+
It's almost certain that there's a better approach to solving this particular case of TSP, but we ran out of time/motivation to investigate further. If you know a better approach, please let us know!
|
55
|
+
|
56
|
+
## Performance
|
57
|
+
|
58
|
+
The algorithm used by this gem has complexity O(n<sup>2</sup>) in the size of the list being sorted. Some example timings on a MacBook Pro:
|
59
|
+
|
60
|
+
Number of colors | Time (seconds)
|
61
|
+
---------------- | --------------
|
62
|
+
100 | 0.11
|
63
|
+
200 | 0.37
|
64
|
+
300 | 0.72
|
65
|
+
500 | 2.14
|
66
|
+
1000 | 9.01
|
67
|
+
|
68
|
+
## A note on naming
|
69
|
+
|
70
|
+
This gem was authored in the UK, where color is usually spelt colour. However, this gem depends on two others ([color](http://color.rubyforge.org/) and [colorscore](https://github.com/quadule/colorscore)) that spell it without the u, so for the sake of consistency it's spelt as color in this gem too.
|
71
|
+
|
72
|
+
## Contributing
|
73
|
+
|
74
|
+
1. Fork it ( https://github.com/ms-digital-labs/color_sort/fork )
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
78
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/color_sort.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'color_sort/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "color_sort"
|
8
|
+
spec.version = ColorSort::VERSION
|
9
|
+
spec.authors = ["Pip Taylor"]
|
10
|
+
spec.email = ["pip@evilgeek.co.uk"]
|
11
|
+
spec.summary = %q{Sorts colors perceptually}
|
12
|
+
spec.homepage = "https://github.com/ms-digital-labs/color_sort"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "colorscore"
|
21
|
+
spec.add_dependency "color"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "rspec-radar"
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "colorscore"
|
2
|
+
|
3
|
+
module ColorSort
|
4
|
+
module Distance
|
5
|
+
def self.ciede2000(lab_color_a, lab_color_b)
|
6
|
+
cache_key = [lab_color_a, lab_color_b].sort
|
7
|
+
ciede2000_cache[cache_key] ||=
|
8
|
+
Colorscore::Metrics.delta_e_cie_2000(*lab_color_a, *lab_color_b)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def self.ciede2000_cache
|
13
|
+
@ciede2000_cache ||= {}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "color_sort/distance"
|
2
|
+
|
3
|
+
module ColorSort
|
4
|
+
class Ordering
|
5
|
+
attr_reader :colors
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@colors = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_lab_color(color)
|
12
|
+
if colors.size < 2
|
13
|
+
colors << color
|
14
|
+
else
|
15
|
+
min_delta = distance(color, colors.first)
|
16
|
+
min_delta_index = 0
|
17
|
+
|
18
|
+
(1...colors.size).each do |i|
|
19
|
+
remove_distance = distance(colors[i-1], colors[i])
|
20
|
+
add_distance = distance(colors[i-1], color) + distance(color, colors[i])
|
21
|
+
delta = add_distance - remove_distance
|
22
|
+
if delta < min_delta
|
23
|
+
min_delta = delta
|
24
|
+
min_delta_index = i
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if distance(colors.last, color) < min_delta
|
29
|
+
min_delta_index = colors.size
|
30
|
+
end
|
31
|
+
|
32
|
+
colors.insert(min_delta_index, color)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def distance(color_a, color_b)
|
38
|
+
ColorSort::Distance.ciede2000(color_a, color_b)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ColorSort
|
2
|
+
class Sorter
|
3
|
+
def initialize(colors)
|
4
|
+
@colors = colors
|
5
|
+
end
|
6
|
+
|
7
|
+
def sorted
|
8
|
+
ordering.colors.map { |lab_color|
|
9
|
+
color_map[lab_color]
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
attr_reader :colors
|
15
|
+
|
16
|
+
def color_map
|
17
|
+
@color_map ||= colors.each_with_object({}) { |hex_rgb_color, hash|
|
18
|
+
lab_color = ColorSort::ColorSpaceConverter.hex_rgb_to_lab(hex_rgb_color)
|
19
|
+
hash[lab_color] = hex_rgb_color
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def lab_colors
|
24
|
+
@lab_colors ||= colors.map { |hex_rgb_color|
|
25
|
+
ColorSort::ColorSpaceConverter.hex_rgb_to_lab(hex_rgb_color)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def ordering
|
30
|
+
@ordering ||= lab_colors.each_with_object(Ordering.new) { |lab_color, ordering|
|
31
|
+
ordering.add_lab_color(lab_color)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/color_sort.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ColorSort do
|
4
|
+
it 'should have a version number' do
|
5
|
+
ColorSort::VERSION.should_not be_nil
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".sort" do
|
9
|
+
it "passes the colors to ColorSort::Sorter and calls #sorted" do
|
10
|
+
expect(ColorSort.sort(["#123456"])).to eq(["#123456"])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ColorSort::ColorSpaceConverter do
|
4
|
+
describe "#hex_rgb_to_lab" do
|
5
|
+
subject { ColorSort::ColorSpaceConverter }
|
6
|
+
|
7
|
+
let(:expected_lab_result) {
|
8
|
+
[21.041610053894317, 1.0523062624117063, -24.099168114444936]
|
9
|
+
}
|
10
|
+
|
11
|
+
context "with a preceeding #" do
|
12
|
+
it "converts hex RGB color to LAB" do
|
13
|
+
expect(subject.hex_rgb_to_lab("#123456")).to eq(expected_lab_result)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with a preceeding #" do
|
18
|
+
it "converts hex RGB color to LAB" do
|
19
|
+
expect(subject.hex_rgb_to_lab("123456")).to eq(expected_lab_result)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ColorSort::Distance do
|
4
|
+
describe "#ciede2000" do
|
5
|
+
let(:distance) { double(:distance) }
|
6
|
+
|
7
|
+
it "splats the lab colors and passes them to Colorscore" do
|
8
|
+
expect(Colorscore::Metrics).to receive(:delta_e_cie_2000)
|
9
|
+
.with(1, 2, 3, 4, 5, 6)
|
10
|
+
|
11
|
+
ColorSort::Distance.ciede2000([1, 2, 3], [4, 5, 6])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "only calls in to Colorscore once for each pair of colors" do
|
15
|
+
expect(Colorscore::Metrics).to receive(:delta_e_cie_2000)
|
16
|
+
.with(1, 2, 3, 4, 5, 6)
|
17
|
+
.once
|
18
|
+
.and_return(distance)
|
19
|
+
|
20
|
+
expect(ColorSort::Distance.ciede2000([1, 2, 3], [4, 5, 6])).to eq(distance)
|
21
|
+
expect(ColorSort::Distance.ciede2000([4, 5, 6], [1, 2, 3])).to eq(distance)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ColorSort::Ordering do
|
4
|
+
let(:red) { double(:red) }
|
5
|
+
let(:green) { double(:green) }
|
6
|
+
let(:blue) { double(:blue) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
set_distance(red, red, 0)
|
10
|
+
set_distance(green, green, 0)
|
11
|
+
set_distance(blue, blue, 0)
|
12
|
+
|
13
|
+
set_distance(red, blue, 1)
|
14
|
+
set_distance(blue, green, 2)
|
15
|
+
set_distance(red, green, 3)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#add_lab_color" do
|
19
|
+
context "with an empty ordering" do
|
20
|
+
it "adds the color to the end of the array" do
|
21
|
+
subject.add_lab_color(red)
|
22
|
+
|
23
|
+
expect(subject.colors).to eq([red])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with one color in the ordering" do
|
28
|
+
it "adds the color to the end of the array" do
|
29
|
+
subject.add_lab_color(red)
|
30
|
+
subject.add_lab_color(green)
|
31
|
+
|
32
|
+
expect(subject.colors).to eq([red, green])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with multiple colors in the ordering" do
|
37
|
+
context "best position is at the beginning" do
|
38
|
+
it "adds the color in the position that minimises total distance" do
|
39
|
+
subject.add_lab_color(blue)
|
40
|
+
subject.add_lab_color(green)
|
41
|
+
subject.add_lab_color(red)
|
42
|
+
|
43
|
+
expect(subject.colors).to eq([red, blue, green])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "best position is in the middle" do
|
48
|
+
it "adds the color in the position that minimises total distance" do
|
49
|
+
subject.add_lab_color(red)
|
50
|
+
subject.add_lab_color(green)
|
51
|
+
subject.add_lab_color(blue)
|
52
|
+
|
53
|
+
expect(subject.colors).to eq([red, blue, green])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "best position is at the end" do
|
58
|
+
it "adds the color in the position that minimises total distance" do
|
59
|
+
subject.add_lab_color(green)
|
60
|
+
subject.add_lab_color(blue)
|
61
|
+
subject.add_lab_color(red)
|
62
|
+
|
63
|
+
expect(subject.colors).to eq([green, blue, red])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_distance(color_a, color_b, distance)
|
70
|
+
allow(ColorSort::Distance).to receive(:ciede2000)
|
71
|
+
.with(color_a, color_b)
|
72
|
+
.and_return(distance)
|
73
|
+
allow(ColorSort::Distance).to receive(:ciede2000)
|
74
|
+
.with(color_b, color_a)
|
75
|
+
.and_return(distance)
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ColorSort::Sorter do
|
4
|
+
describe "#sorted" do
|
5
|
+
let(:red_1) { "#ff0000" }
|
6
|
+
let(:red_2) { "#cc0000" }
|
7
|
+
let(:green_1) { "#00ff00" }
|
8
|
+
let(:green_2) { "#00cc00" }
|
9
|
+
let(:blue_1) { "#0000ff" }
|
10
|
+
let(:blue_2) { "#0000cc" }
|
11
|
+
|
12
|
+
let(:colors) { [red_1, blue_1, green_1, red_2, blue_2, green_2] }
|
13
|
+
|
14
|
+
subject { described_class.new(colors) }
|
15
|
+
|
16
|
+
it "orders the colors perceptually" do
|
17
|
+
expect(subject.sorted).to eq([red_1, red_2, blue_2, blue_1, green_2, green_1])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: color_sort
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pip Taylor
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorscore
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: color
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-radar
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description:
|
98
|
+
email:
|
99
|
+
- pip@evilgeek.co.uk
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- color_sort.gemspec
|
111
|
+
- lib/color_sort.rb
|
112
|
+
- lib/color_sort/color_space_converter.rb
|
113
|
+
- lib/color_sort/distance.rb
|
114
|
+
- lib/color_sort/ordering.rb
|
115
|
+
- lib/color_sort/sorter.rb
|
116
|
+
- lib/color_sort/version.rb
|
117
|
+
- spec/color_sort_spec.rb
|
118
|
+
- spec/lib/color_space_converter_spec.rb
|
119
|
+
- spec/lib/distance_spec.rb
|
120
|
+
- spec/lib/ordering_spec.rb
|
121
|
+
- spec/lib/sorter_spec.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
homepage: https://github.com/ms-digital-labs/color_sort
|
124
|
+
licenses:
|
125
|
+
- MIT
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.2.2
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Sorts colors perceptually
|
147
|
+
test_files:
|
148
|
+
- spec/color_sort_spec.rb
|
149
|
+
- spec/lib/color_space_converter_spec.rb
|
150
|
+
- spec/lib/distance_spec.rb
|
151
|
+
- spec/lib/ordering_spec.rb
|
152
|
+
- spec/lib/sorter_spec.rb
|
153
|
+
- spec/spec_helper.rb
|