<repo_name>marinamcpeak/PaletteDrop<file_sep>/PaletteDrop/PaletteImageView.swift
////  PaletteImageView.swift
// Created: 2019-06-24
//


import Foundation

class PaletteImageView: UIViewController {
    
    @IBOutlet weak var imageView: UIImageView!
    var matcher:PaletteImageMatcher?
    let feedbackGenerator = UINotificationFeedbackGenerator()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        showNextImage()
    }
    
    
    // We are willing to become first responder to get shake motion
    override var canBecomeFirstResponder: Bool {
        get {
            return true
        }
    }
    
    // Enable detection of shake motion
    override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            showNextImage()
        }
    }
    
    func showNextImage() {
        print("Will Change Image")
        feedbackGenerator.prepare()
        guard let paletteImage = matcher?.nextImage() else {
            feedbackGenerator.notificationOccurred(.warning)
            return
        }
        
        guard let image = paletteImage.image else {
            feedbackGenerator.notificationOccurred(.error)
            return
        }
        if (paletteImage.height >= paletteImage.width) {
            imageView.image = image;
        } else {
            imageView.image = image.rotate(radians: .pi/2)
        }
        imageView.setNeedsLayout();
        feedbackGenerator.notificationOccurred(.success)
    }
    
}

extension UIImage {
    func rotate(radians: Float) -> UIImage? {
        var newSize = CGRect(origin: CGPoint.zero, size: self.size).applying(CGAffineTransform(rotationAngle: CGFloat(radians))).size
        // Trim off the extremely small float value to prevent core graphics from rounding it up
        newSize.width = floor(newSize.width)
        newSize.height = floor(newSize.height)
        
        UIGraphicsBeginImageContextWithOptions(newSize, false, self.scale)
        let context = UIGraphicsGetCurrentContext()!
        
        // Move origin to middle
        context.translateBy(x: newSize.width/2, y: newSize.height/2)
        // Rotate around middle
        context.rotate(by: CGFloat(radians))
        // Draw the image at its center
        self.draw(in: CGRect(x: -self.size.width/2, y: -self.size.height/2, width: self.size.width, height: self.size.height))
        
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return newImage
    }
}
<file_sep>/Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'PaletteDrop' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for PaletteDrop
  # Realm
  pod 'Realm','~> 3.16'

  target 'PaletteDropTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'PaletteDropUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end
<file_sep>/PaletteDrop/Colors.swift
////  Colors.swift
// Created: 2019-06-22
//


import Foundation

