[
  {
    "path": "README.md",
    "content": "# shoppingCart\n\n## swift的购物车demo\n采用纯代码UI，autolayout自动布局，core animation动画效果。\n\n![image](https://github.com/6ag/shoppingCart/blob/master/shoppingCart.gif)\n\n\n"
  },
  {
    "path": "shoppingCart/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  shoppingCart\n//\n//  Created by jianfeng on 15/11/17.\n//  Copyright © 2015年 六阿哥. All rights reserved.\n//\n\nimport UIKit\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {\n        \n        // 手动创建window\n        window = UIWindow(frame: UIScreen.mainScreen().bounds)\n        \n        // 设置window的根控制器\n        window?.rootViewController = UINavigationController(rootViewController: JFGoodListViewController())\n        \n        // 设置window为主window并显示在窗口\n        window?.makeKeyAndVisible()\n        \n        return true\n    }\n\n    func applicationWillResignActive(application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(application: UIApplication) {\n        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n\n"
  },
  {
    "path": "shoppingCart/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/add_icon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"add_icon@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/button_cart.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"button_cart@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/button_cart_add.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"button_add_cart.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/check_n.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"check_n@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/check_y.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"check_p@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/delete_icon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"delete_icon@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_0.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_0.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_1.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_1.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_2.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_2.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_3.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_3.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_4.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_4.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_5.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_5.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_6.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_6.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_7.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_7.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_8.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_8.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/goodicon_9.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"goodicon_9.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/numbe_bg_icon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"numbe_bg_icon@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Assets.xcassets/subtraction_icon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"jian_icon@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "shoppingCart/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"9059\" systemVersion=\"15B42\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"9049\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Llm-lL-Icb\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xb3-aO-Qok\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"600\" height=\"600\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <animations/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-414\" y=\"382\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "shoppingCart/Classes/GoodList/Controller/JFGoodListViewController.swift",
    "content": "//\n//  JFGoodListViewController.swift\n//  shoppingCart\n//\n//  Created by jianfeng on 15/11/17.\n//  Copyright © 2015年 六阿哥. All rights reserved.\n//\n\nimport UIKit\n\n// 屏幕尺寸\nlet SCREEN_WIDTH = UIScreen.mainScreen().bounds.size.width\nlet SCREEN_HEIGHT = UIScreen.mainScreen().bounds.size.height\n\nclass JFGoodListViewController: UIViewController {\n    \n    // MARK: - 属性\n    /// 商品模型数组，初始化\n    private var goodArray = [JFGoodModel]()\n    \n    /// 商品列表cell的重用标识符\n    private let goodListCellIdentifier = \"goodListCell\"\n    \n    /// 已经添加进购物车的商品模型数组，初始化\n    private var addGoodArray = [JFGoodModel]()\n    \n    /// 贝塞尔曲线\n    private var path: UIBezierPath?\n    \n    /// 自定义图层\n    var layer: CALayer?\n    \n    // MARK: - view生命周期\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        // 提醒：这个方法中一般用于初始化控制器中的一些数据、添加子控件等。但是这个方法获取的frame并不一定准确，所以不建议在这个方法约束子控件\n        \n        // 初始化模型数组，也就是搞点假数据。这里整10个模型\n        for i in 0..<10 {\n            var dict = [String : AnyObject]()\n            dict[\"iconName\"] = \"goodicon_\\(i)\"\n            dict[\"title\"] = \"\\(i + 1)阿哥\"\n            dict[\"desc\"] = \"这是第\\(i + 1)个商品\"\n            dict[\"newPrice\"] = \"1000\\(i)\"\n            dict[\"oldPrice\"] = \"2000\\(i)\"\n            \n            // 字典转模型并将模型添加到模型数组中\n            goodArray.append(JFGoodModel(dict: dict))\n        }\n        \n        // 准备子控件\n        prepareUI()\n        \n    }\n    \n    override func viewWillAppear(animated: Bool) {\n        super.viewWillAppear(animated)\n        \n        // 提示：这个方法是在控制器view已经显示后调用，我们可以在这个方法里面做一些子控件约束操作等\n        \n        // 约束子控件\n        layoutUI()\n    }\n    \n    /**\n     准备子控件方法，在这个方法中我们可以创建并添加子控件到view\n     */\n    private func prepareUI() {\n        \n        // 标题\n        navigationItem.title = \"商品列表\"\n        \n        // 添加导航栏上的购物车按钮和已经添加的商品数量label\n        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: cartButton)\n        \n        // 添加购物车按钮上的label\n        navigationController?.navigationBar.addSubview(addCountLabel)\n        navigationController?.navigationBar.barTintColor = UIColor.whiteColor()\n        \n        // 添加tableView到控制器的view上\n        view.addSubview(tableView)\n        \n        // 注册cell\n        tableView.registerClass(JFGoodListCell.self, forCellReuseIdentifier: goodListCellIdentifier)\n    }\n    \n    /**\n     约束子控件的方法\n     */\n    private func layoutUI() {\n        \n        // 约束tableview，让它全屏显示。注意：这里我使用了第三方约束框架（SnapKit）。如果还不会使用，请学习\n        tableView.snp_makeConstraints { (make) -> Void in\n            make.edges.equalTo(view.snp_edges)\n        }\n        \n        addCountLabel.snp_makeConstraints { (make) -> Void in\n            make.right.equalTo(-12)\n            make.top.equalTo(10.5)\n            make.width.equalTo(15)\n            make.height.equalTo(15)\n        }\n    }\n\n    // MARK: - 懒加载\n    /// tableView\n    lazy var tableView: UITableView = {\n        let tableView = UITableView()\n        tableView.rowHeight = 80\n        // 指定数据源和代理\n        tableView.dataSource = self\n        tableView.delegate = self\n        \n        return tableView\n    }()\n    \n    /// cartButton顶部购物车按钮\n    lazy var cartButton: UIButton = {\n        let carButton = UIButton(type: UIButtonType.Custom)\n        carButton.setImage(UIImage(named: \"button_cart\"), forState: UIControlState.Normal)\n        carButton.addTarget(self, action: \"didTappedCarButton:\", forControlEvents: UIControlEvents.TouchUpInside)\n        carButton.sizeToFit()\n        return carButton\n    }()\n    \n    /// 已经添加进购物车的商品数量\n    lazy var addCountLabel: UILabel = {\n        let addCountLabel = UILabel()\n        addCountLabel.backgroundColor = UIColor.whiteColor()\n        addCountLabel.textColor = UIColor.redColor()\n        addCountLabel.font = UIFont.boldSystemFontOfSize(11)\n        addCountLabel.textAlignment = NSTextAlignment.Center\n        addCountLabel.text = \"\\(self.addGoodArray.count)\"\n        addCountLabel.layer.cornerRadius = 7.5\n        addCountLabel.layer.masksToBounds = true\n        addCountLabel.layer.borderWidth = 1\n        addCountLabel.layer.borderColor = UIColor.redColor().CGColor\n        addCountLabel.hidden = true\n        return addCountLabel\n    }()\n\n}\n\n// MARK: - UITableViewDataSource, UITableViewDelegate 数据源和代理方法\nextension JFGoodListViewController: UITableViewDataSource, UITableViewDelegate {\n    \n    // 第section组有多少个cell,我们这里一共就一组。所以直接返回模型数组的长度\n    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return goodArray.count\n    }\n    \n    // 创建每个cell\n    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {\n        \n        // 从缓存池创建cell，如果没有从缓存池创建成功就根据注册的cell重用标识符创建一个新的cell\n        let cell = tableView.dequeueReusableCellWithIdentifier(goodListCellIdentifier, forIndexPath: indexPath) as! JFGoodListCell\n        \n        // 取消选中效果\n        cell.selectionStyle = UITableViewCellSelectionStyle.None\n        \n        // 为cell传递数据\n        cell.goodModel = goodArray[indexPath.row]\n        \n        // 指定代理\n        cell.delegate = self\n        \n        // 返回创建好的cell\n        return cell\n    }\n}\n\n// view上的一些事件处理在这个类扩展里\nextension JFGoodListViewController {\n    \n    /**\n     当点击了购物车触发，modal到购物车控制器\n     \n     - parameter button: 购物车按钮\n     */\n    @objc private func didTappedCarButton(button: UIButton) {\n        \n        let shoppingCartVc = JFShoppingCartViewController()\n        \n        // 传递商品模型数组\n        shoppingCartVc.addGoodArray = addGoodArray\n        \n        // 模态出一个购物车控制器\n        presentViewController(UINavigationController(rootViewController: shoppingCartVc), animated: true, completion: nil)\n    }\n}\n\n// MARK: - JFGoodListCellDelegate代理方法\nextension JFGoodListViewController: JFGoodListCellDelegate {\n    \n    /**\n     代理回调方法，当点击了cell上的购买按钮后触发\n     \n     - parameter cell:     被点击的cell\n     - parameter iconView: 被点击的cell上的图标对象\n     */\n    func goodListCell(cell: JFGoodListCell, iconView: UIImageView) {\n        \n        guard let indexPath = tableView.indexPathForCell(cell) else {\n            return\n        }\n        \n        // 获取当前模型，添加到购物车模型数组\n        let model = goodArray[indexPath.row]\n        addGoodArray.append(model)\n        \n        // 重新计算iconView的frame，并开启动画\n        var rect = tableView .rectForRowAtIndexPath(indexPath)\n        rect.origin.y -= tableView.contentOffset.y\n        var headRect = iconView.frame\n        headRect.origin.y = rect.origin.y + headRect.origin.y - 64\n        startAnimation(headRect, iconView: iconView)\n    }\n}\n\n// MARK: - 商品图片抛入购物车的动画效果\nextension JFGoodListViewController {\n    \n    /**\n     开始动画\n     - parameter rect:     商品图标对象的frame\n     - parameter iconView: 商品图标对象\n     */\n    private func startAnimation(rect: CGRect, iconView: UIImageView) {\n        if layer == nil {\n            layer = CALayer()\n            layer?.contents = iconView.layer.contents\n            layer?.contentsGravity = kCAGravityResizeAspectFill\n            layer?.bounds = rect\n            layer?.cornerRadius = CGRectGetHeight(layer!.bounds) * 0.5\n            layer?.masksToBounds = true\n            layer?.position = CGPoint(x: iconView.center.x, y: CGRectGetMinY(rect) + 96)\n            UIApplication.sharedApplication().keyWindow?.layer.addSublayer(layer!)\n            \n            path = UIBezierPath()\n            path!.moveToPoint(layer!.position)\n            path!.addQuadCurveToPoint(CGPoint(x: SCREEN_WIDTH - 25, y: 35), controlPoint: CGPoint(x: SCREEN_WIDTH * 0.5, y: rect.origin.y - 80))\n        }\n        \n        // 组动画\n        groupAnimation()\n    }\n    \n    /**\n     组动画，帧动画抛入购物车，并放大、缩小图层增加点动效。\n     */\n    private func groupAnimation() {\n        \n        // 开始动画禁用tableview交互\n        tableView.userInteractionEnabled = false\n        \n        // 帧动画\n        let animation = CAKeyframeAnimation(keyPath: \"position\")\n        animation.path = path!.CGPath\n        animation.rotationMode = kCAAnimationRotateAuto\n        \n        // 放大动画\n        let bigAnimation = CABasicAnimation(keyPath: \"transform.scale\")\n        bigAnimation.duration = 0.5\n        bigAnimation.fromValue = 1\n        bigAnimation.toValue = 2\n        bigAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)\n        \n        // 缩小动画\n        let smallAnimation = CABasicAnimation(keyPath: \"transform.scale\")\n        smallAnimation.beginTime = 0.5\n        smallAnimation.duration = 1.5\n        smallAnimation.fromValue = 2\n        smallAnimation.toValue = 0.3\n        smallAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)\n        \n        // 组动画\n        let groupAnimation = CAAnimationGroup()\n        groupAnimation.animations = [animation, bigAnimation, smallAnimation]\n        groupAnimation.duration = 2\n        groupAnimation.removedOnCompletion = false\n        groupAnimation.fillMode = kCAFillModeForwards\n        groupAnimation.delegate = self\n        layer?.addAnimation(groupAnimation, forKey: \"groupAnimation\")\n    }\n    \n    /**\n     动画结束后做一些操作\n     */\n    override func animationDidStop(anim: CAAnimation, finished flag: Bool) {\n        \n        // 如果动画是我们的组动画，才开始一些操作\n        if anim == layer?.animationForKey(\"groupAnimation\") {\n            \n            // 开启交互\n            tableView.userInteractionEnabled = true\n            \n            // 隐藏图层\n            layer?.removeAllAnimations()\n            layer?.removeFromSuperlayer()\n            layer = nil\n            \n            // 如果商品数大于0，显示购物车里的商品数量\n            if self.addGoodArray.count > 0 {\n                addCountLabel.hidden = false\n            }\n            \n            // 商品数量渐出\n            let goodCountAnimation = CATransition()\n            goodCountAnimation.duration = 0.25\n            addCountLabel.text = \"\\(self.addGoodArray.count)\"\n            addCountLabel.layer.addAnimation(goodCountAnimation, forKey: nil)\n            \n            // 购物车抖动\n            let cartAnimation = CABasicAnimation(keyPath: \"transform.translation.y\")\n            cartAnimation.duration = 0.25\n            cartAnimation.fromValue = -5\n            cartAnimation.toValue = 5\n            cartAnimation.autoreverses = true\n            cartButton.layer.addAnimation(cartAnimation, forKey: nil)\n        }\n    }\n}\n"
  },
  {
    "path": "shoppingCart/Classes/GoodList/View/JFGoodListCell.swift",
    "content": "//\n//  JFGoodListCell.swift\n//  shoppingCart\n//\n//  Created by jianfeng on 15/11/17.\n//  Copyright © 2015年 六阿哥. All rights reserved.\n//\n\nimport UIKit\n\nprotocol JFGoodListCellDelegate: NSObjectProtocol {\n    \n    func goodListCell(cell: JFGoodListCell, iconView: UIImageView)\n}\n\nclass JFGoodListCell: UITableViewCell {\n\n    // MARK: - 属性\n    /// 商品模型\n    var goodModel: JFGoodModel? {\n        didSet {\n            \n            if let iconName = goodModel?.iconName {\n                iconView.image = UIImage(named: iconName)\n            }\n            \n            if let title = goodModel?.title {\n                titleLabel.text = title\n            }\n            \n            if let desc = goodModel?.desc {\n                descLabel.text = desc\n            }\n\n            // 已经点击的就禁用,这样做是防止cell重用\n            addCartButton.enabled = !goodModel!.alreadyAddShoppingCart\n            \n            // 重新布局，会更新frame\n            layoutIfNeeded()\n            \n        }\n    }\n    \n    /// 代理属性\n    weak var delegate: JFGoodListCellDelegate?\n    \n    /// 回调给控制器的商品图标\n    var callBackIconView: UIImageView?\n    \n    // MARK: - 构造方法\n    required init?(coder aDecoder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }\n    \n    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {\n        super.init(style: style, reuseIdentifier: reuseIdentifier)\n        \n        // 准备UI\n        prepareUI()\n    }\n    \n    /**\n     准备UI\n     */\n    private func prepareUI() {\n        \n        // 添加子控件\n        contentView.addSubview(iconView)\n        contentView.addSubview(titleLabel)\n        contentView.addSubview(descLabel)\n        contentView.addSubview(addCartButton)\n        \n        // 约束子控件\n        iconView.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(12)\n            make.top.equalTo(10)\n            make.width.equalTo(60)\n            make.height.equalTo(60)\n        }\n        \n        titleLabel.snp_makeConstraints { (make) -> Void in\n            make.top.equalTo(contentView.snp_top).offset(10)\n            make.left.equalTo(iconView.snp_right).offset(12)\n        }\n        \n        descLabel.snp_makeConstraints { (make) -> Void in\n            make.top.equalTo(titleLabel.snp_bottom).offset(12)\n            make.left.equalTo(iconView.snp_right).offset(12)\n        }\n        \n        addCartButton.snp_makeConstraints { (make) -> Void in\n            make.right.equalTo(-12)\n            make.top.equalTo(25)\n            make.width.equalTo(80)\n            make.height.equalTo(30)\n        }\n        \n    }\n    \n    // MARK: - 响应事件\n    /**\n    点击了购买按钮的事件\n    \n    - parameter button: 购买按钮\n    */\n    @objc private func didTappedAddCartButton(button: UIButton) {\n        \n        // 已经购买\n        goodModel!.alreadyAddShoppingCart = true\n        \n        // 已经点击的就禁用\n        button.enabled = !goodModel!.alreadyAddShoppingCart\n        \n        // 通知代理对象，去处理后续操作\n        delegate?.goodListCell(self, iconView: iconView)\n    }\n    \n    // MARK: - 懒加载\n    /// 商品图片\n    private lazy var iconView: UIImageView = {\n        let iconView = UIImageView()\n        iconView.layer.cornerRadius = 30\n        iconView.layer.masksToBounds = true\n        return iconView\n    }()\n    \n    /// 商品标题\n    private lazy var titleLabel: UILabel = {\n        let titleLabel = UILabel()\n        \n        return titleLabel\n    }()\n    \n    /// 商品描述\n    private lazy var descLabel: UILabel = {\n        let descLabel = UILabel()\n        descLabel.textColor = UIColor.grayColor()\n        return descLabel\n    }()\n    \n    /// 添加按钮\n    private lazy var addCartButton: UIButton = {\n        let addCartButton = UIButton(type: UIButtonType.Custom)\n        addCartButton.setBackgroundImage(UIImage(named: \"button_cart_add\"), forState: UIControlState.Normal)\n        addCartButton.setTitle(\"购买\", forState: UIControlState.Normal)\n        \n        // 添加按钮点击事件\n        addCartButton.addTarget(self, action: \"didTappedAddCartButton:\", forControlEvents: UIControlEvents.TouchUpInside)\n        \n        return addCartButton\n    }()\n    \n}\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/Constraint.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\n/**\n    Used to expose API's for a Constraint\n*/\npublic class Constraint {\n    \n    public func install() -> [LayoutConstraint] { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func uninstall() -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func activate() -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func deactivate() -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    \n    public func updateOffset(amount: Float) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updateOffset(amount: Double) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updateOffset(amount: CGFloat) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updateOffset(amount: Int) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updateOffset(amount: UInt) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updateOffset(amount: CGPoint) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updateOffset(amount: CGSize) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updateOffset(amount: EdgeInsets) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    \n    public func updateInsets(amount: EdgeInsets) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    \n    public func updatePriority(priority: Float) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriority(priority: Double) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriority(priority: CGFloat) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriority(priority: UInt) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriority(priority: Int) -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriorityRequired() -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriorityHigh() -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriorityMedium() -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    public func updatePriorityLow() -> Void { fatalError(\"Must be implemented by Concrete subclass.\") }\n    \n    internal var makerLocation: SourceLocation = SourceLocation(file: \"Unknown\", line: 0)\n    \n    internal(set) public var location: SourceLocation?\n}\n\n/**\n    Used internally to implement a ConcreteConstraint\n*/\ninternal class ConcreteConstraint: Constraint {\n    \n    internal override func updateOffset(amount: Float) -> Void {\n        self.constant = amount\n    }\n    internal override func updateOffset(amount: Double) -> Void {\n        self.updateOffset(Float(amount))\n    }\n    internal override func updateOffset(amount: CGFloat) -> Void {\n        self.updateOffset(Float(amount))\n    }\n    internal override func updateOffset(amount: Int) -> Void {\n        self.updateOffset(Float(amount))\n    }\n    internal override func updateOffset(amount: UInt) -> Void {\n        self.updateOffset(Float(amount))\n    }\n    internal override func updateOffset(amount: CGPoint) -> Void {\n        self.constant = amount\n    }\n    internal override func updateOffset(amount: CGSize) -> Void {\n        self.constant = amount\n    }\n    internal override func updateOffset(amount: EdgeInsets) -> Void {\n        self.constant = amount\n    }\n    \n    internal override func updateInsets(amount: EdgeInsets) -> Void {\n        self.constant = EdgeInsets(top: amount.top, left: amount.left, bottom: -amount.bottom, right: -amount.right)\n    }\n    \n    internal override func updatePriority(priority: Float) -> Void {\n        self.priority = priority\n    }\n    internal override func updatePriority(priority: Double) -> Void {\n        self.updatePriority(Float(priority))\n    }\n    internal override func updatePriority(priority: CGFloat) -> Void {\n        self.updatePriority(Float(priority))\n    }\n    internal override func updatePriority(priority: UInt) -> Void {\n        self.updatePriority(Float(priority))\n    }\n    internal override func updatePriority(priority: Int) -> Void {\n        self.updatePriority(Float(priority))\n    }\n    internal override func updatePriorityRequired() -> Void {\n        self.updatePriority(Float(1000.0))\n    }\n    internal override func updatePriorityHigh() -> Void {\n        self.updatePriority(Float(750.0))\n    }\n    internal override func updatePriorityMedium() -> Void {\n        #if os(iOS) || os(tvOS)\n        self.updatePriority(Float(500.0))\n        #else\n        self.updatePriority(Float(501.0))\n        #endif\n    }\n    internal override func updatePriorityLow() -> Void {\n        self.updatePriority(Float(250.0))\n    }\n\n    internal override func install() -> [LayoutConstraint] {\n        return self.installOnView(updateExisting: false, location: self.makerLocation)\n    }\n\n    internal override func uninstall() -> Void {\n        self.uninstallFromView()\n    }\n\n    internal override func activate() -> Void {\n        guard self.installInfo != nil else {\n            self.install()\n            return\n        }\n        #if SNAPKIT_DEPLOYMENT_LEGACY\n        guard #available(iOS 8.0, OSX 10.10, *) else {\n            self.install()\n            return\n        }\n        #endif\n        let layoutConstraints = self.installInfo!.layoutConstraints.allObjects as! [LayoutConstraint]\n        if layoutConstraints.count > 0 {\n            NSLayoutConstraint.activateConstraints(layoutConstraints)\n        }\n    }\n\n    internal override func deactivate() -> Void {\n        guard self.installInfo != nil else {\n            return\n        }\n        #if SNAPKIT_DEPLOYMENT_LEGACY\n        guard #available(iOS 8.0, OSX 10.10, *) else {\n            return\n        }\n        #endif\n        let layoutConstraints = self.installInfo!.layoutConstraints.allObjects as! [LayoutConstraint]\n        if layoutConstraints.count > 0 {\n            NSLayoutConstraint.deactivateConstraints(layoutConstraints)\n        }\n    }\n    \n    private let fromItem: ConstraintItem\n    private let toItem: ConstraintItem\n    private let relation: ConstraintRelation\n    private let multiplier: Float\n    private var constant: Any {\n        didSet {\n            if let installInfo = self.installInfo {\n                for layoutConstraint in installInfo.layoutConstraints.allObjects as! [LayoutConstraint] {\n                    let attribute = (layoutConstraint.secondAttribute == .NotAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute\n                    layoutConstraint.constant = attribute.snp_constantForValue(self.constant)\n                }\n            }\n        }\n    }\n    private var priority: Float {\n        didSet {\n            if let installInfo = self.installInfo {\n                for layoutConstraint in installInfo.layoutConstraints.allObjects as! [LayoutConstraint] {\n                    layoutConstraint.priority = self.priority\n                }\n            }\n        }\n    }\n    \n    private var installInfo: ConcreteConstraintInstallInfo? = nil\n    \n    internal init(fromItem: ConstraintItem, toItem: ConstraintItem, relation: ConstraintRelation, constant: Any, multiplier: Float, priority: Float, location: SourceLocation?) {\n        self.fromItem = fromItem\n        self.toItem = toItem\n        self.relation = relation\n        self.constant = constant\n        self.multiplier = multiplier\n        self.priority = priority\n        super.init()\n        self.location = location\n    }\n    \n    internal func installOnView(updateExisting updateExisting: Bool = false, location: SourceLocation? = nil) -> [LayoutConstraint] {\n        var installOnView: View? = nil\n        if self.toItem.view != nil {\n            installOnView = closestCommonSuperviewFromView(self.fromItem.view, toView: self.toItem.view)\n            if installOnView == nil {\n                NSException(name: \"Cannot Install Constraint\", reason: \"No common superview between views (@\\(self.makerLocation.file)#\\(self.makerLocation.line))\", userInfo: nil).raise()\n                return []\n            }\n        } else {\n            \n            if self.fromItem.attributes.isSubsetOf(ConstraintAttributes.Width.union(.Height)) {\n                installOnView = self.fromItem.view\n            } else {\n                installOnView = self.fromItem.view?.superview\n                if installOnView == nil {\n                    NSException(name: \"Cannot Install Constraint\", reason: \"Missing superview (@\\(self.makerLocation.file)#\\(self.self.makerLocation.line))\", userInfo: nil).raise()\n                    return []\n                }\n            }\n        }\n        \n        if let installedOnView = self.installInfo?.view {\n            if installedOnView != installOnView {\n                NSException(name: \"Cannot Install Constraint\", reason: \"Already installed on different view. (@\\(self.makerLocation.file)#\\(self.makerLocation.line))\", userInfo: nil).raise()\n                return []\n            }\n            return self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint] ?? []\n        }\n        \n        var newLayoutConstraints = [LayoutConstraint]()\n        let layoutFromAttributes = self.fromItem.attributes.layoutAttributes\n        let layoutToAttributes = self.toItem.attributes.layoutAttributes\n        \n        // get layout from\n        let layoutFrom: View? = self.fromItem.view\n        \n        // get layout relation\n        let layoutRelation: NSLayoutRelation = self.relation.layoutRelation\n        \n        for layoutFromAttribute in layoutFromAttributes {\n            // get layout to attribute\n            let layoutToAttribute = (layoutToAttributes.count > 0) ? layoutToAttributes[0] : layoutFromAttribute\n            \n            // get layout constant\n            let layoutConstant: CGFloat = layoutToAttribute.snp_constantForValue(self.constant)\n            \n            // get layout to\n            #if os(iOS) || os(tvOS)\n            var layoutTo: AnyObject? = self.toItem.view ?? self.toItem.layoutSupport\n            #else\n            var layoutTo: AnyObject? = self.toItem.view\n            #endif\n            if layoutTo == nil && layoutToAttribute != .Width && layoutToAttribute != .Height {\n                layoutTo = installOnView\n            }\n            \n            // create layout constraint\n            let layoutConstraint = LayoutConstraint(\n                item: layoutFrom!,\n                attribute: layoutFromAttribute,\n                relatedBy: layoutRelation,\n                toItem: layoutTo,\n                attribute: layoutToAttribute,\n                multiplier: CGFloat(self.multiplier),\n                constant: layoutConstant)\n            \n            // set priority\n            layoutConstraint.priority = self.priority\n            \n            // set constraint\n            layoutConstraint.snp_constraint = self\n            \n            newLayoutConstraints.append(layoutConstraint)\n        }\n        \n        // special logic for updating\n        if updateExisting {\n            // get existing constraints for this view\n            let existingLayoutConstraints = layoutFrom!.snp_installedLayoutConstraints.reverse()\n            \n            // array that will contain only new layout constraints to keep\n            var newLayoutConstraintsToKeep = [LayoutConstraint]()\n            \n            // begin looping\n            for layoutConstraint in newLayoutConstraints {\n                // layout constraint that should be updated\n                var updateLayoutConstraint: LayoutConstraint? = nil\n                \n                // loop through existing and check for match\n                for existingLayoutConstraint in existingLayoutConstraints {\n                    if existingLayoutConstraint == layoutConstraint {\n                        updateLayoutConstraint = existingLayoutConstraint\n                        break\n                    }\n                }\n                \n                // if we have existing one lets just update the constant\n                if updateLayoutConstraint != nil {\n                    updateLayoutConstraint!.constant = layoutConstraint.constant\n                }\n                    // otherwise add this layout constraint to new keep list\n                else {\n                    newLayoutConstraintsToKeep.append(layoutConstraint)\n                }\n            }\n            \n            // set constraints to only new ones\n            newLayoutConstraints = newLayoutConstraintsToKeep\n        }\n        \n        // add constraints\n        #if SNAPKIT_DEPLOYMENT_LEGACY && !os(OSX)\n        if #available(iOS 8.0, *) {\n            NSLayoutConstraint.activateConstraints(newLayoutConstraints)\n        } else {\n            installOnView!.addConstraints(newLayoutConstraints)\n        }\n        #else\n            NSLayoutConstraint.activateConstraints(newLayoutConstraints)\n        #endif\n        \n        // set install info\n        self.installInfo = ConcreteConstraintInstallInfo(view: installOnView, layoutConstraints: NSHashTable.weakObjectsHashTable())\n        \n        // store which layout constraints are installed for this constraint\n        for layoutConstraint in newLayoutConstraints {\n            self.installInfo!.layoutConstraints.addObject(layoutConstraint)\n        }\n        \n        // store the layout constraints against the layout from view\n        layoutFrom!.snp_installedLayoutConstraints += newLayoutConstraints\n        \n        // return the new constraints\n        return newLayoutConstraints\n    }\n    \n    internal func uninstallFromView() {\n        if let installInfo = self.installInfo,\n            let installedLayoutConstraints = installInfo.layoutConstraints.allObjects as? [LayoutConstraint] {\n                \n                if installedLayoutConstraints.count > 0 {\n                    // remove the constraints from the UIView's storage\n                    #if SNAPKIT_DEPLOYMENT_LEGACY && !os(OSX)\n                    if #available(iOS 8.0, *) {\n                        NSLayoutConstraint.deactivateConstraints(installedLayoutConstraints)\n                    } else if let installedOnView = installInfo.view {\n                        installedOnView.removeConstraints(installedLayoutConstraints)\n                    }\n                    #else\n                        NSLayoutConstraint.deactivateConstraints(installedLayoutConstraints)\n                    #endif\n                    \n                    // remove the constraints from the from item view\n                    if let fromView = self.fromItem.view {\n                        fromView.snp_installedLayoutConstraints = fromView.snp_installedLayoutConstraints.filter {\n                            return !installedLayoutConstraints.contains($0)\n                        }\n                    }\n                }\n                \n        }\n        self.installInfo = nil\n    }\n    \n}\n\nprivate struct ConcreteConstraintInstallInfo {\n    \n    weak var view: View? = nil\n    let layoutConstraints: NSHashTable\n    \n}\n\nprivate extension NSLayoutAttribute {\n    \n    private func snp_constantForValue(value: Any?) -> CGFloat {\n        // Float\n        if let float = value as? Float {\n            return CGFloat(float)\n        }\n            // Double\n        else if let double = value as? Double {\n            return CGFloat(double)\n        }\n            // UInt\n        else if let int = value as? Int {\n            return CGFloat(int)\n        }\n            // Int\n        else if let uint = value as? UInt {\n            return CGFloat(uint)\n        }\n            // CGFloat\n        else if let float = value as? CGFloat {\n            return float\n        }\n            // CGSize\n        else if let size = value as? CGSize {\n            if self == .Width {\n                return size.width\n            } else if self == .Height {\n                return size.height\n            }\n        }\n            // CGPoint\n        else if let point = value as? CGPoint {\n            #if os(iOS) || os(tvOS)\n                switch self {\n                case .Left, .CenterX, .LeftMargin, .CenterXWithinMargins: return point.x\n                case .Top, .CenterY, .TopMargin, .CenterYWithinMargins, .Baseline, .FirstBaseline: return point.y\n                case .Right, .RightMargin: return point.x\n                case .Bottom, .BottomMargin: return point.y\n                case .Leading, .LeadingMargin: return point.x\n                case .Trailing, .TrailingMargin: return point.x\n                case .Width, .Height, .NotAnAttribute: return CGFloat(0)\n                }\n            #else\n                switch self {\n                case .Left, .CenterX: return point.x\n                case .Top, .CenterY, .Baseline: return point.y\n                case .Right: return point.x\n                case .Bottom: return point.y\n                case .Leading: return point.x\n                case .Trailing: return point.x\n                case .Width, .Height, .NotAnAttribute: return CGFloat(0)\n                case .FirstBaseline: return point.y\n                }\n            #endif\n        }\n            // EdgeInsets\n        else if let insets = value as? EdgeInsets {\n            #if os(iOS) || os(tvOS)\n                switch self {\n                case .Left, .CenterX, .LeftMargin, .CenterXWithinMargins: return insets.left\n                case .Top, .CenterY, .TopMargin, .CenterYWithinMargins, .Baseline, .FirstBaseline: return insets.top\n                case .Right, .RightMargin: return insets.right\n                case .Bottom, .BottomMargin: return insets.bottom\n                case .Leading, .LeadingMargin: return  (Config.interfaceLayoutDirection == .LeftToRight) ? insets.left : -insets.right\n                case .Trailing, .TrailingMargin: return  (Config.interfaceLayoutDirection == .LeftToRight) ? insets.right : -insets.left\n                case .Width, .Height, .NotAnAttribute: return CGFloat(0)\n                }\n            #else\n                switch self {\n                case .Left, .CenterX: return insets.left\n                case .Top, .CenterY, .Baseline: return insets.top\n                case .Right: return insets.right\n                case .Bottom: return insets.bottom\n                case .Leading: return  (Config.interfaceLayoutDirection == .LeftToRight) ? insets.left : -insets.right\n                case .Trailing: return  (Config.interfaceLayoutDirection == .LeftToRight) ? insets.right : -insets.left\n                case .Width, .Height, .NotAnAttribute: return CGFloat(0)\n                case .FirstBaseline: return insets.bottom\n                }\n            #endif\n        }\n        \n        return CGFloat(0);\n    }\n}\n\nprivate func closestCommonSuperviewFromView(fromView: View?, toView: View?) -> View? {\n    var views = Set<View>()\n    var fromView = fromView\n    var toView = toView\n    repeat {\n        if let view = toView {\n            if views.contains(view) {\n                return view\n            }\n            views.insert(view)\n            toView = view.superview\n        }\n        if let view = fromView {\n            if views.contains(view) {\n                return view\n            }\n            views.insert(view)\n            fromView = view.superview\n        }\n    } while (fromView != nil || toView != nil)\n    \n    return nil\n}\n\nprivate func ==(left: ConcreteConstraint, right: ConcreteConstraint) -> Bool {\n    return (left.fromItem == right.fromItem &&\n            left.toItem == right.toItem &&\n            left.relation == right.relation &&\n            left.multiplier == right.multiplier &&\n            left.priority == right.priority)\n}\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/ConstraintAttributes.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\n/**\n    Used to define `NSLayoutAttributes` in a more concise and composite manner\n*/\ninternal struct ConstraintAttributes: OptionSetType, BooleanType {\n    \n    internal init(rawValue: UInt) {\n        self.rawValue = rawValue\n    }\n    internal init(_ rawValue: UInt) {\n        self.init(rawValue: rawValue)\n    }\n    internal init(nilLiteral: ()) {\n        self.rawValue = 0\n    }\n    \n    internal private(set) var rawValue: UInt\n    internal static var allZeros: ConstraintAttributes { return self.init(0) }\n    internal static func convertFromNilLiteral() -> ConstraintAttributes { return self.init(0) }\n    internal var boolValue: Bool { return self.rawValue != 0 }\n    \n    internal func toRaw() -> UInt { return self.rawValue }\n    internal static func fromRaw(raw: UInt) -> ConstraintAttributes? { return self.init(raw) }\n    internal static func fromMask(raw: UInt) -> ConstraintAttributes { return self.init(raw) }\n    \n    // normal\n    \n    internal static var None: ConstraintAttributes { return self.init(0) }\n    internal static var Left: ConstraintAttributes { return self.init(1) }\n    internal static var Top: ConstraintAttributes {  return self.init(2) }\n    internal static var Right: ConstraintAttributes { return self.init(4) }\n    internal static var Bottom: ConstraintAttributes { return self.init(8) }\n    internal static var Leading: ConstraintAttributes { return self.init(16) }\n    internal static var Trailing: ConstraintAttributes { return self.init(32) }\n    internal static var Width: ConstraintAttributes { return self.init(64) }\n    internal static var Height: ConstraintAttributes { return self.init(128) }\n    internal static var CenterX: ConstraintAttributes { return self.init(256) }\n    internal static var CenterY: ConstraintAttributes { return self.init(512) }\n    internal static var Baseline: ConstraintAttributes { return self.init(1024) }\n    \n    @available(iOS 8.0, *)\n    internal static var FirstBaseline: ConstraintAttributes { return self.init(2048) }\n    @available(iOS 8.0, *)\n    internal static var LeftMargin: ConstraintAttributes { return self.init(4096) }\n    @available(iOS 8.0, *)\n    internal static var RightMargin: ConstraintAttributes { return self.init(8192) }\n    @available(iOS 8.0, *)\n    internal static var TopMargin: ConstraintAttributes { return self.init(16384) }\n    @available(iOS 8.0, *)\n    internal static var BottomMargin: ConstraintAttributes { return self.init(32768) }\n    @available(iOS 8.0, *)\n    internal static var LeadingMargin: ConstraintAttributes { return self.init(65536) }\n    @available(iOS 8.0, *)\n    internal static var TrailingMargin: ConstraintAttributes { return self.init(131072) }\n    @available(iOS 8.0, *)\n    internal static var CenterXWithinMargins: ConstraintAttributes { return self.init(262144) }\n    @available(iOS 8.0, *)\n    internal static var CenterYWithinMargins: ConstraintAttributes { return self.init(524288) }\n    \n    // aggregates\n    \n    internal static var Edges: ConstraintAttributes { return self.init(15) }\n    internal static var Size: ConstraintAttributes { return self.init(192) }\n    internal static var Center: ConstraintAttributes { return self.init(768) }\n    \n    @available(iOS 8.0, *)\n    internal static var Margins: ConstraintAttributes { return self.init(61440) }\n    \n    @available(iOS 8.0, *)\n    internal static var CenterWithinMargins: ConstraintAttributes { return self.init(786432) }\n    \n    internal var layoutAttributes:[NSLayoutAttribute] {\n        var attrs = [NSLayoutAttribute]()\n        if (self.contains(ConstraintAttributes.Left)) {\n            attrs.append(.Left)\n        }\n        if (self.contains(ConstraintAttributes.Top)) {\n            attrs.append(.Top)\n        }\n        if (self.contains(ConstraintAttributes.Right)) {\n            attrs.append(.Right)\n        }\n        if (self.contains(ConstraintAttributes.Bottom)) {\n            attrs.append(.Bottom)\n        }\n        if (self.contains(ConstraintAttributes.Leading)) {\n            attrs.append(.Leading)\n        }\n        if (self.contains(ConstraintAttributes.Trailing)) {\n            attrs.append(.Trailing)\n        }\n        if (self.contains(ConstraintAttributes.Width)) {\n            attrs.append(.Width)\n        }\n        if (self.contains(ConstraintAttributes.Height)) {\n            attrs.append(.Height)\n        }\n        if (self.contains(ConstraintAttributes.CenterX)) {\n            attrs.append(.CenterX)\n        }\n        if (self.contains(ConstraintAttributes.CenterY)) {\n            attrs.append(.CenterY)\n        }\n        if (self.contains(ConstraintAttributes.Baseline)) {\n            attrs.append(.Baseline)\n        }\n        \n        #if os(iOS) || os(tvOS)\n        #if SNAPKIT_DEPLOYMENT_LEGACY\n        guard #available(iOS 8.0, *) else {\n            return attrs\n        }\n        #endif\n        if (self.contains(ConstraintAttributes.FirstBaseline)) {\n            attrs.append(.FirstBaseline)\n        }\n        if (self.contains(ConstraintAttributes.LeftMargin)) {\n            attrs.append(.LeftMargin)\n        }\n        if (self.contains(ConstraintAttributes.RightMargin)) {\n            attrs.append(.RightMargin)\n        }\n        if (self.contains(ConstraintAttributes.TopMargin)) {\n            attrs.append(.TopMargin)\n        }\n        if (self.contains(ConstraintAttributes.BottomMargin)) {\n            attrs.append(.BottomMargin)\n        }\n        if (self.contains(ConstraintAttributes.LeadingMargin)) {\n            attrs.append(.LeadingMargin)\n        }\n        if (self.contains(ConstraintAttributes.TrailingMargin)) {\n            attrs.append(.TrailingMargin)\n        }\n        if (self.contains(ConstraintAttributes.CenterXWithinMargins)) {\n            attrs.append(.CenterXWithinMargins)\n        }\n        if (self.contains(ConstraintAttributes.CenterYWithinMargins)) {\n            attrs.append(.CenterYWithinMargins)\n        }\n        #endif\n        \n        return attrs\n    }\n}\ninternal func +=(inout left: ConstraintAttributes, right: ConstraintAttributes) {\n    left.unionInPlace(right)\n}\ninternal func -=(inout left: ConstraintAttributes, right: ConstraintAttributes) {\n    left.subtractInPlace(right)\n}\ninternal func ==(left: ConstraintAttributes, right: ConstraintAttributes) -> Bool {\n    return left.rawValue == right.rawValue\n}\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/ConstraintDescription.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\npublic protocol RelationTarget {\n    var constraintItem: ConstraintItem { get }\n}\n\npublic protocol FloatConvertible: RelationTarget {\n    var floatValue: Float { get }\n}\n\nextension FloatConvertible {\n    public var constraintItem: ConstraintItem {\n        return ConstraintItem(object: nil, attributes: ConstraintAttributes.None)\n    }\n}\n\nextension Float: FloatConvertible, RelationTarget {\n    public var floatValue: Float {\n        return self\n    }\n}\n\nextension Int: FloatConvertible, RelationTarget {\n    public var floatValue: Float {\n        return Float(self)\n    }\n}\n\nextension UInt: FloatConvertible, RelationTarget {\n    public var floatValue: Float {\n        return Float(self)\n    }\n}\n\nextension Double: FloatConvertible, RelationTarget {\n    public var floatValue: Float {\n        return Float(self)\n    }\n}\n\nextension CGFloat: FloatConvertible, RelationTarget {\n    public var floatValue: Float {\n        return Float(self)\n    }\n}\n\n@available(iOS 9.0, OSX 10.11, *)\nextension NSLayoutAnchor: RelationTarget {\n    public var constraintItem: ConstraintItem {\n        return ConstraintItem(object: self, attributes: ConstraintAttributes.None)\n    }\n}\n\nextension CGPoint: RelationTarget {\n    public var constraintItem: ConstraintItem {\n        return ConstraintItem(object: nil, attributes: ConstraintAttributes.None)\n    }\n}\n\nextension CGSize: RelationTarget {\n    public var constraintItem: ConstraintItem {\n        return ConstraintItem(object: nil, attributes: ConstraintAttributes.None)\n    }\n}\n\nextension EdgeInsets: RelationTarget {\n    public var constraintItem: ConstraintItem {\n        return ConstraintItem(object: nil, attributes: ConstraintAttributes.None)\n    }\n}\n\nextension View: RelationTarget {\n    public var constraintItem: ConstraintItem {\n        return ConstraintItem(object: self, attributes: ConstraintAttributes.None)\n    }\n}\n\nextension ConstraintItem: RelationTarget {\n    public var constraintItem: ConstraintItem {\n        return self\n    }\n}\n\n/**\n    Used to expose the final API of a `ConstraintDescription` which allows getting a constraint from it\n */\npublic class ConstraintDescriptionFinalizable {\n    \n    private let backing: ConstraintDescription\n    \n    internal init(_ backing: ConstraintDescription) {\n        self.backing = backing\n    }\n    \n    public var constraint: Constraint {\n        return backing.constraint\n    }\n}\n\n/**\n    Used to expose priority APIs\n */\npublic class ConstraintDescriptionPriortizable: ConstraintDescriptionFinalizable {\n    \n    public func priority(priority: FloatConvertible) -> ConstraintDescriptionFinalizable {\n        return ConstraintDescriptionFinalizable(self.backing.priority(priority))\n    }\n    \n    public func priorityRequired() -> ConstraintDescriptionFinalizable {\n        return ConstraintDescriptionFinalizable(self.backing.priorityRequired())\n    }\n    public func priorityHigh() -> ConstraintDescriptionFinalizable {\n        return ConstraintDescriptionFinalizable(self.backing.priorityHigh())\n    }\n    public func priorityMedium() -> ConstraintDescriptionFinalizable {\n        return ConstraintDescriptionFinalizable(self.backing.priorityMedium())\n    }\n    public func priorityLow() -> ConstraintDescriptionFinalizable {\n        return ConstraintDescriptionFinalizable(self.backing.priorityLow())\n    }\n}\n\n/**\n    Used to expose multiplier & constant APIs\n*/\npublic class ConstraintDescriptionEditable: ConstraintDescriptionPriortizable {\n\n    public func multipliedBy(amount: FloatConvertible) -> ConstraintDescriptionEditable {\n        return ConstraintDescriptionEditable(self.backing.multipliedBy(amount))\n    }\n    \n    public func dividedBy(amount: FloatConvertible) -> ConstraintDescriptionEditable {\n        return self.multipliedBy(1 / amount.floatValue)\n    }\n    \n    public func offset(amount: FloatConvertible) -> ConstraintDescriptionEditable {\n        return ConstraintDescriptionEditable(self.backing.offset(amount))\n    }\n    public func offset(amount: CGPoint) -> ConstraintDescriptionEditable {\n        return ConstraintDescriptionEditable(self.backing.offset(amount))\n    }\n    public func offset(amount: CGSize) -> ConstraintDescriptionEditable {\n        return ConstraintDescriptionEditable(self.backing.offset(amount))\n    }\n    public func offset(amount: EdgeInsets) -> ConstraintDescriptionEditable {\n        return ConstraintDescriptionEditable(self.backing.offset(amount))\n    }\n    \n    public func inset(amount: FloatConvertible) -> ConstraintDescriptionEditable {\n        return ConstraintDescriptionEditable(self.backing.inset(amount))\n    }\n    public func inset(amount: EdgeInsets) -> ConstraintDescriptionEditable {\n        return ConstraintDescriptionEditable(self.backing.inset(amount))\n    }\n}\n\n/**\n    Used to expose relation APIs\n*/\npublic class ConstraintDescriptionRelatable {\n\n    private let backing: ConstraintDescription\n    \n    init(_ backing: ConstraintDescription) {\n        self.backing = backing\n    }\n    \n    public func equalTo(other: RelationTarget, file: String = __FILE__, line: UInt = __LINE__) -> ConstraintDescriptionEditable {\n        let location = SourceLocation(file: file, line: line)\n        return ConstraintDescriptionEditable(self.backing.constrainTo(other, relation: .Equal, location: location))\n    }\n    public func equalTo(other: LayoutSupport, file: String = __FILE__, line: UInt = __LINE__) -> ConstraintDescriptionEditable {\n        let location = SourceLocation(file: file, line: line)\n        return ConstraintDescriptionEditable(self.backing.constrainTo(other, relation: .Equal, location: location))\n    }\n    \n    public func lessThanOrEqualTo(other: RelationTarget, file: String = __FILE__, line: UInt = __LINE__) -> ConstraintDescriptionEditable {\n        let location = SourceLocation(file: file, line: line)\n        return ConstraintDescriptionEditable(self.backing.constrainTo(other, relation: .LessThanOrEqualTo, location: location))\n    }\n    public func lessThanOrEqualTo(other: LayoutSupport, file: String = __FILE__, line: UInt = __LINE__) -> ConstraintDescriptionEditable {\n        let location = SourceLocation(file: file, line: line)\n        return ConstraintDescriptionEditable(self.backing.constrainTo(other, relation: .LessThanOrEqualTo, location: location))\n    }\n    \n    public func greaterThanOrEqualTo(other: RelationTarget, file: String = __FILE__, line: UInt = __LINE__) -> ConstraintDescriptionEditable {\n        let location = SourceLocation(file: file, line: line)\n        return ConstraintDescriptionEditable(self.backing.constrainTo(other, relation: .GreaterThanOrEqualTo, location: location))\n    }\n    public func greaterThanOrEqualTo(other: LayoutSupport, file: String = __FILE__, line: UInt = __LINE__) -> ConstraintDescriptionEditable {\n        let location = SourceLocation(file: file, line: line)\n        return ConstraintDescriptionEditable(self.backing.constrainTo(other, relation: .GreaterThanOrEqualTo, location: location))\n    }\n}\n\n/**\n    Used to expose chaining APIs\n*/\npublic class ConstraintDescriptionExtendable: ConstraintDescriptionRelatable {\n    \n    public var left: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.left)\n    }\n    public var top: ConstraintDescriptionExtendable  {\n        return ConstraintDescriptionExtendable(self.backing.top)\n    }\n    public var bottom: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.bottom)\n    }\n    public var right: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.right)\n    }\n    public var leading: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.leading)\n    }\n    public var trailing: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.trailing)\n    }\n    public var width: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.width)\n    }\n    public var height: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.height)\n    }\n    public var centerX: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.centerX)\n    }\n    public var centerY: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.centerY)\n    }\n    public var baseline: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.baseline)\n    }\n    \n    @available(iOS 8.0, *)\n    public var firstBaseline: ConstraintDescriptionExtendable  {\n        return ConstraintDescriptionExtendable(self.backing.firstBaseline)\n    }\n    @available(iOS 8.0, *)\n    public var leftMargin: ConstraintDescriptionExtendable  {\n        return ConstraintDescriptionExtendable(self.backing.leftMargin)\n    }\n    @available(iOS 8.0, *)\n    public var rightMargin: ConstraintDescriptionExtendable  {\n        return ConstraintDescriptionExtendable(self.backing.rightMargin)\n    }\n    @available(iOS 8.0, *)\n    public var topMargin: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.topMargin)\n    }\n    @available(iOS 8.0, *)\n    public var bottomMargin: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.bottomMargin)\n    }\n    @available(iOS 8.0, *)\n    public var leadingMargin: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.leadingMargin)\n    }\n    @available(iOS 8.0, *)\n    public var trailingMargin: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.trailingMargin)\n    }\n    @available(iOS 8.0, *)\n    public var centerXWithinMargins: ConstraintDescriptionExtendable  {\n        return ConstraintDescriptionExtendable(self.backing.centerXWithinMargins)\n    }\n    @available(iOS 8.0, *)\n    public var centerYWithinMargins: ConstraintDescriptionExtendable {\n        return ConstraintDescriptionExtendable(self.backing.centerYWithinMargins)\n    }\n}\n\n/**\n    Used to internally manage building constraint\n */\ninternal class ConstraintDescription {\n    \n    private var location: SourceLocation? = nil\n    \n    private var left: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Left) }\n    private var top: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Top) }\n    private var right: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Right) }\n    private var bottom: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Bottom) }\n    private var leading: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Leading) }\n    private var trailing: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Trailing) }\n    private var width: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Width) }\n    private var height: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Height) }\n    private var centerX: ConstraintDescription { return self.addConstraint(ConstraintAttributes.CenterX) }\n    private var centerY: ConstraintDescription { return self.addConstraint(ConstraintAttributes.CenterY) }\n    private var baseline: ConstraintDescription { return self.addConstraint(ConstraintAttributes.Baseline) }\n    \n    @available(iOS 8.0, *)\n    private var firstBaseline: ConstraintDescription { return self.addConstraint(ConstraintAttributes.FirstBaseline) }\n    @available(iOS 8.0, *)\n    private var leftMargin: ConstraintDescription { return self.addConstraint(ConstraintAttributes.LeftMargin) }\n    @available(iOS 8.0, *)\n    private var rightMargin: ConstraintDescription { return self.addConstraint(ConstraintAttributes.RightMargin) }\n    @available(iOS 8.0, *)\n    private var topMargin: ConstraintDescription { return self.addConstraint(ConstraintAttributes.TopMargin) }\n    @available(iOS 8.0, *)\n    private var bottomMargin: ConstraintDescription { return self.addConstraint(ConstraintAttributes.BottomMargin) }\n    @available(iOS 8.0, *)\n    private var leadingMargin: ConstraintDescription { return self.addConstraint(ConstraintAttributes.LeadingMargin) }\n    @available(iOS 8.0, *)\n    private var trailingMargin: ConstraintDescription { return self.addConstraint(ConstraintAttributes.TrailingMargin) }\n    @available(iOS 8.0, *)\n    private var centerXWithinMargins: ConstraintDescription { return self.addConstraint(ConstraintAttributes.CenterXWithinMargins) }\n    @available(iOS 8.0, *)\n    private var centerYWithinMargins: ConstraintDescription { return self.addConstraint(ConstraintAttributes.CenterYWithinMargins) }\n    \n    // MARK: initializer\n    \n    init(fromItem: ConstraintItem) {\n        self.fromItem = fromItem\n        self.toItem = ConstraintItem(object: nil, attributes: ConstraintAttributes.None)\n    }\n    \n    // MARK: multiplier\n    \n    private func multipliedBy(amount: FloatConvertible) -> ConstraintDescription {\n        self.multiplier = amount.floatValue\n        return self\n    }\n    \n    private func dividedBy(amount: FloatConvertible) -> ConstraintDescription {\n        self.multiplier = 1.0 / amount.floatValue;\n        return self\n    }\n    \n    // MARK: offset\n    \n    private func offset(amount: FloatConvertible) -> ConstraintDescription {\n        self.constant = amount.floatValue\n        return self\n    }\n    private func offset(amount: CGPoint) -> ConstraintDescription {\n        self.constant = amount\n        return self\n    }\n    private func offset(amount: CGSize) -> ConstraintDescription {\n        self.constant = amount\n        return self\n    }\n    private func offset(amount: EdgeInsets) -> ConstraintDescription {\n        self.constant = amount\n        return self\n    }\n    \n    // MARK: inset\n    \n    private func inset(amount: FloatConvertible) -> ConstraintDescription {\n        let value = CGFloat(amount.floatValue)\n        self.constant = EdgeInsets(top: value, left: value, bottom: -value, right: -value)\n        return self\n    }\n    private func inset(amount: EdgeInsets) -> ConstraintDescription {\n        self.constant = EdgeInsets(top: amount.top, left: amount.left, bottom: -amount.bottom, right: -amount.right)\n        return self\n    }\n    \n    // MARK: priority\n    \n    private func priority(priority: FloatConvertible) -> ConstraintDescription {\n        self.priority = priority.floatValue\n        return self\n    }\n    private func priorityRequired() -> ConstraintDescription {\n        return self.priority(1000.0)\n    }\n    private func priorityHigh() -> ConstraintDescription {\n        return self.priority(750.0)\n    }\n    private func priorityMedium() -> ConstraintDescription {\n        #if os(iOS) || os(tvOS)\n        return self.priority(500.0)\n        #else\n        return self.priority(501.0)\n        #endif\n    }\n    private func priorityLow() -> ConstraintDescription {\n        return self.priority(250.0)\n    }\n    \n    // MARK: Constraint\n    \n    internal var constraint: Constraint {\n        if self.concreteConstraint == nil {\n            if self.relation == nil {\n                fatalError(\"Attempting to create a constraint from a ConstraintDescription before it has been fully chained.\")\n            }\n            self.concreteConstraint = ConcreteConstraint(\n                fromItem: self.fromItem,\n                toItem: self.toItem,\n                relation: self.relation!,\n                constant: self.constant,\n                multiplier: self.multiplier,\n                priority: self.priority,\n                location: self.location\n            )\n        }\n        return self.concreteConstraint!\n    }\n    \n    // MARK: Private\n    \n    private let fromItem: ConstraintItem\n    private var toItem: ConstraintItem {\n        willSet {\n            if self.concreteConstraint != nil {\n                fatalError(\"Attempting to modify a ConstraintDescription after its constraint has been created.\")\n            }\n        }\n    }\n    private var relation: ConstraintRelation? {\n        willSet {\n            if self.concreteConstraint != nil {\n                fatalError(\"Attempting to modify a ConstraintDescription after its constraint has been created.\")\n            }\n        }\n    }\n    private var constant: Any = Float(0.0) {\n        willSet {\n            if self.concreteConstraint != nil {\n                fatalError(\"Attempting to modify a ConstraintDescription after its constraint has been created.\")\n            }\n        }\n    }\n    private var multiplier: Float = 1.0 {\n        willSet {\n            if self.concreteConstraint != nil {\n                fatalError(\"Attempting to modify a ConstraintDescription after its constraint has been created.\")\n            }\n        }\n    }\n    private var priority: Float = 1000.0 {\n        willSet {\n            if self.concreteConstraint != nil {\n                fatalError(\"Attempting to modify a ConstraintDescription after its constraint has been created.\")\n            }\n        }\n    }\n    private var concreteConstraint: ConcreteConstraint? = nil\n    \n    private func addConstraint(attributes: ConstraintAttributes) -> ConstraintDescription {\n        if self.relation == nil {\n            self.fromItem.attributes += attributes\n        }\n        return self\n    }\n    \n    private func constrainTo(other: RelationTarget, relation: ConstraintRelation, location: SourceLocation) -> ConstraintDescription {\n        \n        self.location = location\n        \n        if let constant = other as? FloatConvertible {\n            self.constant = constant.floatValue\n        }\n        \n        let item = other.constraintItem\n        \n        if item.attributes != ConstraintAttributes.None {\n            let toLayoutAttributes = item.attributes.layoutAttributes\n            if toLayoutAttributes.count > 1 {\n                let fromLayoutAttributes = self.fromItem.attributes.layoutAttributes\n                if toLayoutAttributes != fromLayoutAttributes {\n                    NSException(name: \"Invalid Constraint\", reason: \"Cannot constrain to multiple non identical attributes\", userInfo: nil).raise()\n                    return self\n                }\n                item.attributes = ConstraintAttributes.None\n            }\n        }\n        self.toItem = item\n        self.relation = relation\n        return self\n    }\n    \n    @available(iOS 7.0, *)\n    private func constrainTo(other: LayoutSupport, relation: ConstraintRelation, location: SourceLocation) -> ConstraintDescription {\n        return constrainTo(ConstraintItem(object: other, attributes: ConstraintAttributes.None), relation: relation, location: location)\n    }\n    \n}\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/ConstraintItem.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\n/**\n    Used to assist in building a constraint\n*/\npublic class ConstraintItem {\n    \n    internal init(object: AnyObject?, attributes: ConstraintAttributes) {\n        self.object = object\n        self.attributes = attributes\n    }\n    \n    internal weak var object: AnyObject?\n    internal var attributes: ConstraintAttributes\n    \n    internal var view: View? {\n        return self.object as? View\n    }\n    \n    @available(iOS 7.0, *)\n    internal var layoutSupport: LayoutSupport? {\n        return self.object as? LayoutSupport\n    }\n}\n\n\ninternal func ==(left: ConstraintItem, right: ConstraintItem) -> Bool {\n    if left.object == nil {\n        return false\n    }\n    if right.object == nil {\n        return false\n    }\n    if left.object !== right.object {\n        return false\n    }\n    if left.attributes != right.attributes {\n        return false\n    }\n    return true\n}"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/ConstraintMaker.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\n/**\n    Used to make constraints\n*/\npublic class ConstraintMaker {\n    \n    /// left edge\n    public var left: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Left) }\n    \n    /// top edge\n    public var top: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Top) }\n    \n    /// right edge\n    public var right: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Right) }\n    \n    /// bottom edge\n    public var bottom: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Bottom) }\n    \n    /// leading edge\n    public var leading: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Leading) }\n    \n    /// trailing edge\n    public var trailing: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Trailing) }\n    \n    /// width dimension\n    public var width: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Width) }\n    \n    /// height dimension\n    public var height: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Height) }\n    \n    /// centerX dimension\n    public var centerX: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterX) }\n    \n    /// centerY dimension\n    public var centerY: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterY) }\n    \n    /// baseline position\n    public var baseline: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Baseline) }\n    \n    /// firse baseline position\n    @available(iOS 8.0, *)\n    public var firstBaseline: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.FirstBaseline) }\n    \n    /// left margin\n    @available(iOS 8.0, *)\n    public var leftMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.LeftMargin) }\n    \n    /// right margin\n    @available(iOS 8.0, *)\n    public var rightMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.RightMargin) }\n    \n    /// top margin\n    @available(iOS 8.0, *)\n    public var topMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.TopMargin) }\n    \n    /// bottom margin\n    @available(iOS 8.0, *)\n    public var bottomMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.BottomMargin) }\n    \n    /// leading margin\n    @available(iOS 8.0, *)\n    public var leadingMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.LeadingMargin) }\n    \n    /// trailing margin\n    @available(iOS 8.0, *)\n    public var trailingMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.TrailingMargin) }\n    \n    /// centerX within margins\n    @available(iOS 8.0, *)\n    public var centerXWithinMargins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterXWithinMargins) }\n    \n    /// centerY within margins\n    @available(iOS 8.0, *)\n    public var centerYWithinMargins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterYWithinMargins) }\n    \n    /// top + left + bottom + right edges\n    public var edges: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Edges) }\n    \n    /// width + height dimensions\n    public var size: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Size) }\n    \n    // centerX + centerY positions\n    public var center: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Center) }\n    \n    // top + left + bottom + right margins\n    @available(iOS 8.0, *)\n    public var margins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Margins) }\n    \n    // centerX + centerY within margins\n    @available(iOS 8.0, *)\n    public var centerWithinMargins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterWithinMargins) }\n    \n    internal init(view: View, location: SourceLocation) {\n        self.view = view\n        self.location = location\n    }\n    \n    internal let location: SourceLocation\n    internal let view: View\n    internal var constraintDescriptions = [ConstraintDescription]()\n    \n    internal func makeConstraintDescription(attributes: ConstraintAttributes) -> ConstraintDescriptionExtendable {\n        let item = ConstraintItem(object: self.view, attributes: attributes)\n        let constraintDescription = ConstraintDescription(fromItem: item)\n        self.constraintDescriptions.append(constraintDescription)\n        return ConstraintDescriptionExtendable(constraintDescription)\n    }\n    \n    internal class func prepareConstraints(view view: View, location: SourceLocation, @noescape closure: (make: ConstraintMaker) -> Void) -> [Constraint] {\n        let maker = ConstraintMaker(view: view, location: location)\n        closure(make: maker)\n        \n        let constraints = maker.constraintDescriptions.map { $0.constraint }\n        for constraint in constraints {\n            constraint.makerLocation = maker.location\n        }\n        return constraints\n    }\n    \n    internal class func makeConstraints(view view: View, location: SourceLocation, @noescape closure: (make: ConstraintMaker) -> Void) {\n        view.translatesAutoresizingMaskIntoConstraints = false\n        let maker = ConstraintMaker(view: view, location: location)\n        closure(make: maker)\n        \n        let constraints = maker.constraintDescriptions.map { $0.constraint as! ConcreteConstraint }\n        for constraint in constraints {\n            constraint.makerLocation = maker.location\n            constraint.installOnView(updateExisting: false)\n        }\n    }\n    \n    internal class func remakeConstraints(view view: View, location: SourceLocation, @noescape closure: (make: ConstraintMaker) -> Void) {\n        view.translatesAutoresizingMaskIntoConstraints = false\n        let maker = ConstraintMaker(view: view, location: location)\n        closure(make: maker)\n        \n        self.removeConstraints(view: view)\n        let constraints = maker.constraintDescriptions.map { $0.constraint as! ConcreteConstraint }\n        for constraint in constraints {\n            constraint.makerLocation = maker.location\n            constraint.installOnView(updateExisting: false)\n        }\n    }\n    \n    internal class func updateConstraints(view view: View, location: SourceLocation, @noescape closure: (make: ConstraintMaker) -> Void) {\n        view.translatesAutoresizingMaskIntoConstraints = false\n        let maker = ConstraintMaker(view: view, location: location)\n        closure(make: maker)\n        \n        let constraints = maker.constraintDescriptions.map { $0.constraint as! ConcreteConstraint}\n        for constraint in constraints {\n            constraint.makerLocation = maker.location\n            constraint.installOnView(updateExisting: true)\n        }\n    }\n    \n    internal class func removeConstraints(view view: View) {\n        for existingLayoutConstraint in view.snp_installedLayoutConstraints {\n            existingLayoutConstraint.snp_constraint?.uninstall()\n        }\n    }\n}\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/ConstraintRelation.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\n/**\n    Used to define `NSLayoutRelation`\n*/\ninternal enum ConstraintRelation: Int {\n    case Equal = 1, LessThanOrEqualTo, GreaterThanOrEqualTo\n    \n    internal var layoutRelation: NSLayoutRelation {\n        get {\n            switch(self) {\n            case .LessThanOrEqualTo:\n                return .LessThanOrEqual\n            case .GreaterThanOrEqualTo:\n                return .GreaterThanOrEqual\n            default:\n                return .Equal\n            }\n        }\n    }\n}"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/Debugging.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\n/**\n    Used to allow adding a snp_label to a View for debugging purposes\n*/\npublic extension View {\n    \n    public var snp_label: String? {\n        get {\n            return objc_getAssociatedObject(self, &labelKey) as? String\n        }\n        set {\n            objc_setAssociatedObject(self, &labelKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)\n        }\n    }\n    \n}\n\n/**\n    Used to allow adding a snp_label to a LayoutConstraint for debugging purposes\n*/\npublic extension LayoutConstraint {\n    \n    public var snp_label: String? {\n        get {\n            return objc_getAssociatedObject(self, &labelKey) as? String\n        }\n        set {\n            objc_setAssociatedObject(self, &labelKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)\n        }\n    }\n\n    override public var description: String {\n        var description = \"<\"\n        \n        description += descriptionForObject(self)\n        \n        description += \" \\(descriptionForObject(self.firstItem))\"\n        if self.firstAttribute != .NotAnAttribute {\n            description += \".\\(self.firstAttribute.snp_description)\"\n        }\n        \n        description += \" \\(self.relation.snp_description)\"\n        \n        if let secondItem: AnyObject = self.secondItem {\n            description += \" \\(descriptionForObject(secondItem))\"\n        }\n        \n        if self.secondAttribute != .NotAnAttribute {\n            description += \".\\(self.secondAttribute.snp_description)\"\n        }\n        \n        if self.multiplier != 1.0 {\n            description += \" * \\(self.multiplier)\"\n        }\n        \n        if self.secondAttribute == .NotAnAttribute {\n            description += \" \\(self.constant)\"\n        } else {\n            if self.constant > 0.0 {\n                description += \" + \\(self.constant)\"\n            } else if self.constant < 0.0 {\n                description += \" - \\(CGFloat.abs(self.constant))\"\n            }\n        }\n        \n        if self.priority != 1000.0 {\n            description += \" ^\\(self.priority)\"\n        }\n        \n        description += \">\"\n        \n        return description\n    }\n    \n    internal var snp_makerFile: String? {\n        return self.snp_constraint?.makerLocation.file\n    }\n    \n    internal var snp_makerLine: UInt? {\n        return self.snp_constraint?.makerLocation.line\n    }\n    \n}\n\nprivate var labelKey = \"\"\n\nprivate func descriptionForObject(object: AnyObject) -> String {\n    let pointerDescription = NSString(format: \"%p\", ObjectIdentifier(object).uintValue)\n    var desc = \"\"\n    \n    desc += object.dynamicType.description()\n    \n    if let object = object as? View {\n        desc += \":\\(object.snp_label ?? pointerDescription)\"\n    } else if let object = object as? LayoutConstraint {\n        desc += \":\\(object.snp_label ?? pointerDescription)\"\n    } else {\n        desc += \":\\(pointerDescription)\"\n    }\n    \n    if let object = object as? LayoutConstraint, let file = object.snp_makerFile, let line = object.snp_makerLine {\n        desc += \"@\\(file)#\\(line)\"\n    }\n    \n    desc += \"\"\n    return desc\n}\n\nprivate extension NSLayoutRelation {\n    \n    private var snp_description: String {\n        switch self {\n        case .Equal:                return \"==\"\n        case .GreaterThanOrEqual:   return \">=\"\n        case .LessThanOrEqual:      return \"<=\"\n        }\n    }\n    \n}\n\nprivate extension NSLayoutAttribute {\n    \n    private var snp_description: String {\n        #if os(iOS) || os(tvOS)\n        switch self {\n        case .NotAnAttribute:       return \"notAnAttribute\"\n        case .Top:                  return \"top\"\n        case .Left:                 return \"left\"\n        case .Bottom:               return \"bottom\"\n        case .Right:                return \"right\"\n        case .Leading:              return \"leading\"\n        case .Trailing:             return \"trailing\"\n        case .Width:                return \"width\"\n        case .Height:               return \"height\"\n        case .CenterX:              return \"centerX\"\n        case .CenterY:              return \"centerY\"\n        case .Baseline:             return \"baseline\"\n        case .FirstBaseline:        return \"firstBaseline\"\n        case .TopMargin:            return \"topMargin\"\n        case .LeftMargin:           return \"leftMargin\"\n        case .BottomMargin:         return \"bottomMargin\"\n        case .RightMargin:          return \"rightMargin\"\n        case .LeadingMargin:        return \"leadingMargin\"\n        case .TrailingMargin:       return \"trailingMargin\"\n        case .CenterXWithinMargins: return \"centerXWithinMargins\"\n        case .CenterYWithinMargins: return \"centerYWithinMargins\"\n        }\n        #else\n        switch self {\n        case .NotAnAttribute:       return \"notAnAttribute\"\n        case .Top:                  return \"top\"\n        case .Left:                 return \"left\"\n        case .Bottom:               return \"bottom\"\n        case .Right:                return \"right\"\n        case .Leading:              return \"leading\"\n        case .Trailing:             return \"trailing\"\n        case .Width:                return \"width\"\n        case .Height:               return \"height\"\n        case .CenterX:              return \"centerX\"\n        case .CenterY:              return \"centerY\"\n        case .Baseline:             return \"baseline\"\n        default:                    return \"default\"\n        }\n        #endif\n        \n    }\n    \n}\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/EdgeInsets.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\npublic typealias EdgeInsets = UIEdgeInsets\npublic func EdgeInsetsMake(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> EdgeInsets {\n    return EdgeInsets(top: top, left: left, bottom: bottom, right: right)\n}\npublic let EdgeInsetsZero = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0)\n#else\nimport AppKit\npublic typealias EdgeInsets = NSEdgeInsets\npublic func EdgeInsetsMake(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> EdgeInsets {\n    return EdgeInsets(top: top, left: left, bottom: bottom, right: right)\n}\npublic let EdgeInsetsZero = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0)\n#endif\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/LayoutConstraint.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n#else\nimport AppKit\n#endif\n\n/**\n    Used to add extra information to the actual `NSLayoutConstraint`'s that will UIKit/AppKit will utilize\n*/\npublic class LayoutConstraint: NSLayoutConstraint {\n    \n    internal var snp_constraint: Constraint? = nil\n    \n    public var snp_location: SourceLocation? {\n        return snp_constraint?.location\n    }\n}\n\ninternal func ==(left: LayoutConstraint, right: LayoutConstraint) -> Bool {\n    if left.firstItem !== right.firstItem {\n        return false\n    }\n    if left.secondItem !== right.secondItem {\n        return false\n    }\n    if left.firstAttribute != right.firstAttribute {\n        return false\n    }\n    if left.secondAttribute != right.secondAttribute {\n        return false\n    }\n    if left.relation != right.relation {\n        return false\n    }\n    if left.priority != right.priority {\n        return false\n    }\n    if left.multiplier != right.multiplier {\n        return false\n    }\n    return true\n}\n\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/SnapKit.h",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#import <Foundation/Foundation.h>\n\nFOUNDATION_EXPORT double SnapKitVersionNumber;\nFOUNDATION_EXPORT const unsigned char SnapKitVersionString[];"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/SnapKit.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\npublic typealias InterfaceLayoutDirection = UIUserInterfaceLayoutDirection\npublic typealias LayoutSupport = UILayoutSupport\n#else\nimport AppKit\npublic typealias InterfaceLayoutDirection = NSUserInterfaceLayoutDirection\npublic class LayoutSupport {}\n#endif\n\n/**\n    Used to configure different parts of SnapKit\n*/\npublic struct Config {\n    \n    /// The interface layout direction\n    public static var interfaceLayoutDirection = InterfaceLayoutDirection.LeftToRight\n    \n}"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/SourceLocation.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\npublic struct SourceLocation {\n    \n    public let file: String\n    public let line: UInt\n    \n    init(file: String, line: UInt) {\n        self.file = file\n        self.line = line\n    }\n    \n}\n\n\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/View+SnapKit.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\npublic typealias View = UIView\n#else\nimport AppKit\npublic typealias View = NSView\n#endif\n\n/**\n    Used to expose public API on views\n*/\npublic extension View {\n    \n    /// left edge\n    public var snp_left: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Left) }\n    \n    /// top edge\n    public var snp_top: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Top) }\n    \n    /// right edge\n    public var snp_right: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Right) }\n    \n    /// bottom edge\n    public var snp_bottom: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Bottom) }\n    \n    /// leading edge\n    public var snp_leading: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Leading) }\n    \n    /// trailing edge\n    public var snp_trailing: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Trailing) }\n    \n    /// width dimension\n    public var snp_width: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Width) }\n    \n    /// height dimension\n    public var snp_height: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Height) }\n    \n    /// centerX position\n    public var snp_centerX: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterX) }\n    \n    /// centerY position\n    public var snp_centerY: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterY) }\n    \n    /// baseline position\n    public var snp_baseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Baseline) }\n    \n    /// first baseline position\n    @available(iOS 8.0, *)\n    public var snp_firstBaseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.FirstBaseline) }\n    \n    /// left margin\n    @available(iOS 8.0, *)\n    public var snp_leftMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeftMargin) }\n    \n    /// right margin\n    @available(iOS 8.0, *)\n    public var snp_rightMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.RightMargin) }\n    \n    /// top margin\n    @available(iOS 8.0, *)\n    public var snp_topMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TopMargin) }\n    \n    /// bottom margin\n    @available(iOS 8.0, *)\n    public var snp_bottomMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.BottomMargin) }\n    \n    /// leading margin\n    @available(iOS 8.0, *)\n    public var snp_leadingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeadingMargin) }\n    \n    /// trailing margin\n    @available(iOS 8.0, *)\n    public var snp_trailingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TrailingMargin) }\n    \n    /// centerX within margins\n    @available(iOS 8.0, *)\n    public var snp_centerXWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterXWithinMargins) }\n    \n    /// centerY within margins\n    @available(iOS 8.0, *)\n    public var snp_centerYWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterYWithinMargins) }\n    \n    // top + left + bottom + right edges\n    public var snp_edges: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Edges) }\n    \n    // width + height dimensions\n    public var snp_size: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Size) }\n    \n    // centerX + centerY positions\n    public var snp_center: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Center) }\n    \n    // top + left + bottom + right margins\n    @available(iOS 8.0, *)\n    public var snp_margins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Margins) }\n    \n    // centerX + centerY within margins\n    @available(iOS 8.0, *)\n    public var snp_centerWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterWithinMargins) }\n    \n    /**\n        Prepares constraints with a `ConstraintMaker` and returns the made constraints but does not install them.\n\n        :param: closure that will be passed the `ConstraintMaker` to make the constraints with\n        \n        :returns: the constraints made\n    */\n    public func snp_prepareConstraints(file: String = __FILE__, line: UInt = __LINE__, @noescape closure: (make: ConstraintMaker) -> Void) -> [Constraint] {\n        return ConstraintMaker.prepareConstraints(view: self, location: SourceLocation(file: file, line: line), closure: closure)\n    }\n    \n    /**\n        Makes constraints with a `ConstraintMaker` and installs them along side any previous made constraints.\n        \n        :param: closure that will be passed the `ConstraintMaker` to make the constraints with\n    */\n    public func snp_makeConstraints(file: String = __FILE__, line: UInt = __LINE__, @noescape closure: (make: ConstraintMaker) -> Void) -> Void {\n        ConstraintMaker.makeConstraints(view: self, location: SourceLocation(file: file, line: line), closure: closure)\n    }\n    \n    /**\n        Updates constraints with a `ConstraintMaker` that will replace existing constraints that match and install new ones.\n    \n        For constraints to match only the constant can be updated.\n    \n        :param: closure that will be passed the `ConstraintMaker` to update the constraints with\n    */\n    public func snp_updateConstraints(file: String = __FILE__, line: UInt = __LINE__, @noescape closure: (make: ConstraintMaker) -> Void) -> Void {\n        ConstraintMaker.updateConstraints(view: self, location: SourceLocation(file: file, line: line), closure: closure)\n    }\n    \n    /**\n        Remakes constraints with a `ConstraintMaker` that will first remove all previously made constraints and make and install new ones.\n    \n        :param: closure that will be passed the `ConstraintMaker` to remake the constraints with\n    */\n    public func snp_remakeConstraints(file: String = __FILE__, line: UInt = __LINE__, @noescape closure: (make: ConstraintMaker) -> Void) -> Void {\n        ConstraintMaker.remakeConstraints(view: self, location: SourceLocation(file: file, line: line), closure: closure)\n    }\n    \n    /**\n        Removes all previously made constraints.\n    */\n    public func snp_removeConstraints() {\n        ConstraintMaker.removeConstraints(view: self)\n    }\n    \n    internal var snp_installedLayoutConstraints: [LayoutConstraint] {\n        get {\n            if let constraints = objc_getAssociatedObject(self, &installedLayoutConstraintsKey) as? [LayoutConstraint] {\n                return constraints\n            }\n            return []\n        }\n        set {\n            objc_setAssociatedObject(self, &installedLayoutConstraintsKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)\n        }\n    }\n}\n\nprivate var installedLayoutConstraintsKey = \"\"\n"
  },
  {
    "path": "shoppingCart/Classes/Library/SnapKit/ViewController+SnapKit.swift",
    "content": "//\n//  SnapKit\n//\n//  Copyright (c) 2011-2015 SnapKit Team - https://github.com/SnapKit\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a copy\n//  of this software and associated documentation files (the \"Software\"), to deal\n//  in the Software without restriction, including without limitation the rights\n//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n//  copies of the Software, and to permit persons to whom the Software is\n//  furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n//  THE SOFTWARE.\n\n#if os(iOS) || os(tvOS)\nimport UIKit\n\n/**\n    Used to expose public API on view controllers\n*/\npublic extension UIViewController {\n    \n    /// top layout guide top\n    public var snp_topLayoutGuideTop: ConstraintItem { return ConstraintItem(object: self.topLayoutGuide, attributes: ConstraintAttributes.Top) }\n    \n    /// top layout guide bottom\n    public var snp_topLayoutGuideBottom: ConstraintItem { return ConstraintItem(object: self.topLayoutGuide, attributes: ConstraintAttributes.Bottom) }\n    \n    /// bottom layout guide top\n    public var snp_bottomLayoutGuideTop: ConstraintItem { return ConstraintItem(object: self.bottomLayoutGuide, attributes: ConstraintAttributes.Top) }\n    \n    /// bottom layout guide bottom\n    public var snp_bottomLayoutGuideBottom: ConstraintItem { return ConstraintItem(object: self.bottomLayoutGuide, attributes: ConstraintAttributes.Bottom) }\n    \n}\n#endif\n"
  },
  {
    "path": "shoppingCart/Classes/Model/JFGoodModel.swift",
    "content": "//\n//  JFGoodModel.swift\n//  shoppingCart\n//\n//  Created by jianfeng on 15/11/17.\n//  Copyright © 2015年 六阿哥. All rights reserved.\n//\n\nimport UIKit\n\nclass JFGoodModel: NSObject {\n    \n    // 是否已经加入购物车\n    var alreadyAddShoppingCart: Bool = false\n    \n    // 商品图片名称\n    var iconName: String?\n    \n    // 商品标题\n    var title: String?\n    \n    // 商品描述\n    var desc: String?\n    \n    // 商品购买个数,默认0\n    var count: Int = 1\n    \n    // 新价格\n    var newPrice: String?\n    \n    // 老价格\n    var oldPrice: String?\n    \n    // 是否选中，默认没有选中\n    var selected: Bool = true\n    \n    // 字典转模型\n    init(dict: [String : AnyObject]) {\n        super.init()\n        \n        // 使用kvo为当前对象属性设置值\n        setValuesForKeysWithDictionary(dict)\n    }\n    \n    // 防止对象属性和kvc时的dict的key不匹配而崩溃\n    override func setValue(value: AnyObject?, forUndefinedKey key: String) {}\n    \n}\n"
  },
  {
    "path": "shoppingCart/Classes/ShopCart/Controller/JFShoppingCartViewController.swift",
    "content": "//\n//  JFShoppingCartViewController.swift\n//  shoppingCart\n//\n//  Created by jianfeng on 15/11/17.\n//  Copyright © 2015年 六阿哥. All rights reserved.\n//\n\nimport UIKit\n\nclass JFShoppingCartViewController: UIViewController {\n    \n    // MARK: - 属性\n    /// 已经添加进购物车的商品模型数组，初始化\n    var addGoodArray: [JFGoodModel]? {\n        didSet {\n            \n        }\n    }\n    \n    /// 总金额，默认0.00\n    var price: CFloat = 0.00\n    \n    /// 商品列表cell的重用标识符\n    private let shoppingCarCellIdentifier = \"shoppingCarCell\"\n\n    // MARK: - view生命周期\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        // 准备UI\n        prepareUI()\n    }\n    \n    override func viewWillAppear(animated: Bool) {\n        super.viewWillAppear(animated)\n        \n        // 布局UI\n        layoutUI()\n        \n        // 重新计算价格\n        reCalculateGoodCount()\n    }\n    \n    /**\n     准备UI\n     */\n    private func prepareUI() {\n        \n        // 标题\n        navigationItem.title = \"购物车列表\"\n        \n        // 导航栏左边返回\n        navigationItem.leftBarButtonItem = UIBarButtonItem(title: \"返回\", style: UIBarButtonItemStyle.Plain, target: self, action: \"didTappedBackButton\")\n        \n        // view背景颜色\n        view.backgroundColor = UIColor.whiteColor()\n        \n        // cell行高\n        tableView.rowHeight = 80\n        \n        // 注册cell\n        tableView.registerClass(JFShoppingCartCell.self, forCellReuseIdentifier: shoppingCarCellIdentifier)\n        \n        // 添加子控件\n        view.addSubview(tableView)\n        view.addSubview(bottomView)\n        bottomView.addSubview(selectButton)\n        bottomView.addSubview(totalPriceLabel)\n        bottomView.addSubview(buyButton)\n        \n        // 判断是否需要全选\n        \n        for model in addGoodArray! {\n            if model.selected != true {\n                // 只要有一个不等于就不全选\n                selectButton.selected = false\n                break\n            }\n        }\n    }\n    \n    /**\n     布局UI\n     */\n    private func layoutUI() {\n        \n        // 约束子控件\n        tableView.snp_makeConstraints { (make) -> Void in\n            make.left.top.right.equalTo(0)\n            make.bottom.equalTo(-49)\n        }\n        \n        bottomView.snp_makeConstraints { (make) -> Void in\n            make.left.bottom.right.equalTo(0)\n            make.height.equalTo(49)\n        }\n        \n        selectButton.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(12)\n            make.centerY.equalTo(bottomView.snp_centerY)\n        }\n        \n        totalPriceLabel.snp_makeConstraints { (make) -> Void in\n            make.center.equalTo(bottomView.snp_center)\n        }\n        \n        buyButton.snp_makeConstraints { (make) -> Void in\n            make.right.equalTo(-12)\n            make.top.equalTo(9)\n            make.width.equalTo(88)\n            make.height.equalTo(30)\n        }\n        \n    }\n    \n    // MARK: - 懒加载\n    /// tableView\n    lazy var tableView: UITableView = {\n        let tableView = UITableView()\n        \n        // 指定数据源和代理\n        tableView.dataSource = self\n        tableView.delegate = self\n        \n        return tableView\n    }()\n    \n    /// 底部视图\n    lazy var bottomView: UIView = {\n        let bottomView = UIView()\n        bottomView.backgroundColor = UIColor.whiteColor()\n        return bottomView\n    }()\n    \n    /// 底部多选、反选按钮\n    lazy var selectButton: UIButton = {\n        let selectButton = UIButton(type: UIButtonType.Custom)\n        selectButton.setImage(UIImage(named: \"check_n\"), forState: UIControlState.Normal)\n        selectButton.setImage(UIImage(named: \"check_y\"), forState: UIControlState.Selected)\n        selectButton.setTitle(\"多选\\\\反选\", forState: UIControlState.Normal)\n        selectButton.setTitleColor(UIColor.grayColor(), forState: UIControlState.Normal)\n        selectButton.titleLabel?.font = UIFont.systemFontOfSize(12)\n        selectButton.addTarget(self, action: \"didTappedSelectButton:\", forControlEvents: UIControlEvents.TouchUpInside)\n        selectButton.selected = true\n        selectButton.sizeToFit()\n        return selectButton\n    }()\n    \n    /// 底部总价Label\n    lazy var totalPriceLabel: UILabel = {\n        let totalPriceLabel = UILabel()\n        let attributeText = NSMutableAttributedString(string: \"总共价格：\\(self.price)0\")\n        attributeText.setAttributes([NSForegroundColorAttributeName : UIColor.redColor()], range: NSMakeRange(5, attributeText.length - 5))\n        \n        totalPriceLabel.attributedText = attributeText\n        totalPriceLabel.sizeToFit()\n        return totalPriceLabel\n    }()\n    \n    /// 底部付款按钮\n    lazy var buyButton: UIButton = {\n        let buyButton = UIButton(type: UIButtonType.Custom)\n        buyButton.setTitle(\"付款\", forState: UIControlState.Normal)\n        buyButton.setBackgroundImage(UIImage(named: \"button_cart_add\"), forState: UIControlState.Normal)\n        buyButton.layer.cornerRadius = 15\n        buyButton.layer.masksToBounds = true\n        return buyButton\n    }()\n\n}\n\n// MARK: - UITableViewDataSource, UITableViewDelegate数据、代理\nextension JFShoppingCartViewController: UITableViewDataSource, UITableViewDelegate {\n    \n    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return addGoodArray?.count ?? 0\n    }\n    \n    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {\n        \n        // 从缓存池创建cell,不成功就根据重用标识符和注册的cell新创建一个\n        let cell = tableView.dequeueReusableCellWithIdentifier(shoppingCarCellIdentifier, forIndexPath: indexPath) as! JFShoppingCartCell\n        \n        // cell取消选中效果\n        cell.selectionStyle = UITableViewCellSelectionStyle.None\n        \n        // 指定代理对象\n        cell.delegate = self\n        \n        // 传递模型\n        cell.goodModel = addGoodArray?[indexPath.row]\n        \n        return cell\n    }\n    \n    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {\n        reCalculateGoodCount()\n    }\n}\n\n// MARK: - view上的一些事件处理\nextension JFShoppingCartViewController {\n    \n    /**\n     返回按钮\n     */\n    @objc private func didTappedBackButton() {\n        dismissViewControllerAnimated(true, completion: nil)\n    }\n    \n    /**\n     重新计算商品数量\n     */\n    private func reCalculateGoodCount() {\n        \n        // 遍历模型\n        for model in addGoodArray! {\n            \n            // 只计算选中的商品\n            if model.selected == true {\n                price += Float(model.count) * (model.newPrice! as NSString).floatValue\n            }\n        }\n        \n        // 赋值价格\n        let attributeText = NSMutableAttributedString(string: \"总共价格：\\(self.price)0\")\n        attributeText.setAttributes([NSForegroundColorAttributeName : UIColor.redColor()], range: NSMakeRange(5, attributeText.length - 5))\n        totalPriceLabel.attributedText = attributeText\n        \n        // 清空price\n        price = 0\n        \n        // 刷新表格\n        tableView.reloadData()\n    }\n    \n    /**\n     点击了多选按钮后的事件处理\n     \n     - parameter button: 多选按钮\n     */\n    @objc private func didTappedSelectButton(button: UIButton) {\n        \n        selectButton.selected = !selectButton.selected\n        for model in addGoodArray! {\n            model.selected = selectButton.selected\n        }\n        \n        // 重新计算总价\n        reCalculateGoodCount()\n        \n        // 刷新表格\n        tableView.reloadData()\n    }\n}\n\n// MARK: - JFShoppingCartCellDelegate代理方法\nextension JFShoppingCartViewController: JFShoppingCartCellDelegate {\n    \n    /**\n     当点击了cell中加、减按钮\n     \n     - parameter cell:       被点击的cell\n     - parameter button:     被点击的按钮\n     - parameter countLabel: 显示数量的label\n     */\n    func shoppingCartCell(cell: JFShoppingCartCell, button: UIButton, countLabel: UILabel) {\n        \n        // 根据cell获取当前模型\n        guard let indexPath = tableView.indexPathForCell(cell) else {\n            return\n        }\n        \n        // 获取当前模型，添加到购物车模型数组\n        let model = addGoodArray![indexPath.row]\n        \n        if button.tag == 10 {\n            \n            if model.count < 1 {\n                print(\"数量不能低于0\")\n                return\n            }\n            \n            // 减\n            model.count--\n            countLabel.text = \"\\(model.count)\"\n        } else {\n            // 加\n            model.count++\n            countLabel.text = \"\\(model.count)\"\n        }\n        \n        // 重新计算商品数量\n        reCalculateGoodCount()\n    }\n    \n    /**\n     重新计算总价\n     */\n    func reCalculateTotalPrice() {\n        reCalculateGoodCount()\n    }\n}\n"
  },
  {
    "path": "shoppingCart/Classes/ShopCart/View/JFOldPriceLabel.swift",
    "content": "//\n//  JFOldPriceLabel.swift\n//  shoppingCart\n//\n//  Created by jianfeng on 15/11/18.\n//  Copyright © 2015年 六阿哥. All rights reserved.\n//\n\nimport UIKit\n\nclass JFOldPriceLabel: UILabel {\n\n    override func drawRect(rect: CGRect) {\n        // 调用父类是为了让Label原有数据正常显示\n        super.drawRect(rect)\n        \n        // 绘制中划线\n        let ctx = UIGraphicsGetCurrentContext()\n        CGContextMoveToPoint(ctx, 0, rect.size.height * 0.5)\n        CGContextAddLineToPoint(ctx, rect.size.width, rect.size.height * 0.5)\n        CGContextStrokePath(ctx)\n    }\n}\n"
  },
  {
    "path": "shoppingCart/Classes/ShopCart/View/JFShoppingCartCell.swift",
    "content": "//\n//  JFShoppingCartCell.swift\n//  shoppingCart\n//\n//  Created by jianfeng on 15/11/18.\n//  Copyright © 2015年 六阿哥. All rights reserved.\n//\n\nimport UIKit\n\nprotocol JFShoppingCartCellDelegate: NSObjectProtocol {\n    \n    func shoppingCartCell(cell: JFShoppingCartCell, button: UIButton, countLabel: UILabel)\n    \n    func reCalculateTotalPrice()\n}\n\nclass JFShoppingCartCell: UITableViewCell {\n    \n    // MARK: - 属性\n    /// 商品模型\n    var goodModel: JFGoodModel? {\n        didSet {\n            \n            // 选中状态\n            selectButton.selected = goodModel!.selected\n            \n            goodCountLabel.text = \"\\(goodModel!.count)\"\n            \n            if let iconName = goodModel?.iconName {\n                iconView.image = UIImage(named: iconName)\n            }\n            \n            if let title = goodModel?.title {\n                titleLabel.text = title\n            }\n            \n            if let newPrice = goodModel?.newPrice {\n                newPriceLabel.text = newPrice\n            }\n            \n            if let oldPrice = goodModel?.oldPrice {\n                oldPriceLabel.text = oldPrice\n            }\n            \n            // 重新布局，会更新frame\n            layoutIfNeeded()\n            \n        }\n    }\n    \n    /// 代理属性\n    weak var delegate: JFShoppingCartCellDelegate?\n    \n    // MARK: - 构造方法\n    required init?(coder aDecoder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }\n    \n    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {\n        super.init(style: style, reuseIdentifier: reuseIdentifier)\n        \n        // 准备UI\n        prepareUI()\n    }\n    \n    /**\n     准备UI\n     */\n    private func prepareUI() {\n        \n        // 添加子控件\n        contentView.addSubview(selectButton)\n        contentView.addSubview(iconView)\n        contentView.addSubview(titleLabel)\n        contentView.addSubview(newPriceLabel)\n        contentView.addSubview(oldPriceLabel)\n        contentView.addSubview(addAndsubtraction)\n        addAndsubtraction.addSubview(subtractionButton)\n        addAndsubtraction.addSubview(goodCountLabel)\n        addAndsubtraction.addSubview(addButton)\n        \n        // 约束子控件\n        selectButton.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(12)\n            make.centerY.equalTo(contentView.snp_centerY)\n        }\n        \n        iconView.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(42)\n            make.top.equalTo(10)\n            make.width.equalTo(60)\n            make.height.equalTo(60)\n        }\n        \n        titleLabel.snp_makeConstraints { (make) -> Void in\n            make.top.equalTo(contentView.snp_top).offset(10)\n            make.left.equalTo(iconView.snp_right).offset(12)\n        }\n\n        newPriceLabel.snp_makeConstraints { (make) -> Void in\n            make.top.equalTo(titleLabel.snp_top).offset(5)\n            make.right.equalTo(-12)\n        }\n        \n        oldPriceLabel.snp_makeConstraints { (make) -> Void in\n            make.top.equalTo(newPriceLabel.snp_bottom).offset(5)\n            make.right.equalTo(-12)\n        }\n        \n        addAndsubtraction.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(120)\n            make.top.equalTo(40)\n            make.width.equalTo(100)\n            make.height.equalTo(30)\n        }\n        \n        subtractionButton.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(0)\n            make.top.equalTo(0)\n            make.width.equalTo(30)\n            make.height.equalTo(30)\n        }\n        \n        goodCountLabel.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(30)\n            make.top.equalTo(0)\n            make.width.equalTo(40)\n            make.height.equalTo(30)\n        }\n        \n        addButton.snp_makeConstraints { (make) -> Void in\n            make.left.equalTo(70)\n            make.top.equalTo(0)\n            make.width.equalTo(30)\n            make.height.equalTo(30)\n        }\n        \n    }\n    \n    // MARK: - 响应事件\n    /**\n    被点击的按钮，tag10 减   tag11 加\n    \n    - parameter button: 按钮\n    */\n    @objc private func didTappedCalculateButton(button: UIButton) {\n        delegate?.shoppingCartCell(self, button: button, countLabel: goodCountLabel)\n    }\n    \n    /**\n     选中了按钮后触发\n     \n     - parameter button: 被选中的按钮\n     */\n    @objc private func didSelectedButton(button: UIButton) {\n        \n        // 选中\n        button.selected = !button.selected\n        goodModel?.selected = button.selected\n        \n        // 重新计算价格\n        delegate?.reCalculateTotalPrice()\n    }\n    \n    // MARK: - 懒加载\n    /// 选择按钮\n    private lazy var selectButton: UIButton = {\n        let selectButton = UIButton(type: UIButtonType.Custom)\n        selectButton.setImage(UIImage(named: \"check_n\"), forState: UIControlState.Normal)\n        selectButton.setImage(UIImage(named: \"check_y\"), forState: UIControlState.Selected)\n        selectButton.addTarget(self, action: \"didSelectedButton:\", forControlEvents: UIControlEvents.TouchUpInside)\n        selectButton.sizeToFit()\n        return selectButton\n    }()\n    \n    /// 商品图片\n    private lazy var iconView: UIImageView = {\n        let iconView = UIImageView()\n        iconView.layer.cornerRadius = 30\n        iconView.layer.masksToBounds = true\n        return iconView\n    }()\n    \n    /// 商品标题\n    private lazy var titleLabel: UILabel = {\n        let titleLabel = UILabel()\n        return titleLabel\n    }()\n    \n    /// 新价格标签\n    private lazy var newPriceLabel: UILabel = {\n        let newPriceLabel = UILabel()\n        newPriceLabel.textColor = UIColor.redColor()\n        return newPriceLabel\n    }()\n    \n    // 老价格标签\n    private lazy var oldPriceLabel: JFOldPriceLabel = {\n        let oldPriceLabel = JFOldPriceLabel()\n        oldPriceLabel.textColor = UIColor.grayColor()\n        return oldPriceLabel\n    }()\n    \n    // 加减操作的view\n    private lazy var addAndsubtraction: UIView = {\n        let addAndsubtraction = UIView()\n        addAndsubtraction.backgroundColor = UIColor(white: 0.9, alpha: 0.8)\n        return addAndsubtraction\n    }()\n    \n    // 减号按钮\n    private lazy var subtractionButton: UIButton = {\n        let subtractionButton = UIButton(type: UIButtonType.Custom)\n        subtractionButton.tag = 10;\n        subtractionButton.setBackgroundImage(UIImage(named: \"subtraction_icon\"), forState: UIControlState.Normal)\n        subtractionButton.addTarget(self, action: \"didTappedCalculateButton:\", forControlEvents: UIControlEvents.TouchUpInside)\n        return subtractionButton\n    }()\n    \n    // 显示数量lbael\n    private lazy var goodCountLabel: UILabel = {\n        let goodCountLabel = UILabel()\n        goodCountLabel.textAlignment = NSTextAlignment.Center\n        return goodCountLabel\n    }()\n    \n    // 加号按钮\n    private lazy var addButton: UIButton = {\n        let addButton = UIButton(type: UIButtonType.Custom)\n        addButton.tag = 11\n        addButton.setBackgroundImage(UIImage(named: \"add_icon\"), forState: UIControlState.Normal)\n        addButton.addTarget(self, action: \"didTappedCalculateButton:\", forControlEvents: UIControlEvents.TouchUpInside)\n        return addButton\n    }()\n    \n}"
  },
  {
    "path": "shoppingCart/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "shoppingCart.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tA57AB3E01BFB6C3100012F62 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB3DF1BFB6C3100012F62 /* AppDelegate.swift */; };\n\t\tA57AB3E71BFB6C3100012F62 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A57AB3E61BFB6C3100012F62 /* Assets.xcassets */; };\n\t\tA57AB3EA1BFB6C3100012F62 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A57AB3E81BFB6C3100012F62 /* LaunchScreen.storyboard */; };\n\t\tA57AB4181BFB6E6500012F62 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB4091BFB6E6500012F62 /* Constraint.swift */; };\n\t\tA57AB4191BFB6E6500012F62 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB40A1BFB6E6500012F62 /* ConstraintAttributes.swift */; };\n\t\tA57AB41A1BFB6E6500012F62 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB40B1BFB6E6500012F62 /* ConstraintDescription.swift */; };\n\t\tA57AB41B1BFB6E6500012F62 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB40C1BFB6E6500012F62 /* ConstraintItem.swift */; };\n\t\tA57AB41C1BFB6E6500012F62 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB40D1BFB6E6500012F62 /* ConstraintMaker.swift */; };\n\t\tA57AB41D1BFB6E6500012F62 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB40E1BFB6E6500012F62 /* ConstraintRelation.swift */; };\n\t\tA57AB41E1BFB6E6500012F62 /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB40F1BFB6E6500012F62 /* Debugging.swift */; };\n\t\tA57AB41F1BFB6E6500012F62 /* EdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB4101BFB6E6500012F62 /* EdgeInsets.swift */; };\n\t\tA57AB4211BFB6E6500012F62 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB4121BFB6E6500012F62 /* LayoutConstraint.swift */; };\n\t\tA57AB4221BFB6E6500012F62 /* SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB4141BFB6E6500012F62 /* SnapKit.swift */; };\n\t\tA57AB4231BFB6E6500012F62 /* SourceLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB4151BFB6E6500012F62 /* SourceLocation.swift */; };\n\t\tA57AB4241BFB6E6500012F62 /* View+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB4161BFB6E6500012F62 /* View+SnapKit.swift */; };\n\t\tA57AB4251BFB6E6500012F62 /* ViewController+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57AB4171BFB6E6500012F62 /* ViewController+SnapKit.swift */; };\n\t\tA59F9BBC1BFCD30E0076221A /* JFGoodModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F9BBB1BFCD30E0076221A /* JFGoodModel.swift */; };\n\t\tA59F9BCA1BFCD3220076221A /* JFGoodListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F9BBF1BFCD3220076221A /* JFGoodListViewController.swift */; };\n\t\tA59F9BCB1BFCD3220076221A /* JFGoodListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F9BC21BFCD3220076221A /* JFGoodListCell.swift */; };\n\t\tA59F9BCC1BFCD3220076221A /* JFShoppingCartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F9BC51BFCD3220076221A /* JFShoppingCartViewController.swift */; };\n\t\tA59F9BCD1BFCD3220076221A /* JFOldPriceLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F9BC81BFCD3220076221A /* JFOldPriceLabel.swift */; };\n\t\tA59F9BCE1BFCD3220076221A /* JFShoppingCartCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F9BC91BFCD3220076221A /* JFShoppingCartCell.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\tA57AB3DC1BFB6C3100012F62 /* shoppingCart.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = shoppingCart.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tA57AB3DF1BFB6C3100012F62 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\tA57AB3E61BFB6C3100012F62 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tA57AB3E91BFB6C3100012F62 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\tA57AB3EB1BFB6C3100012F62 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tA57AB4091BFB6E6500012F62 /* Constraint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constraint.swift; sourceTree = \"<group>\"; };\n\t\tA57AB40A1BFB6E6500012F62 /* ConstraintAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintAttributes.swift; sourceTree = \"<group>\"; };\n\t\tA57AB40B1BFB6E6500012F62 /* ConstraintDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintDescription.swift; sourceTree = \"<group>\"; };\n\t\tA57AB40C1BFB6E6500012F62 /* ConstraintItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintItem.swift; sourceTree = \"<group>\"; };\n\t\tA57AB40D1BFB6E6500012F62 /* ConstraintMaker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMaker.swift; sourceTree = \"<group>\"; };\n\t\tA57AB40E1BFB6E6500012F62 /* ConstraintRelation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintRelation.swift; sourceTree = \"<group>\"; };\n\t\tA57AB40F1BFB6E6500012F62 /* Debugging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debugging.swift; sourceTree = \"<group>\"; };\n\t\tA57AB4101BFB6E6500012F62 /* EdgeInsets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EdgeInsets.swift; sourceTree = \"<group>\"; };\n\t\tA57AB4121BFB6E6500012F62 /* LayoutConstraint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutConstraint.swift; sourceTree = \"<group>\"; };\n\t\tA57AB4131BFB6E6500012F62 /* SnapKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SnapKit.h; sourceTree = \"<group>\"; };\n\t\tA57AB4141BFB6E6500012F62 /* SnapKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapKit.swift; sourceTree = \"<group>\"; };\n\t\tA57AB4151BFB6E6500012F62 /* SourceLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceLocation.swift; sourceTree = \"<group>\"; };\n\t\tA57AB4161BFB6E6500012F62 /* View+SnapKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"View+SnapKit.swift\"; sourceTree = \"<group>\"; };\n\t\tA57AB4171BFB6E6500012F62 /* ViewController+SnapKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"ViewController+SnapKit.swift\"; sourceTree = \"<group>\"; };\n\t\tA59F9BBB1BFCD30E0076221A /* JFGoodModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JFGoodModel.swift; sourceTree = \"<group>\"; };\n\t\tA59F9BBF1BFCD3220076221A /* JFGoodListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JFGoodListViewController.swift; sourceTree = \"<group>\"; };\n\t\tA59F9BC21BFCD3220076221A /* JFGoodListCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JFGoodListCell.swift; sourceTree = \"<group>\"; };\n\t\tA59F9BC51BFCD3220076221A /* JFShoppingCartViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JFShoppingCartViewController.swift; sourceTree = \"<group>\"; };\n\t\tA59F9BC81BFCD3220076221A /* JFOldPriceLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JFOldPriceLabel.swift; sourceTree = \"<group>\"; };\n\t\tA59F9BC91BFCD3220076221A /* JFShoppingCartCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JFShoppingCartCell.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tA57AB3D91BFB6C3100012F62 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tA57AB3D31BFB6C3100012F62 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA57AB3DE1BFB6C3100012F62 /* shoppingCart */,\n\t\t\t\tA57AB3DD1BFB6C3100012F62 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA57AB3DD1BFB6C3100012F62 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA57AB3DC1BFB6C3100012F62 /* shoppingCart.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA57AB3DE1BFB6C3100012F62 /* shoppingCart */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA57AB3FA1BFB6DB600012F62 /* Classes */,\n\t\t\t\tA57AB3DF1BFB6C3100012F62 /* AppDelegate.swift */,\n\t\t\t\tA57AB3E61BFB6C3100012F62 /* Assets.xcassets */,\n\t\t\t\tA57AB3E81BFB6C3100012F62 /* LaunchScreen.storyboard */,\n\t\t\t\tA57AB3EB1BFB6C3100012F62 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = shoppingCart;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA57AB3FA1BFB6DB600012F62 /* Classes */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BBD1BFCD3220076221A /* GoodList */,\n\t\t\t\tA59F9BC31BFCD3220076221A /* ShopCart */,\n\t\t\t\tA59F9BBA1BFCD30E0076221A /* Model */,\n\t\t\t\tA57AB3FF1BFB6DB600012F62 /* Library */,\n\t\t\t);\n\t\t\tpath = Classes;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA57AB3FF1BFB6DB600012F62 /* Library */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA57AB4081BFB6E6500012F62 /* SnapKit */,\n\t\t\t);\n\t\t\tpath = Library;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA57AB4081BFB6E6500012F62 /* SnapKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA57AB4091BFB6E6500012F62 /* Constraint.swift */,\n\t\t\t\tA57AB40A1BFB6E6500012F62 /* ConstraintAttributes.swift */,\n\t\t\t\tA57AB40B1BFB6E6500012F62 /* ConstraintDescription.swift */,\n\t\t\t\tA57AB40C1BFB6E6500012F62 /* ConstraintItem.swift */,\n\t\t\t\tA57AB40D1BFB6E6500012F62 /* ConstraintMaker.swift */,\n\t\t\t\tA57AB40E1BFB6E6500012F62 /* ConstraintRelation.swift */,\n\t\t\t\tA57AB40F1BFB6E6500012F62 /* Debugging.swift */,\n\t\t\t\tA57AB4101BFB6E6500012F62 /* EdgeInsets.swift */,\n\t\t\t\tA57AB4121BFB6E6500012F62 /* LayoutConstraint.swift */,\n\t\t\t\tA57AB4131BFB6E6500012F62 /* SnapKit.h */,\n\t\t\t\tA57AB4141BFB6E6500012F62 /* SnapKit.swift */,\n\t\t\t\tA57AB4151BFB6E6500012F62 /* SourceLocation.swift */,\n\t\t\t\tA57AB4161BFB6E6500012F62 /* View+SnapKit.swift */,\n\t\t\t\tA57AB4171BFB6E6500012F62 /* ViewController+SnapKit.swift */,\n\t\t\t);\n\t\t\tpath = SnapKit;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BBA1BFCD30E0076221A /* Model */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BBB1BFCD30E0076221A /* JFGoodModel.swift */,\n\t\t\t);\n\t\t\tpath = Model;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BBD1BFCD3220076221A /* GoodList */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BBE1BFCD3220076221A /* Controller */,\n\t\t\t\tA59F9BC01BFCD3220076221A /* Model */,\n\t\t\t\tA59F9BC11BFCD3220076221A /* View */,\n\t\t\t);\n\t\t\tpath = GoodList;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BBE1BFCD3220076221A /* Controller */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BBF1BFCD3220076221A /* JFGoodListViewController.swift */,\n\t\t\t);\n\t\t\tpath = Controller;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BC01BFCD3220076221A /* Model */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tpath = Model;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BC11BFCD3220076221A /* View */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BC21BFCD3220076221A /* JFGoodListCell.swift */,\n\t\t\t);\n\t\t\tpath = View;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BC31BFCD3220076221A /* ShopCart */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BC41BFCD3220076221A /* Controller */,\n\t\t\t\tA59F9BC61BFCD3220076221A /* Model */,\n\t\t\t\tA59F9BC71BFCD3220076221A /* View */,\n\t\t\t);\n\t\t\tpath = ShopCart;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BC41BFCD3220076221A /* Controller */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BC51BFCD3220076221A /* JFShoppingCartViewController.swift */,\n\t\t\t);\n\t\t\tpath = Controller;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BC61BFCD3220076221A /* Model */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tpath = Model;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA59F9BC71BFCD3220076221A /* View */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA59F9BC81BFCD3220076221A /* JFOldPriceLabel.swift */,\n\t\t\t\tA59F9BC91BFCD3220076221A /* JFShoppingCartCell.swift */,\n\t\t\t);\n\t\t\tpath = View;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tA57AB3DB1BFB6C3100012F62 /* shoppingCart */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = A57AB3EE1BFB6C3100012F62 /* Build configuration list for PBXNativeTarget \"shoppingCart\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tA57AB3D81BFB6C3100012F62 /* Sources */,\n\t\t\t\tA57AB3D91BFB6C3100012F62 /* Frameworks */,\n\t\t\t\tA57AB3DA1BFB6C3100012F62 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = shoppingCart;\n\t\t\tproductName = shoppingCart;\n\t\t\tproductReference = A57AB3DC1BFB6C3100012F62 /* shoppingCart.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tA57AB3D41BFB6C3100012F62 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 0710;\n\t\t\t\tLastUpgradeCheck = 0710;\n\t\t\t\tORGANIZATIONNAME = \"六阿哥\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tA57AB3DB1BFB6C3100012F62 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.1;\n\t\t\t\t\t\tDevelopmentTeam = GABKPEQD3S;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = A57AB3D71BFB6C3100012F62 /* Build configuration list for PBXProject \"shoppingCart\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = A57AB3D31BFB6C3100012F62;\n\t\t\tproductRefGroup = A57AB3DD1BFB6C3100012F62 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tA57AB3DB1BFB6C3100012F62 /* shoppingCart */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tA57AB3DA1BFB6C3100012F62 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA57AB3EA1BFB6C3100012F62 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\tA57AB3E71BFB6C3100012F62 /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tA57AB3D81BFB6C3100012F62 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA57AB41B1BFB6E6500012F62 /* ConstraintItem.swift in Sources */,\n\t\t\t\tA57AB4231BFB6E6500012F62 /* SourceLocation.swift in Sources */,\n\t\t\t\tA59F9BBC1BFCD30E0076221A /* JFGoodModel.swift in Sources */,\n\t\t\t\tA57AB41D1BFB6E6500012F62 /* ConstraintRelation.swift in Sources */,\n\t\t\t\tA57AB4221BFB6E6500012F62 /* SnapKit.swift in Sources */,\n\t\t\t\tA59F9BCE1BFCD3220076221A /* JFShoppingCartCell.swift in Sources */,\n\t\t\t\tA57AB41E1BFB6E6500012F62 /* Debugging.swift in Sources */,\n\t\t\t\tA59F9BCD1BFCD3220076221A /* JFOldPriceLabel.swift in Sources */,\n\t\t\t\tA57AB41F1BFB6E6500012F62 /* EdgeInsets.swift in Sources */,\n\t\t\t\tA57AB4181BFB6E6500012F62 /* Constraint.swift in Sources */,\n\t\t\t\tA57AB3E01BFB6C3100012F62 /* AppDelegate.swift in Sources */,\n\t\t\t\tA57AB4191BFB6E6500012F62 /* ConstraintAttributes.swift in Sources */,\n\t\t\t\tA57AB4211BFB6E6500012F62 /* LayoutConstraint.swift in Sources */,\n\t\t\t\tA57AB4251BFB6E6500012F62 /* ViewController+SnapKit.swift in Sources */,\n\t\t\t\tA59F9BCC1BFCD3220076221A /* JFShoppingCartViewController.swift in Sources */,\n\t\t\t\tA57AB4241BFB6E6500012F62 /* View+SnapKit.swift in Sources */,\n\t\t\t\tA59F9BCA1BFCD3220076221A /* JFGoodListViewController.swift in Sources */,\n\t\t\t\tA57AB41C1BFB6E6500012F62 /* ConstraintMaker.swift in Sources */,\n\t\t\t\tA57AB41A1BFB6E6500012F62 /* ConstraintDescription.swift in Sources */,\n\t\t\t\tA59F9BCB1BFCD3220076221A /* JFGoodListCell.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\tA57AB3E81BFB6C3100012F62 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tA57AB3E91BFB6C3100012F62 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tA57AB3EC1BFB6C3100012F62 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tA57AB3ED1BFB6C3100012F62 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.1;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tA57AB3EF1BFB6C3100012F62 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tINFOPLIST_FILE = shoppingCart/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = cn.6ag.shoppingCart;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tA57AB3F01BFB6C3100012F62 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tINFOPLIST_FILE = shoppingCart/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = cn.6ag.shoppingCart;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tA57AB3D71BFB6C3100012F62 /* Build configuration list for PBXProject \"shoppingCart\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tA57AB3EC1BFB6C3100012F62 /* Debug */,\n\t\t\t\tA57AB3ED1BFB6C3100012F62 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tA57AB3EE1BFB6C3100012F62 /* Build configuration list for PBXNativeTarget \"shoppingCart\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tA57AB3EF1BFB6C3100012F62 /* Debug */,\n\t\t\t\tA57AB3F01BFB6C3100012F62 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = A57AB3D41BFB6C3100012F62 /* Project object */;\n}\n"
  },
  {
    "path": "shoppingCart.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:shoppingCart.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "shoppingCart.xcodeproj/xcuserdata/jianfeng.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n   type = \"1\"\n   version = \"2.0\">\n   <Breakpoints>\n      <BreakpointProxy\n         BreakpointExtensionID = \"Xcode.Breakpoint.SwiftErrorBreakpoint\">\n         <BreakpointContent\n            shouldBeEnabled = \"Yes\"\n            ignoreCount = \"0\"\n            continueAfterRunningActions = \"No\">\n         </BreakpointContent>\n      </BreakpointProxy>\n   </Breakpoints>\n</Bucket>\n"
  },
  {
    "path": "shoppingCart.xcodeproj/xcuserdata/jianfeng.xcuserdatad/xcschemes/shoppingCart.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0710\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"A57AB3DB1BFB6C3100012F62\"\n               BuildableName = \"shoppingCart.app\"\n               BlueprintName = \"shoppingCart\"\n               ReferencedContainer = \"container:shoppingCart.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"A57AB3DB1BFB6C3100012F62\"\n            BuildableName = \"shoppingCart.app\"\n            BlueprintName = \"shoppingCart\"\n            ReferencedContainer = \"container:shoppingCart.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"A57AB3DB1BFB6C3100012F62\"\n            BuildableName = \"shoppingCart.app\"\n            BlueprintName = \"shoppingCart\"\n            ReferencedContainer = \"container:shoppingCart.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"A57AB3DB1BFB6C3100012F62\"\n            BuildableName = \"shoppingCart.app\"\n            BlueprintName = \"shoppingCart\"\n            ReferencedContainer = \"container:shoppingCart.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "shoppingCart.xcodeproj/xcuserdata/jianfeng.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>shoppingCart.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>0</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict>\n\t\t<key>A57AB3DB1BFB6C3100012F62</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  }
]