class Colors {
    static let names:[String:String] = [
        "#000000":    "black*",
        "#000080":    "navy*",
        "#00008B":    "blue 4 (darkblue)",
        "#0000CD":    "blue 3 (mediumblue)",
        "#0000EE":    "blue 2",
        "#0000FF":    "blue*",
        "#006400":    "darkgreen",
        "#00688B":    "deepskyblue 4",
        "#008000":    "green*",
        "#008080":    "teal*",
        "#00868B":    "turquoise 4",
        "#008B00":    "green 4",
        "#008B45":    "springgreen 3",
        "#008B8B":    "cyan 4 (darkcyan)",
        "#009ACD":    "deepskyblue 3",
        "#00B2EE":    "deepskyblue 2",
        "#00BFFF":    "deepskyblue 1 (deepskyblue)",
        "#00C5CD":    "turquoise 3",
        "#00C78C":    "turquoiseblue",
        "#00C957":    "emeraldgreen",
        "#00CD00":    "green 3",
        "#00CD66":    "springgreen 2",
        "#00CDCD":    "cyan 3",
        "#00CED1":    "darkturquoise",
        "#00E5EE":    "turquoise 2",
        "#00EE00":    "green 2",
        "#00EE76":    "springgreen 1",
        "#00EEEE":    "cyan 2",
        "#00F5FF":    "turquoise 1",
        "#00FA9A":    "mediumspringgreen",
        "#00FF00":    "green 1 (lime*)",
        "#00FF7F":    "springgreen",
        "#00FFFF":    "cyan / aqua*",
        "#030303":    "gray 1",
        "#03A89E":    "manganeseblue",
        "#050505":    "gray 2",
        "#080808":    "gray 3",
        "#0A0A0A":    "gray 4",
        "#0D0D0D":    "gray 5",
        "#0F0F0F":    "gray 6",
        "#104E8B":    "dodgerblue 4",
        "#121212":    "gray 7",
        "#141414":    "gray 8",
        "#171717":    "gray 9",
        "#1874CD":    "dodgerblue 3",
        "#191970":    "midnightblue",
        "#1A1A1A":    "gray 10",
        "#1C1C1C":    "gray 11",
        "#1C86EE":    "dodgerblue 2",
        "#1E1E1E":    "sgi gray 12",
        "#1E90FF":    "dodgerblue 1 (dodgerblue)",
        "#1F1F1F":    "gray 12",
        "#20B2AA":    "lightseagreen",
        "#212121":    "gray 13",
        "#228B22":    "forestgreen",
        "#242424":    "gray 14",
        "#262626":    "gray 15",
        "#27408B":    "royalblue 4",
        "#282828":    "sgi gray 16",
        "#292421":    "ivoryblack",
        "#292929":    "gray 16",
        "#2B2B2B":    "gray 17",
        "#2E2E2E":    "gray 18",
        "#2E8B57":    "seagreen 4 (seagreen)",
        "#2F4F4F":    "darkslategray",
        "#303030":    "gray 19",
        "#308014":    "sapgreen",
        "#32CD32":    "limegreen",
        "#333333":    "gray 20",
        "#33A1C9":    "peacock",
        "#363636":    "gray 21",
        "#36648B":    "steelblue 4",
        "#383838":    "gray 22",
        "#388E8E":    "sgi teal",
        "#3A5FCD":    "royalblue 3",
        "#3B3B3B":    "gray 23",
        "#3CB371":    "mediumseagreen",
        "#3D3D3D":    "gray 24",
        "#3D59AB":    "cobalt",
        "#3D9140":    "cobaltgreen",
        "#404040":    "gray 25",
        "#40E0D0":    "turquoise",
        "#4169E1":    "royalblue",
        "#424242":    "gray 26",
        "#436EEE":    "royalblue 2",
        "#43CD80":    "seagreen 3",
        "#454545":    "gray 27",
        "#458B00":    "chartreuse 4",
        "#458B74":    "aquamarine 4",
        "#4682B4":    "steelblue",
        "#473C8B":    "slateblue 4",
        "#474747":    "gray 28",
        "#483D8B":    "darkslateblue",
        "#4876FF":    "royalblue 1",
        "#48D1CC":    "mediumturquoise",
        "#4A4A4A":    "gray 29",
        "#4A708B":    "skyblue 4",
        "#4B0082":    "indigo",
        "#4D4D4D":    "gray 30",
        "#4EEE94":    "seagreen 2",
        "#4F4F4F":    "gray 31",
        "#4F94CD":    "steelblue 3",
        "#515151":    "sgi gray 32",
        "#525252":    "gray 32",
        "#528B8B":    "darkslategray 4",
        "#53868B":    "cadetblue 4",
        "#545454":    "gray 33",
        "#548B54":    "palegreen 4",
        "#54FF9F":    "seagreen 1",
        "#551A8B":    "purple 4",
        "#555555":    "sgi darkgray",
        "#556B2F":    "darkolivegreen",
        "#575757":    "gray 34",
        "#595959":    "gray 35",
        "#5B5B5B":    "sgi gray 36",
        "#5C5C5C":    "gray 36",
        "#5CACEE":    "steelblue 2",
        "#5D478B":    "mediumpurple 4",
        "#5E2612":    "sepia",
        "#5E5E5E":    "gray 37",
        "#5F9EA0":    "cadetblue",
        "#607B8B":    "lightskyblue 4",
        "#616161":    "gray 38",
        "#636363":    "gray 39",
        "#63B8FF":    "steelblue 1",
        "#6495ED":    "cornflowerblue",
        "#666666":    "gray 40",
        "#668B8B":    "paleturquoise 4",
        "#66CD00":    "chartreuse 3",
        "#66CDAA":    "aquamarine 3 (mediumaquamarine)",
        "#68228B":    "darkorchid 4",
        "#68838B":    "lightblue 4",
        "#6959CD":    "slateblue 3",
        "#696969":    "dimgray (gray 42)",
        "#698B22":    "olivedrab 4",
        "#698B69":    "darkseagreen 4",
        "#6A5ACD":    "slateblue",
        "#6B6B6B":    "gray 42",
        "#6B8E23":    "olivedrab",
        "#6C7B8B":    "slategray 4",
        "#6CA6CD":    "skyblue 3",
        "#6E6E6E":    "gray 43",
        "#6E7B8B":    "lightsteelblue 4",
        "#6E8B3D":    "darkolivegreen 4",
        "#707070":    "gray 44",
        "#708090":    "slategray",
        "#7171C6":    "sgi slateblue",
        "#71C671":    "sgi chartreuse",
        "#737373":    "gray 45",
        "#757575":    "gray 46",
        "#76EE00":    "chartreuse 2",
        "#76EEC6":    "aquamarine 2",
        "#778899":    "lightslategray",
        "#787878":    "gray 47",
        "#79CDCD":    "darkslategray 3",
        "#7A378B":    "mediumorchid 4",
        "#7A67EE":    "slateblue 2",
        "#7A7A7A":    "gray 48",
        "#7A8B8B":    "lightcyan 4",
        "#7AC5CD":    "cadetblue 3",
        "#7B68EE":    "mediumslateblue",
        "#7CCD7C":    "palegreen 3",
        "#7CFC00":    "lawngreen",
        "#7D26CD":    "purple 3",
        "#7D7D7D":    "gray 49",
        "#7D9EC0":    "sgi lightblue",
        "#7EC0EE":    "skyblue 2",
        "#7F7F7F":    "gray 50",
        "#7FFF00":    "chartreuse 1 (chartreuse)",
        "#7FFFD4":    "aquamarine 1 (aquamarine)",
        "#800000":    "maroon*",
        "#800080":    "purple*",
        "#808000":    "olive*",
        "#808069":    "warmgrey",
        "#808080":    "gray*",
        "#808A87":    "coldgrey",
        "#828282":    "gray 51",
        "#836FFF":    "slateblue 1",
        "#838B83":    "honeydew 4",
        "#838B8B":    "azure 4",
        "#8470FF":    "lightslateblue",
        "#848484":    "sgi gray 52",
        "#858585":    "gray 52",
        "#872657":    "raspberry",
        "#878787":    "gray 53",
        "#87CEEB":    "skyblue",
        "#87CEFA":    "lightskyblue",
        "#87CEFF":    "skyblue 1",
        "#8968CD":    "mediumpurple 3",
        "#8A2BE2":    "blueviolet",
        "#8A3324":    "burntumber",
        "#8A360F":    "burntsienna",
        "#8A8A8A":    "gray 54",
        "#8B0000":    "red 4 (darkred)",
        "#8B008B":    "magenta 4 (darkmagenta)",
        "#8B0A50":    "deeppink 4",
        "#8B1A1A":    "firebrick 4",
        "#8B1C62":    "maroon 4",
        "#8B2252":    "violetred 4",
        "#8B2323":    "brown 4",
        "#8B2500":    "orangered 4",
        "#8B3626":    "tomato 4",
        "#8B3A3A":    "indianred 4",
        "#8B3A62":    "hotpink 4",
        "#8B3E2F":    "coral 4",
        "#8B4500":    "darkorange 4",
        "#8B4513":    "chocolate 4 (saddlebrown)",
        "#8B4726":    "sienna 4",
        "#8B475D":    "palevioletred 4",
        "#8B4789":    "orchid 4",
        "#8B4C39":    "salmon 4",
        "#8B5742":    "lightsalmon 4",
        "#8B5A00":    "orange 4",
        "#8B5A2B":    "tan 4",
        "#8B5F65":    "lightpink 4",
        "#8B636C":    "pink 4",
        "#8B6508":    "darkgoldenrod 4",
        "#8B668B":    "plum 4",
        "#8B6914":    "goldenrod 4",
        "#8B6969":    "rosybrown 4",
        "#8B7355":    "burlywood 4",
        "#8B7500":    "gold 4",
        "#8B7765":    "peachpuff 4",
        "#8B795E":    "navajowhite 4",
        "#8B7B8B":    "thistle 4",
        "#8B7D6B":    "bisque 4",
        "#8B7D7B":    "mistyrose 4",
        "#8B7E66":    "wheat 4",
        "#8B814C":    "lightgoldenrod 4",
        "#8B8378":    "antiquewhite 4",
        "#8B8386":    "lavenderblush 4",
        "#8B864E":    "khaki 4",
        "#8B8682":    "seashell 4",
        "#8B8878":    "cornsilk 4",
        "#8B8970":    "lemonchiffon 4",
        "#8B8989":    "snow 4",
        "#8B8B00":    "yellow 4",
        "#8B8B7A":    "lightyellow 4",
        "#8B8B83":    "ivory 4",
        "#8C8C8C":    "gray 55",
        "#8DB6CD":    "lightskyblue 3",
        "#8DEEEE":    "darkslategray 2",
        "#8E388E":    "sgi beet",
        "#8E8E38":    "sgi olivedrab",
        "#8E8E8E":    "sgi gray 56",
        "#8EE5EE":    "cadetblue 2",
        "#8F8F8F":    "gray 56",
        "#8FBC8F":    "darkseagreen",
        "#90EE90":    "palegreen 2 (lightgreen)",
        "#912CEE":    "purple 2",
        "#919191":    "gray 57",
        "#9370DB":    "mediumpurple",
        "#9400D3":    "darkviolet",
        "#949494":    "gray 58",
        "#969696":    "gray 59",
        "#96CDCD":    "paleturquoise 3",
        "#97FFFF":    "darkslategray 1",
        "#98F5FF":    "cadetblue 1",
        "#98FB98":    "palegreen",
        "#9932CC":    "darkorchid",
        "#999999":    "gray 60",
        "#9A32CD":    "darkorchid 3",
        "#9AC0CD":    "lightblue 3",
        "#9ACD32":    "olivedrab 3 (yellowgreen)",
        "#9AFF9A":    "palegreen 1",
        "#9B30FF":    "purple 1",
        "#9BCD9B":    "darkseagreen 3",
        "#9C661F":    "brick",
        "#9C9C9C":    "gray 61",
        "#9E9E9E":    "gray 62",
        "#9F79EE":    "mediumpurple 2",
        "#9FB6CD":    "slategray 3",
        "#A0522D":    "sienna",
        "#A1A1A1":    "gray 63",
        "#A2B5CD":    "lightsteelblue 3",
        "#A2CD5A":    "darkolivegreen 3",
        "#A3A3A3":    "gray 64",
        "#A4D3EE":    "lightskyblue 2",
        "#A52A2A":    "brown",
        "#A6A6A6":    "gray 65",
        "#A8A8A8":    "gray 66",
        "#A9A9A9":    "darkgray",
        "#AAAAAA":    "sgi lightgray",
        "#AB82FF":    "mediumpurple 1",
        "#ABABAB":    "gray 67",
        "#ADADAD":    "gray 68",
        "#ADD8E6":    "lightblue",
        "#ADFF2F":    "greenyellow",
        "#AEEEEE":    "paleturquoise 2 (paleturquoise)",
        "#B0171F":    "indian red",
        "#B0B0B0":    "gray 69",
        "#B0C4DE":    "lightsteelblue",
        "#B0E0E6":    "powderblue",
        "#B0E2FF":    "lightskyblue 1",
        "#B22222":    "firebrick",
        "#B23AEE":    "darkorchid 2",
        "#B2DFEE":    "lightblue 2",
        "#B3B3B3":    "gray 70",
        "#B3EE3A":    "olivedrab 2",
        "#B452CD":    "mediumorchid 3",
        "#B4CDCD":    "lightcyan 3",
        "#B4EEB4":    "darkseagreen 2",
        "#B5B5B5":    "gray 71",
        "#B7B7B7":    "sgi gray 72",
        "#B8860B":    "darkgoldenrod",
        "#B8B8B8":    "gray 72",
        "#B9D3EE":    "slategray 2",
        "#BA55D3":    "mediumorchid",
        "#BABABA":    "gray 73",
        "#BBFFFF":    "paleturquoise 1",
        "#BC8F8F":    "rosybrown",
        "#BCD2EE":    "lightsteelblue 2",
        "#BCEE68":    "darkolivegreen 2",
        "#BDB76B":    "darkkhaki",
        "#BDBDBD":    "gray 74",
        "#BDFCC9":    "mint",
        "#BF3EFF":    "darkorchid 1",
        "#BFBFBF":    "gray 75",
        "#BFEFFF":    "lightblue 1",
        "#C0C0C0":    "silver*",
        "#C0FF3E":    "olivedrab 1",
        "#C1C1C1":    "sgi gray 76",
        "#C1CDC1":    "honeydew 3",
        "#C1CDCD":    "azure 3",
        "#C1FFC1":    "darkseagreen 1",
        "#C2C2C2":    "gray 76",
        "#C4C4C4":    "gray 77",
        "#C5C1AA":    "sgi brightgray",
        "#C67171":    "sgi salmon",
        "#C6E2FF":    "slategray 1",
        "#C71585":    "mediumvioletred",
        "#C76114":    "rawsienna",
        "#C7C7C7":    "gray 78",
        "#C9C9C9":    "gray 79",
        "#CAE1FF":    "lightsteelblue 1",
        "#CAFF70":    "darkolivegreen 1",
        "#CCCCCC":    "gray 80",
        "#CD0000":    "red 3",
        "#CD00CD":    "magenta 3",
        "#CD1076":    "deeppink 3",
        "#CD2626":    "firebrick 3",
        "#CD2990":    "maroon 3",
        "#CD3278":    "violetred 3",
        "#CD3333":    "brown 3",
        "#CD3700":    "orangered 3",
        "#CD4F39":    "tomato 3",
        "#CD5555":    "indianred 3",
        "#CD5B45":    "coral 3",
        "#CD5C5C":    "indianred",
        "#CD6090":    "hotpink 3",
        "#CD6600":    "darkorange 3",
        "#CD661D":    "chocolate 3",
        "#CD6839":    "sienna 3",
        "#CD6889":    "palevioletred 3",
        "#CD69C9":    "orchid 3",
        "#CD7054":    "salmon 3",
        "#CD8162":    "lightsalmon 3",
        "#CD8500":    "orange 3",
        "#CD853F":    "tan 3 (peru)",
        "#CD8C95":    "lightpink 3",
        "#CD919E":    "pink 3",
        "#CD950C":    "darkgoldenrod 3",
        "#CD96CD":    "plum 3",
        "#CD9B1D":    "goldenrod 3",
        "#CD9B9B":    "rosybrown 3",
        "#CDAA7D":    "burlywood 3",
        "#CDAD00":    "gold 3",
        "#CDAF95":    "peachpuff 3",
        "#CDB38B":    "navajowhite 3",
        "#CDB5CD":    "thistle 3",
        "#CDB79E":    "bisque 3",
        "#CDB7B5":    "mistyrose 3",
        "#CDBA96":    "wheat 3",
        "#CDBE70":    "lightgoldenrod 3",
        "#CDC0B0":    "antiquewhite 3",
        "#CDC1C5":    "lavenderblush 3",
        "#CDC5BF":    "seashell 3",
        "#CDC673":    "khaki 3",
        "#CDC8B1":    "cornsilk 3",
        "#CDC9A5":    "lemonchiffon 3",
        "#CDC9C9":    "snow 3",
        "#CDCD00":    "yellow 3",
        "#CDCDB4":    "lightyellow 3",
        "#CDCDC1":    "ivory 3",
        "#CFCFCF":    "gray 81",
        "#D02090":    "violetred",
        "#D15FEE":    "mediumorchid 2",
        "#D1D1D1":    "gray 82",
        "#D1EEEE":    "lightcyan 2",
        "#D2691E":    "chocolate",
        "#D2B48C":    "tan",
        "#D3D3D3":    "lightgrey",
        "#D4D4D4":    "gray 83",
        "#D6D6D6":    "gray 84",
        "#D8BFD8":    "thistle",
        "#D9D9D9":    "gray 85",
        "#DA70D6":    "orchid",
        "#DAA520":    "goldenrod",
        "#DB7093":    "palevioletred",
        "#DBDBDB":    "gray 86",
        "#DC143C":    "crimson",
        "#DCDCDC":    "gainsboro",
        "#DDA0DD":    "plum",
        "#DEB887":    "burlywood",
        "#DEDEDE":    "gray 87",
        "#E066FF":    "mediumorchid 1",
        "#E0E0E0":    "gray 88",
        "#E0EEE0":    "honeydew 2",
        "#E0EEEE":    "azure 2",
        "#E0FFFF":    "lightcyan 1 (lightcyan)",
        "#E3A869":    "melon",
        "#E3CF57":    "banana",
        "#E3E3E3":    "gray 89",
        "#E5E5E5":    "gray 90",
        "#E6E6FA":    "lavender",
        "#E8E8E8":    "gray 91",
        "#E9967A":    "darksalmon",
        "#EAEAEA":    "sgi gray 92",
        "#EBEBEB":    "gray 92",
        "#ED9121":    "carrot",
        "#EDEDED":    "gray 93",
        "#EE0000":    "red 2",
        "#EE00EE":    "magenta 2",
        "#EE1289":    "deeppink 2",
        "#EE2C2C":    "firebrick 2",
        "#EE30A7":    "maroon 2",
        "#EE3A8C":    "violetred 2",
        "#EE3B3B":    "brown 2",
        "#EE4000":    "orangered 2",
        "#EE5C42":    "tomato 2",
        "#EE6363":    "indianred 2",
        "#EE6A50":    "coral 2",
        "#EE6AA7":    "hotpink 2",
        "#EE7600":    "darkorange 2",
        "#EE7621":    "chocolate 2",
        "#EE7942":    "sienna 2",
        "#EE799F":    "palevioletred 2",
        "#EE7AE9":    "orchid 2",
        "#EE8262":    "salmon 2",
        "#EE82EE":    "violet",
        "#EE9572":    "lightsalmon 2",
        "#EE9A00":    "orange 2",
        "#EE9A49":    "tan 2",
        "#EEA2AD":    "lightpink 2",
        "#EEA9B8":    "pink 2",
        "#EEAD0E":    "darkgoldenrod 2",
        "#EEAEEE":    "plum 2",
        "#EEB422":    "goldenrod 2",
        "#EEB4B4":    "rosybrown 2",
        "#EEC591":    "burlywood 2",
        "#EEC900":    "gold 2",
        "#EECBAD":    "peachpuff 2",
        "#EECFA1":    "navajowhite 2",
        "#EED2EE":    "thistle 2",
        "#EED5B7":    "bisque 2",
        "#EED5D2":    "mistyrose 2",
        "#EED8AE":    "wheat 2",
        "#EEDC82":    "lightgoldenrod 2",
        "#EEDFCC":    "antiquewhite 2",
        "#EEE0E5":    "lavenderblush 2",
        "#EEE5DE":    "seashell 2",
        "#EEE685":    "khaki 2",
        "#EEE8AA":    "palegoldenrod",
        "#EEE8CD":    "cornsilk 2",
        "#EEE9BF":    "lemonchiffon 2",
        "#EEE9E9":    "snow 2",
        "#EEEE00":    "yellow 2",
        "#EEEED1":    "lightyellow 2",
        "#EEEEE0":    "ivory 2",
        "#F08080":    "lightcoral",
        "#F0E68C":    "khaki",
        "#F0F0F0":    "gray 94",
        "#F0F8FF":    "aliceblue",
        "#F0FFF0":    "honeydew 1 (honeydew)",
        "#F0FFFF":    "azure 1 (azure)",
        "#F2F2F2":    "gray 95",
        "#F4A460":    "sandybrown",
        "#F4F4F4":    "sgi gray 96",
        "#F5DEB3":    "wheat",
        "#F5F5DC":    "beige",
        "#F5F5F5":    "white smoke (gray 96)",
        "#F5FFFA":    "mintcream",
        "#F7F7F7":    "gray 97",
        "#F8F8FF":    "ghostwhite",
        "#FA8072":    "salmon",
        "#FAEBD7":    "antiquewhite",
        "#FAF0E6":    "linen",
        "#FAFAD2":    "lightgoldenrodyellow",
        "#FAFAFA":    "gray 98",
        "#FCE6C9":    "eggshell",
        "#FCFCFC":    "gray 99",
        "#FDF5E6":    "oldlace",
        "#FF0000":    "red 1 (red*)",
        "#FF00FF":    "magenta (fuchsia*)",
        "#FF1493":    "deeppink 1 (deeppink)",
        "#FF3030":    "firebrick 1",
        "#FF34B3":    "maroon 1",
        "#FF3E96":    "violetred 1",
        "#FF4040":    "brown 1",
        "#FF4500":    "orangered 1 (orangered)",
        "#FF6103":    "cadmiumorange",
        "#FF6347":    "tomato 1 (tomato)",
        "#FF69B4":    "hotpink",
        "#FF6A6A":    "indianred 1",
        "#FF6EB4":    "hotpink 1",
        "#FF7256":    "coral 1",
        "#FF7D40":    "flesh",
        "#FF7F00":    "darkorange 1",
        "#FF7F24":    "chocolate 1",
        "#FF7F50":    "coral",
        "#FF8000":    "orange",
        "#FF8247":    "sienna 1",
        "#FF82AB":    "palevioletred 1",
        "#FF83FA":    "orchid 1",
        "#FF8C00":    "darkorange",
        "#FF8C69":    "salmon 1",
        "#FF9912":    "cadmiumyellow",
        "#FFA07A":    "lightsalmon 1 (lightsalmon)",
        "#FFA500":    "orange 1 (orange)",
        "#FFA54F":    "tan 1",
        "#FFAEB9":    "lightpink 1",
        "#FFB5C5":    "pink 1",
        "#FFB6C1":    "lightpink",
        "#FFB90F":    "darkgoldenrod 1",
        "#FFBBFF":    "plum 1",
        "#FFC0CB":    "pink",
        "#FFC125":    "goldenrod 1",
        "#FFC1C1":    "rosybrown 1",
        "#FFD39B":    "burlywood 1",
        "#FFD700":    "gold 1 (gold)",
        "#FFDAB9":    "peachpuff 1 (peachpuff)",
        "#FFDEAD":    "navajowhite 1 (navajowhite)",
        "#FFE1FF":    "thistle 1",
        "#FFE4B5":    "moccasin",
        "#FFE4C4":    "bisque 1 (bisque)",
        "#FFE4E1":    "mistyrose 1 (mistyrose)",
        "#FFE7BA":    "wheat 1",
        "#FFEBCD":    "blanchedalmond",
        "#FFEC8B":    "lightgoldenrod 1",
        "#FFEFD5":    "papayawhip",
        "#FFEFDB":    "antiquewhite 1",
        "#FFF0F5":    "lavenderblush 1 (lavenderblush)",
        "#FFF5EE":    "seashell 1 (seashell)",
        "#FFF68F":    "khaki 1",
        "#FFF8DC":    "cornsilk 1 (cornsilk)",
        "#FFFACD":    "lemonchiffon 1 (lemonchiffon)",
        "#FFFAF0":    "floralwhite",
        "#FFFAFA":    "snow 1 (snow)",
        "#FFFF00":    "yellow 1 (yellow*)",
        "#FFFFE0":    "lightyellow 1 (lightyellow)",
        "#FFFFF0":    "ivory 1 (ivory)",
        "#FFFFFF":    "white*"
    ]
    
    static func hexString(_ color:UIColor) -> String {
        var red:CGFloat = 0
        var blue:CGFloat = 0
        var green:CGFloat = 0
        var alpha:CGFloat = 0
        color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        let colorVal:Int = (Int)(red*255)<<16 | (Int)(green*255)<<8 | (Int)(blue*255)<<0
        return String(format:"#%06X", colorVal)
    }
}
<file_sep>/PaletteDrop/Saved Palettes/SavedPaletteCell.swift
import UIKit

class SavedPaletteCell : UICollectionViewCell {
    
    var colors = [UIColor]()
    
    var savedPalettesView: SavedPaletteDesign?
    
    override func draw(_ rect: CGRect) {
        // PaletteDesign.drawBackground_MaskCanvas(frame: frame, resizing:  PaletteDesign.ResizingBehavior.center);
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        //        view.backgroundColor = .yellow
    }
    
    override func layoutSubviews() {
        if savedPalettesView == nil {
            let view = SavedPaletteDesign(frame: bounds)
            view.backgroundColor = UIColor(red: (41.0/255), green: (43.0/255), blue: (45.0/255), alpha: 1.0)
            addSubview(view)
            savedPalettesView = view
        }
        if colors.count > 0 {
            savedPalettesView?.colors = colors;
            savedPalettesView?.setNeedsDisplay();
        }
    }
    
}
<file_sep>/PaletteDrop/Colour Wheel/ColorWheel.swift
////  ColorWheel.swift
// Created: 2019-06-19
//


import UIKit

//source: https://stackoverflow.com/questions/12770181/how-to-get-the-pixel-color-on-touch

protocol ColorChange: AnyObject {
    func colorChangedTo(changeColor: UIColor)
}

class ColorWheel: UIImageView {
    
    weak var delegate:ColorChange?
    var feedbackGenerator:UISelectionFeedbackGenerator?
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//        let touch = touches.first
//        if let point = touch?.location(in: self) {
//            let color = self.getPixelColorAtPoint(point: point)
//            if let color = color {
//                print(color)
//                delegate?.colorChangedTo(changeColor: color)
//            }
//        }
        self.alpha = 1
        feedbackGenerator = UISelectionFeedbackGenerator()
        feedbackGenerator?.prepare()
        super.touchesBegan(touches, with: event)
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        if let point = touch?.location(in: self) {
            if(self.point(inside: point, with: event)) {
                let color = self.getPixelColorAtPoint(point: point)
                if let color = color {
                    print(color)
                    delegate?.colorChangedTo(changeColor: color)
                    colorGeneratesHaptics(color)
                }
            }
        }
        super.touchesMoved(touches, with: event)
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        feedbackGenerator = nil
        UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: {
            self.alpha = 0.3
        }, completion: nil)
        super.touchesEnded(touches, with: event)
    }
    
    func getPixelColorAtPoint(point:CGPoint) -> UIColor?{
        let pixel = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: 4)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
        let context = CGContext(data: pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
        var color: UIColor? = nil
        
        if let context = context {
            context.translateBy(x: -point.x, y: -point.y)
            self.layer.render(in: context)
            
            color = UIColor(red: CGFloat(pixel[0])/255.0,
                            green: CGFloat(pixel[1])/255.0,
                            blue: CGFloat(pixel[2])/255.0,
                            alpha: CGFloat(pixel[3])/255.0)
            
            pixel.deallocate()
        }
        return color
    }
    
    func colorGeneratesHaptics(_ color:UIColor) {
        var red:CGFloat = 0
        var blue:CGFloat = 0
        var green:CGFloat = 0
        var alpha:CGFloat = 0
        color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        red = round(red * 10)
        green = round(green * 10)
        blue = round(blue * 10)
        if red == blue || red == green || blue == green {
            print("Haptics!!!")
            feedbackGenerator?.selectionChanged()
            feedbackGenerator?.prepare()
        }
    }
}
<file_sep>/PaletteDrop/PaletteExport.swift
////  Palette+Export.swift
// Created: 2019-06-23
//


import Foundation

class PaletteExport {
    
    let palette:Palette
    
    init(withPalette palette:Palette) {
        self.palette = palette
    }
    
    func text() -> String {
        var colorString = ""
        for color in palette.colors {
            colorString += Colors.hexString(color)
            if color != palette.colors.last {
                colorString += ", "
            }
        }
        return colorString
    }
    
    func textWithPaletteName() -> String {
        return palette.name + ": " + text()
    }
    
    func image(size:CGSize = CGSize(width: 256,height: 64)) -> UIImage? {
        UIGraphicsBeginImageContext(size)
        let width = size.width/CGFloat(palette.colors.count)
        for i in 0..<palette.colors.count {
            let baseColourPath = UIBezierPath(rect: CGRect(x: CGFloat(i) * width, y: 0, width: width, height: size.height))
            palette.colors[i].setFill()
            baseColourPath.fill()
        }
        
        let myImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return myImage
    }
}
<file_sep>/PaletteDrop/Palettes/PaletteCell.swift
import UIKit

class PaletteCell : UITableViewCell {
    var colors = [UIColor]()
    
    var paletteView: PaletteDesignView?
    
    override func draw(_ rect: CGRect) {
        // PaletteDesign.drawBackground_MaskCanvas(frame: frame, resizing:  PaletteDesign.ResizingBehavior.center);
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
//        view.backgroundColor = .yellow
    }
    
    override func layoutSubviews() {
        if paletteView == nil {
            let view = PaletteDesignView(frame: bounds)
            view.backgroundColor = UIColor(red: (41.0/255), green: (43.0/255), blue: (45.0/255), alpha: 1.0)
            addSubview(view)
            paletteView = view
        } 
        if colors.count > 0 {
            paletteView?.colors = colors;
            paletteView?.setNeedsDisplay();
        }
    }
    // rgb(41,43,45)
    func addPaletteView() {
        
    }
}

<file_sep>/PaletteDrop/Colour Wheel/ColourWheelView.swift
////  ViewController.swift
// Created: 2019-06-19
//


import UIKit

class ColourWheelView: UIViewController, ColorChange {

    

    @IBOutlet weak var colorWheel: ColorWheel!
    @IBOutlet weak var selectedColourButton: UIButton!

    let ioColorMindNamingService = IOColorMindNamingService.defaultInstance()
    override func viewDidLoad() {
        super.viewDidLoad()

//        let button = UIButton(type: .custom)
//        button.frame = CGRect(x: 160, y: 100, width: 50, height: 50)
//        button.layer.cornerRadius = 0.5 * button.bounds.size.width
//        button.clipsToBounds = true
//        button.setImage(UIImage(named:"thumbsUp.png"), for: .normal)
//        button.addTarget(self, action: #selector(thumbsUpButtonPressed), for: .touchUpInside)
//        view.addSubview(button)
        
//        selectedColourButton.layer.borderWidth = 7.
//        selectedColourButton.frame = CGRect(50, 8, 120, 120)
//        selectedColourButton.layer.cornerRadius = selectedColourButton.frame.width/2
//        selectedColourButton.layer.masksToBounds = true
//        colorWheel.delegate = self
        
        selectedColourButton.frame = CGRect(x: 160, y: 160, width: 160, height: 160)
        selectedColourButton.layer.cornerRadius = 0.5 * selectedColourButton.bounds.size.width
        selectedColourButton.layer.masksToBounds = true
        colorWheel.delegate = self
        self.navigationItem.setHidesBackButton(true, animated:true);
       
        
    }
    
//    @objc dynamic public class func drawCanvas1(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 150, height: 150)) {
//        //// General Declarations
//        let context = UIGraphicsGetCurrentContext()!
//
//        //// Image Declarations
//        let selectedColour = UIImage(named: "selectedColour.png")!
//
//        //// Oval Drawing
//        let ovalPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 150, height: 150))
//        context.saveGState()
//        ovalPath.addClip()
//        context.scaleBy(x: 1, y: -1)
//        context.draw(selectedColour.cgImage!, in: CGRect(x: 0, y: 0, width: selectedColour.size.width, height: selectedColour.size.height), byTiling: true)
//        context.restoreGState()
//
//        context.restoreGState()
//
//    }

    func colorChangedTo(changeColor: UIColor) {
        selectedColourButton.backgroundColor = changeColor
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "paletteSegue" {
            let palettesTableView = segue.destination as! PalettesTableView
            palettesTableView.coreColor = selectedColourButton.backgroundColor
        }
        
    }
    
    //Mark: Hide Navigation
    
//    override func viewWillAppear(_ animated: Bool) {
//        super.viewWillAppear(animated)
//        navigationController?.setNavigationBarHidden(true, animated: animated)
//    }
//    
//    override func viewWillDisappear(_ animated: Bool) {
//        super.viewWillDisappear(animated)
//        navigationController?.setNavigationBarHidden(false, animated: animated)
//    }

}

<file_sep>/PaletteDrop/Generators.swift
////  Generators.swift
// Created: 2019-06-21
//


import Foundation

protocol PaletteViewerDelegate {
    func didUpdatePalette(forTag: Int, palette: Palette);
}

class Generators : PaletteGeneratorDelegate {

    var delegate:PaletteViewerDelegate? = nil;
    var generators:[Int:PaletteGenerator] = [:]
    var baseColor:UIColor = UIColor()
    
    
    func generatorInstanceFromString(_ className: String) -> PaletteGenerator? {
        /// get namespace
        //let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String;
        
        /// get 'anyClass' with classname and namespace\(namespace).\(className)
        guard let classType = NSClassFromString(className)
            as? (NSObject).Type else {
            return nil
            
        }
        let generator = classType.init()
        if let generator = generator as? PaletteGenerator {
            return generator
        }
        return nil
    }
    

    func register(generator className: String, withTag tag:Int, forPalette paletteName:String = "") {
        if let generator = generatorInstanceFromString(className) {
            generators[tag] = generator
            generator.name = paletteName
            generator.tag = tag
            generator.delegate = self
        }
    }
    
    func generateAllForColor(_ color:UIColor) {
        for (_ , generator) in generators {
            generator.baseColors = [color]
            generator.generate()
        }
    }
    
    func didGeneratePalette(forTag tag: Int) {
        guard let generator = generators[tag], let delegate = self.delegate else {
            return;
        }
        let palette = Palette(name:generator.name, andColors:generator.generatedPalette)
        
        delegate.didUpdatePalette(forTag: tag, palette: palette)
        
    }
    
    
}

<file_sep>/PaletteDrop/PaletteImageService.swift
////  PaletteImageService.swift
// Created: 2019-06-23
//

import Foundation
import UIKit


struct PaletteImage {
    var image:UIImage? = nil
    let url:URL?
    let width:Int
    let height:Int
    let distance:Double
    let title:String
    let creator:String
    let year:String
    var palette = [[Int]]()
}

class PaletteImageMatcher {
    var images = [PaletteImage]()
    var enumeratedIndex:Int = 0;
    var downloadIndex:Int = 0;
    let defaultSession = URLSession(configuration: .default)
    var dataTask: URLSessionDataTask?
    
    //will be called from the main thread
    func nextImage()->PaletteImage? {
        for index in enumeratedIndex..<images.count {
            if images[index].image != nil {
                enumeratedIndex = index + 1
                print("Sending image \(index)")
                return images[index]
            }
        }

        //Didn't find a match - rotate back to 0
        for index in 0..<enumeratedIndex {
            if images[index].image != nil {
                enumeratedIndex = index + 1
                print("[R] Sending image \(index)")
                return images[index]
            }
        }
      
        return nil
    }
    
    //will be called in background thread
    func downloadNext() {
        guard downloadIndex < images.count else {
            return
        }
        dataTask?.cancel()
        if let url = images[downloadIndex].url {
            print("Downloading image \(url)")
            dataTask = defaultSession.dataTask(with:url) {
                data, response, error in
                defer {
                    self.dataTask = nil
                }
                
                if let error = error {
                    print( "Image Download error: " + error.localizedDescription + "\n")
                } else if let data = data,
                    let response = response as? HTTPURLResponse,
                    response.statusCode == 200 {
                    self.images[self.downloadIndex].image = UIImage.init(data:data)
                    self.downloadIndex+=1;
                    self.downloadNext()
                    // DispatchQueue.main.async {}
                }
            }
            dataTask?.resume()
        } else {
            downloadNext()
        }
    }
    
    func hasImages()->Bool {
        return downloadIndex > 0
    }
}


class PaletteImageService {
    
    let defaultSession = URLSession(configuration: .default)
    var dataTask: URLSessionDataTask?
    
    func getMatchingImages(_ palette:Palette) -> PaletteImageMatcher? {
        var paletteString:String = ""
        for color in palette.colors {
            var hexString = Colors.hexString(color).suffix(6).lowercased()
            paletteString += hexString
            if color != palette.colors.last {
                paletteString.append("-")
            }
        }
        var matcher = PaletteImageMatcher()
        dataTask?.cancel()
        let baseUrl = NSLocalizedString("googleURL", tableName: "Colors", bundle: Bundle.main, value: "", comment: "")
        guard let url = URL(string:baseUrl + paletteString) else {
            return nil
        }
        dataTask = defaultSession.dataTask(with: url) {
            data, response, error in
            defer { self.dataTask = nil }
            // 5
            if let error = error {
                print ("Service Error: " + error.localizedDescription + "\n")
            } else if let data = data,
                let response = response as? HTTPURLResponse,
                response.statusCode == 200 {
                if let result=try? JSONSerialization.jsonObject(with: data.subdata(in: 6..<data.count), options: [.allowFragments]) as? [AnyObject] {
                    for imageInfo in result[0..<5] {
                        guard let info = imageInfo as? [String:AnyObject] else {
                            continue
                        }
                        let width = info["imageWidthPx"] as? Int ?? 0
                        let distance = info["distance"] as? Double ?? 0
                        let title = info["title"] as? String ?? ""
                        let height = info["imageHeightPx"] as? Int ?? 0
                        var url:URL?
                        if let imageUrl = info["imageUrl"] as? String {
                            url = URL(string:imageUrl)
                        }
                        let year = info["date"] as? String ?? ""
                        let creator = info["creator"] as? String ?? ""
                        var colorPalette = [[Int]]()
                        if let colors = info["palette"] as? [AnyObject] {
                            for color in colors  {
                                    if let color = color as? [String:Int] {
                                    var rgb = [Int]()
                                    for (_,v) in color {
                                        rgb.append(v)
                                    }
                                    colorPalette.append(rgb)
                                }
                            }
                        }
                        let paletteImage = PaletteImage(image: nil, url: url, width: width, height: height, distance: distance, title: title, creator: creator, year:year, palette: colorPalette)

                        matcher.images.append(paletteImage)
                    }
                    matcher.downloadNext()
                }
            } else {
                if let response = response as? HTTPURLResponse {
                    print("Failed to query:\(response.statusCode)")
                }
            }
        }
        dataTask?.resume()
        return matcher
    }
}
<file_sep>/PaletteDrop/Colours/ColourCell.swift
import UIKit

class ColourCell : UITableViewCell {
    
    
    
}
<file_sep>/PaletteDrop/Palettes/PaletteDesign.swift
import UIKit

class PaletteDesignView : UIView {
    
    var colors = [
        UIColor(red: 0.514, green: 0.612, blue: 0.847, alpha: 1.000),
        UIColor(red: 0.082, green: 0.090, blue: 0.161, alpha: 1.000),
        UIColor(red: 0.757, green: 0.541, blue: 0.769, alpha: 1.000),
        UIColor(red: 0.643, green: 0.267, blue: 0.380, alpha: 1.000),
        UIColor(red: 0.380, green: 0.314, blue: 0.506, alpha: 1.000)
    ];
    
    var resizing: ResizingBehavior = .aspectFit
    
    // Drawing Methods
    
    override func draw(_ rect: CGRect) {
        // General Declarations
        let context = UIGraphicsGetCurrentContext()!
        // Resize to Target Frame
        context.saveGState()
        let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 379, height: 104), target: frame)
        context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
        context.scaleBy(x: resizedFrame.width / 379, y: resizedFrame.height / 104)
        
        
        // Grey Background: Color Declarations
        let strokeColor = UIColor(red: 0.208, green: 0.216, blue: 0.220, alpha: 1.000)
        //let fillColor = UIColor(red: 0.514, green: 0.612, blue: 0.847, alpha: 1.000)
        //let fillColor2 = UIColor(red: 0.082, green: 0.090, blue: 0.161, alpha: 1.000)
        //let fillColor3 = UIColor(red: 0.757, green: 0.541, blue: 0.769, alpha: 1.000)
        //let fillColor4 = UIColor(red: 0.643, green: 0.267, blue: 0.380, alpha: 1.000)
        //let fillColor5 = UIColor(red: 0.380, green: 0.314, blue: 0.506, alpha: 1.000)
        
        ///First Colour: User selected colour
        let baseColourPath = UIBezierPath(ovalIn: CGRect(x: 8, y: 8, width: 125, height: 88))
        colors[0].setFill()
        baseColourPath.fill()
        
        // Second Colour
        let lightestColourPath = UIBezierPath(ovalIn: CGRect(x: 74, y: 8, width: 117, height: 88))
        colors[1].setFill()
        lightestColourPath.fill()
        
        // Third Colour
        let midColour_OnePath = UIBezierPath(ovalIn: CGRect(x: 133, y: 8, width: 117, height: 88))
        colors[2].setFill()
        midColour_OnePath.fill()
        
        // Fourth Colour
        let midColour_TwoPath = UIBezierPath(ovalIn: CGRect(x: 197, y: 8, width: 111, height: 88))
        colors[3].setFill()
        midColour_TwoPath.fill()
        
        // Fifth Colour
        let darkestColourPath = UIBezierPath(ovalIn: CGRect(x: 258, y: 8, width: 113, height: 88))
        colors[4].setFill()
        darkestColourPath.fill()
        
        // Paths
        let pathPath = UIBezierPath(roundedRect: CGRect(x: 8, y: 8, width: 363, height: 88), cornerRadius: 44)
        strokeColor.setStroke()
        pathPath.lineWidth = 15
        pathPath.stroke()
        
        context.restoreGState()
        
    }
    
    @objc(PaletteSVGResizingBehavior)
    public enum ResizingBehavior: Int {
        case aspectFit /// The content is proportionally resized to fit into the target rectangle.
        case aspectFill /// The content is proportionally resized to completely fill the target rectangle.
        case stretch /// The content is stretched to match the entire target rectangle.
        case center /// The content is centered in the target rectangle, but it is NOT resized.
        
        public func apply(rect: CGRect, target: CGRect) -> CGRect {
            if rect == target || target == CGRect.zero {
                return rect
            }
            
            var scales = CGSize.zero
            scales.width = abs(target.width / rect.width)
            scales.height = abs(target.height / rect.height)
            
            switch self {
            case .aspectFit:
                scales.width = min(scales.width, scales.height)
                scales.height = scales.width
            case .aspectFill:
                scales.width = max(scales.width, scales.height)
                scales.height = scales.width
            case .stretch:
                break
            case .center:
                scales.width = 1
                scales.height = 1
            }
            
            var result = rect.standardized
            result.size.width *= scales.width
            result.size.height *= scales.height
            result.origin.x = target.minX + (target.width - result.width) / 2
            result.origin.y = target.minY + (target.height - result.height) / 2
            return result
        }
    }
}
<file_sep>/PaletteDrop/Colours/ColoursTableView.swift
import UIKit

class ColoursTableView: UITableViewController {
    
    var palette = Palette()
    let paletteImageService = PaletteImageService();
    var matcher:PaletteImageMatcher?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        tableView.separatorStyle = .none
        
        if palette.colors.count > 0 {
            matcher = paletteImageService.getMatchingImages(palette)
        }
            
        
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let frame = self.view.safeAreaLayoutGuide.layoutFrame
        return frame.height / 5
    }
    
    // Mark: Animation When Cells Appear
    
    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        // Add animations here
        cell.alpha = 0
        
        UIView.animate(
            withDuration: 1.0,
            delay: 0.1 * Double(indexPath.row),
            options: [.curveEaseInOut],
            animations: {
                cell.alpha = 1
        })
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return palette.colors.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "coloursCell", for: indexPath)
        if palette.colors.count > 0 {
            cell.backgroundColor = palette.colors[indexPath.row]
        }
        return cell
    }
    
    @IBAction func willStorePaletteInDatabase(_ sender: Any) {
        PaletteStore.defaultInstance().save(palette)
        
        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        let savedPalettesCollectionView = storyBoard.instantiateViewController(withIdentifier: "savedPaletteCollectionView") as! SavedPalettesCollectionView
        self.navigationController?.pushViewController(savedPalettesCollectionView, animated: true)
    }
    
    
    // We are willing to become first responder to get shake motion
    override var canBecomeFirstResponder: Bool {
        get {
            return true
        }
    }
    
    // Enable detection of shake motion
    override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        guard let matcher = self.matcher, matcher.hasImages() else {
            return;
        }
        
        if motion == .motionShake {
            let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
            let paletteImageView = storyBoard.instantiateViewController(withIdentifier: "paletteImageView") as! PaletteImageView
            paletteImageView.matcher = self.matcher
            self.navigationController?
                .pushViewController(paletteImageView, animated: true)
        }
    }
}
<file_sep>/PaletteDrop/Saved Palettes/SavedPalettesCollectionView.swift
import UIKit

class SavedPalettesCollectionView: UICollectionViewController, PaletteViewerDelegate {
    
    func didUpdatePalette(forTag: Int, palette: Palette) {
        palettes[forTag] = palette
        collectionView.reloadData()
    }
    
    var generators:Generators?;
    var coreColor:UIColor?
    var palettes = [Palette]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        palettes = PaletteStore.defaultInstance().loadAllPalettes()
    }
    
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1;
    }
    
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return palettes.count;
    }
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "savedPaletteCell", for: indexPath) as! SavedPaletteCell
        if indexPath.row < palettes.count {
            let palette = palettes[indexPath.row]
            cell.colors = palette.colors
        }
        return cell;
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "coloursSegue-2" {
            let colorsTableView = segue.destination as! ColoursTableView
            if let segueCell = sender as? UICollectionViewCell {
                if let index = self.collectionView.indexPath(for:segueCell),
                    index.row < palettes.count {
                    colorsTableView.palette = palettes[index.row]
                }
            }
        }
    }
    @IBAction func onExportAction(_ sender: Any) {
        let title = "[PaletteDrop]\t\n"
        var activityItems = [Any]()
        activityItems.append(title)
        for palette in self.palettes {
            let export = PaletteExport.init(withPalette: palette)
            activityItems.append("\(export.text())\t\n")
            activityItems.append(export.image() as Any)
        }
        let activityViewController:UIActivityViewController = UIActivityViewController(activityItems:  activityItems, applicationActivities: nil)
        //activityViewController.excludedActivityTypes = [ UIActivityTypeAddToReadingList, UIActivityTypePostToVimeo]
        self.present(activityViewController, animated: true, completion: nil)
    }
}

<file_sep>/PaletteDrop/Palettes/PalettesTableView.swift
import UIKit

class PalettesTableView: UITableViewController, PaletteViewerDelegate {
    
    var generators:Generators?;
    var coreColor:UIColor?
    var palettes = [Palette]()
    let ioColorMindNamingService = IOColorMindNamingService.defaultInstance()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let placeHolderPalette = Palette(name: "HardCoded",
                andColors: [UIColor.clear, UIColor.clear, UIColor.clear, UIColor.clear, UIColor.clear])
       
        if let coreColor = self.coreColor {
            generators = Generators()
            generators!.delegate = self;
            
            for i in 0..<ioColorMindNamingService.names.count {
                palettes.append(placeHolderPalette)
                generators!.register(generator: "IOColorMindGenerator", withTag: i, forPalette: ioColorMindNamingService.names[i])
                
            }
            generators!.generateAllForColor(coreColor)
        }
    
        // Do any additional setup after loading the view.
        
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let frame = self.view.safeAreaLayoutGuide.layoutFrame
        return frame.height / 5
    }
    
    func didUpdatePalette(forTag: Int, palette: Palette) {
        palettes[forTag] = palette
        tableView.reloadData()
    }
    
    
    // Mark: Animation When Cells Appear
    
    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        // Add animations here
        cell.alpha = 0
        
        UIView.animate(
            withDuration: 1.0,
            delay: 0.1 * Double(indexPath.row),
            options: [.curveEaseInOut],
            animations: {
                cell.alpha = 1
        })
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1;
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5;
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "palettesCell", for: indexPath) as! PaletteCell
        if indexPath.row < palettes.count {
            let palette = palettes[indexPath.row]
            cell.colors = palette.colors
        }
        return cell;
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "coloursSegue-1" {
            let colorsTableView = segue.destination as! ColoursTableView
            if let selectedIndex = self.tableView.indexPathForSelectedRow, selectedIndex.row < palettes.count {
                colorsTableView.palette = palettes[selectedIndex.row]
            }
        }
    }
    
}
