text:
It's being already more than four months working full-time in Javascript and I miss already my time creating Python scripts.

Today I decided to break with it, and build with Python a simple implementation of a [Blockchain](https://en.wikipedia.org/wiki/Blockchain) that should help me to dive again into basic Python concepts.

Don't be scared if you don't have any experience with the topic. Actually, the concept behind Blockchain is pretty simple and it will only take just a few lines to build our simple 'not-decentralized version'.

# What is Blockchain?

Quoting Wikipedia, Blockchain is *a continuously growing list of records, called blocks, which are linked and secured using cryptography. Each block typically contains a hash pointer as a link to a previous block, a timestamp and transaction data. By design, blockchains are inherently resistant to modification of the data*.

The brain behind this concept is the person or group of people well-known by the pseudonym of [Satoshi Nakamoto](https://en.wikipedia.org/wiki/Satoshi_Nakamoto). But since then, Blockchain has evolved into something greater that has the potential to transform many industries and our daily lives.

Let's not focus on the potential of the Blockchain and directly jump into one of the most important concepts you need to know to understand the technology, **hash functions**.

## Cryptographic Hash Functions

A hash function is a function that takes a particular input - typically called message, and applies mathematical transformations that finishes with a returning output - typically called digest, tag or hash.

You can hash any kind of data to create the digital signature using any of the long list of existing possible functions like md5, sha256 or bcrypt ([please use bcrypt!!](https://medium.com/@danboterhoven/why-you-should-use-bcrypt-to-hash-passwords-af330100b861)).

# Blocks

For our Blockchain implementation, each block will contain a list of transactions, the creation time, the hash value of the previous block, and the actual hash of the block.

The key resides on the way the new hash for the block is created, as it assures that the chain of blocks is consistent and unbreakable. For each new block in the chain, the new hash will use as a message or input the combination of the transaction list and the previous hash block.

That means that if something change in some earlier block, the consecutive hashes (or digital signatures) of the next blocks should change or the chain will become inconsistent.

```python
import hashlib
import datetime

class Block():
    previous_hash = ""
    transactions = []
    time = ""
    block_hash = ""

    def __init__(self, prev_hash, transaction_list):
        self.transactions = transaction_list
        self.previous_hash = prev_hash
        messages = [self._hash(x) for x in transaction_list] + [prev_hash]
        self.block_hash = self._hash("".join(messages))
        self.time = str(datetime.datetime.now())

    def _hash(self, string):
        return hashlib.sha256(string).hexdigest()
```

# Our Blockchain

Our Blockchain class will contain the list of blocks in the chain and the representation of the last block appended in the list (only used to quickly retrieve the last hash value for the creation of the possible new entry block in the chain).

In addition, during the class initialization we will need to create a hardcoded block also called the **genesis block**, which is the first block in the chain that has no previous block.

The transactions in our Blockchain will be simple informative strings.

```python
class Blockchain():
    block_list = []
    last_block = None

    def __init__(self):
        # needed an initial block
        genesis_transactions = ["satoshi sent 2BTC to jose"]
        genesis_block = Block('', genesis_transactions)
        self.last_block = genesis_block
        self.block_list.append(genesis_block)
        print('Blockchain created with genesis_block hash', genesis_block.block_hash)
        print('Blockchain size', len(self.block_list))

    def add_block(self, transactions):
        block = Block(self.last_block.block_hash, transactions)
        self.last_block = block
        self.block_list.append(block)

    # static method, you can call it without initializing the class
    # in order to get info about the possible hash algorithms
    def available_algorithms():
        print('available:')
        print(hashlib.algorithms_available) # algorithms present in the module and OpenSSI
        print('guaranteed:')
        print(hashlib.algorithms_guaranteed) # algorithms present in the module
```

To test our *pseudo Blockchain*:

```python
bc = Blockchain() # inheritance of class Blockchain
bc.add_block(["jose sent 1BTC to evan", "evan sent 0.5BTC to satoshi"])
print("lenght of the chain: ")
print(len(bc.block_list) - 1) # minus one because of the genesis_block
print(bc)
```

# Improve our class: special methods

My friend [@eliasdorneles](https://twitter.com/eliasdorneles) introduced to me how cool and potential are the special methods or magic functions for the Python Data Model by reading the first chapter of the book [Fluent Python](http://shop.oreilly.com/product/0636920032519.do) - which I strongly recommend to read if you are a Python newbie.

To summarize the chapter in just one sentence, we use magic functions to redefine those operations in Python that were generic for a group of types and which were intended to work even for objects that didn't have methods at all.

For example, we want that our Blockchain class acts like a dictionary, but we don't want to *delete* and *set* from created blocks, we just want to access to the blocks by index, and be able to retrieve the length of the chain by calling the built-in function len(). In this case, by just defining the function *__len__()* and *__getitem__(key)* we can achieve our purpose -  no need in this case to define *__setitem__(key, value)* or *__delitem__(key)*.

In addition, we note that when running the previous code the output of the last *print(bc)* returns an ugly *<__main__.Blockchain instance at 0x7f9a10481200>*. We also want to make the string conversion of the class more meaningful for the users when the function *print* is called. By just defining the function *__str__()* we can achieve our purpose.

```python
class Blockchain():
    block_list = []
    last_block = None

    def __init__(self):
        # needed an initial block
        genesis_transactions = ["satoshi sent 2BTC to jose"]
        genesis_block = Block('', genesis_transactions)
        self.last_block = genesis_block
        self.block_list.append(genesis_block)
        print('Blockchain created with genesis_block hash', genesis_block.block_hash)
        print('Blockchain size', len(self.block_list))

    def __getitem__(self, index):
        return self.block_list[index + 1]

    def __len__(self):
        return len(self.block_list) - 1

    def __str__(self):
        # multi-line
        message = """Total of {lenght} block(s)
            Last block:
            - transactions: {txs}
            - hash: {hash}
            """
        return message.format(lenght = str(len(self)), txs = str(self.previous_block.transactions), hash = str(self.previous_block.block_hash))

    def add_block(self, transactions):
        block = Block(self.last_block.block_hash, transactions)
        self.last_block = block
        self.block_list.append(block)
```

Now when the execute the script, we can access to the blocks in our Blockchain by index, get the real length of the chain by using the *len()* function, or the *print(bc)* will output in the console something as nice as:

```python
Total of 1 block(s)
Last block:
- transactions: ['jose sent 1BTC to evan', 'evan sent 0.5BTC to satoshi']
- hash: c6d52d5840b31cc4f79b6aca78acfa59c7507a92db20f667b2ce23befcdd8850
```


text:
Exec command output stream consumer parser written in Go.

### Activating debug messages

streamon package debug logging output can be enabled through the use of `-ldflags` when building or running your program.

Example usage:

    go run -ldflags '-X streamon.debugEnabled true' *.go

redpajama_set_name: RedPajamaGithub


text:
<?php
namespace Concrete\Core\Backup\ContentImporter\Importer\Routine;

use Concrete\Core\Workflow\Type;
use Concrete\Core\Workflow\Workflow;

class ImportWorkflowsRoutine extends AbstractRoutine
{
    public function getHandle()
    {
        return 'workflow_progress_categories';
    }

    public function import(\SimpleXMLElement $sx)
    {
        if (isset($sx->workflows)) {
            foreach ($sx->workflows->workflow as $wf) {
                $pkg = static::getPackageObject($wf['package']);
                $workflow = Workflow::getByName((string) $wf['name']);
                if (!is_object($workflow)) {
                    $type = Type::getByHandle((string) $wf['type']);
                    if (is_object($type)) {
                        Workflow::add($type, (string) $wf['name'], $pkg);
                    }
                }
            }
        }
    }

}


text:
var maple = require('../treeRouter.js')
   , tree = new maple.RouteTree()
   , assert = require('assert')

tree.define('/hello/:world/', function () {
})

tree.define('/colon/:test/definite/', function () {
})

tree.define('/slashes/:foo/:bar', function () {
})

var match = tree.match('/hello/dude')
assert.equal(match.params.world, 'dude')

match = tree.match('/hello/hello%20world/')
assert.equal(match.params.world, 'hello world')
console.log(match.params.world)

match = tree.match('/colon/hello%20world/definite/') //test decodeURIComponent
assert(match.perfect)
assert.equal(match.params.test, 'hello world')

match = tree.match('/hello/notable%5Gtodecode')
assert.equal(match.params.world, 'notable%5Gtodecode') //when not a valid URI, it will just attach string verbatum

match = tree.match('/slashes/this%2Fis/a%20test')
console.log(match.perfect);
assert.ok(match.perfect, 'should be a perfect match')
assert.equal(match.params.foo, 'this/is', 'should have unsecaped slash') //Should have the decoded slash
assert.equal(match.params.bar, 'a test', 'should have unescaped space') //Should have the decoded space


text:
package org.apache.ctakes.core.util;

import java.lang.reflect.Field;

import org.apache.uima.jcas.cas.TOP;
import org.apache.uima.jcas.tcas.Annotation;

public class JCasUtil {

	public static int getType(String className) {
		try {
			Class<?> cls = Class.forName(className);
			Class<? extends TOP> annotationCls = cls.asSubclass(Annotation.class);
			return JCasUtil.getType(annotationCls);
		} catch (Exception e) {
			throw new IllegalArgumentException(e);
		}
	}

	public static int getType(Class<? extends TOP> cls) {
		try {
			Field typeField = cls.getDeclaredField("type");
			// return value of static field
			return typeField.getInt(null);
		} catch (Exception e) {
			throw new IllegalArgumentException(e);
		}

	}
}


text:
<?php
namespace Application\Sonata\UserBundle\Entity;

use Sonata\UserBundle\Entity\BaseUser as BaseUser;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

use Gregwar\ImageBundle\Image;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user_user")
 */
class User extends BaseUser
{
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

    /**
     * Get id
     *
     * @return integer $id
     */
    public function getId()
    {
        return $this->id;
    }

    const SEX_MALE          = 'male';
    const SEX_FEMALE        = 'female';

    /**
     * @ORM\Column(name="sex", type="string", columnDefinition="ENUM('male', 'female')", nullable="true")
     */
    private $sex;

    /**
     * @var string $mobilePhone
     *
     * @ORM\Column(name="mobile_phone", type="string", length="15", nullable="false")
     */
    private $mobilePhone;

    /**
     * @var string $path
     *
     * @ORM\Column(name="path", type="string", length="255", nullable="true")
     */
    private $path;

    /**
     * @var string $firstName
     *
     * @ORM\Column(name="first_name", type="string", length="255", nullable="true")
     */
    private $firstName;

    /**
     * @var string $lastName
     *
     * @ORM\Column(name="last_name", type="string", length="255", nullable="true")
     */
    private $lastName;

    /**
     * @var string $birthday
     *
     * @ORM\Column(type="date", nullable="false")
     */
    private $birthday;

    /**
     * @var integer $zip
     *
     * @ORM\Column(name="zip", type="integer", nullable="true")
     */
    private $zip;

    /**
     * @var PromoUser
     *
     * @ORM\OneToMany(targetEntity="MTM\AdminBundle\Entity\PromoUser", mappedBy="user", cascade={"remove"})
     */
    private $promoUser;

    /**
     * Override FOSUserBundle username set as email
     * @param $email
     */
    public function setEmail($email)
    {
        parent::setEmail($email);
//        $this->setUsername($email);
    }

    /**
     * Get sex
     *
     * @return string
     */
    public function getSex()
    {
//        var_dump($this->sex);die;
        return $this->sex;
    }

    /**
     * Set sex
     *
     * @param string $sex
     * @throws \InvalidArgumentException
     */
    public function setSex($sex)
    {
        if (!in_array($sex, array(self::SEX_FEMALE, self::SEX_MALE))) {
            throw new \InvalidArgumentException("Invalid sex");
        }

        $this->sex = $sex;
    }

    /**
     * Set mobilePhone
     *
     * @param string $mobilePhone
     */
    public function setMobilePhone($mobilePhone)
    {
        $this->mobilePhone = $mobilePhone;
    }

    /**
     * Get mobilePhone
     *
     * @return string
     */
    public function getMobilePhone()
    {
        return $this->mobilePhone;
    }

    /**
     * Set path
     *
     * @param string $path
     */
    public function setPath($path)
    {
        $this->path = $path;
    }

    /**
     * Get path
     *
     * @return string
     */
    public function getPath()
    {
        return $this->path;
    }

    /**
     * Set firstName
     *
     * @param string $firstName
     */
    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;
    }

    /**
     * Get firstName
     *
     * @return string
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * Set lastName
     *
     * @param string $lastName
     */
    public function setLastName($lastName)
    {
        $this->lastName = $lastName;
    }

    /**
     * Get lastName
     *
     * @return string
     */
    public function getLastName()
    {
        return $this->lastName;
    }

    /**
     * Set birthday
     *
     * @param $birthday
     */
    public function setBirthday($birthday)
    {
        $this->birthday = $birthday;
    }

    /**
     * Get birthday
     *
     * @return string
     */
    public function getBirthday()
    {
        return $this->birthday;
    }

    /**
     * Set zip
     *
     * @param integer $zip
     */
    public function setZip($zip)
    {
        $this->zip = $zip;
    }

    /**
     * Get zip
     *
     * @return integer
     */
    public function getZip()
    {
        return $this->zip;
    }

    /**
     * @var file not column
     */
    public $avatar;

    /**
     * Get absolute path
     *
     * @return null|string
     */
    public function getAbsolutePath()
    {
        return null === $this->path ? null : $this->getUploadRootDir(). '/' . $this->getId() . '/' . $this->path;
    }

    /**
     * Get web path
     *
     * @return null|string
     */
    public function getWebPath()
    {
        return null === $this->path ? $this->getNoAvatar() : $this->getUploadDir(). '/' . $this->getId() . '/' . $this->path;
    }

    /**
     * Get upload root dir (with user id)
     *
     * @return string
     */
    protected function getUploadRootDir()
    {
        // the absolute directory path where uploaded documents should be saved
        return __DIR__.'/../../../../../web/'.$this->getUploadDir() .'/'. $this->getId() . '/';
    }

    /**
     * Get upload dir
     *
     * @return string
     */
    public function getUploadDir()
    {
        // get rid of the __DIR__ so it doesn't screw when displaying uploaded doc/image in the view.
        return 'uploads/documents/user';
    }

    /**
     * Get upload dir
     *
     * @return string
     */
    public function getNoAvatar()
    {
        // get rid of the __DIR__ so it doesn't screw when displaying uploaded doc/image in the view.
        return 'uploads/documents/no_avatar.png';
    }

    public function upload()
    {
        // the file property can be empty if the field is not required
        if (null === $this->avatar) {
            return;
        }

        // we use the original file name here but you should
        // sanitize it at least to avoid any security issues

        // move takes the target directory and then the target filename to move to
        $this->avatar->move($this->getUploadRootDir(), $this->avatar->getClientOriginalName());
        /*Image::open($this->avatar->getPathname())*/
        Image::open($this->getUploadRootDir() . $this->avatar->getClientOriginalName())
            ->resize(66, 66)
            ->save($this->getUploadRootDir() . $this->avatar->getClientOriginalName());

        // set the path property to the filename where you'ved saved the file
        $this->path = $this->avatar->getClientOriginalName();

        // clean up the file property as you won't need it anymore
        $this->avatar = null;
    }

    public function isCanRegister()
    {
        $now = new \DateTime();

        if (null === $this->getBirthday()) {
            return true;
        }

        if ($this->getBirthday() instanceof \DateTime) {
            $date   = $this->getBirthday();
        } else {
            $date   = new \DateTime($this->getBirthday());
        }

        return ($now->diff($date)->y > 13);
    }
}


text:
We're going to build an e-commerce site! We're going to make an online store where users can browse items, put items in their carts, and buy items, which changes our inventory. We're eventually going to integrate the Stripe API to handle payments, and then integrate Segment.io to analyze user events.

Before anything, note that when you generate models, controllers, etc, be sure to include this option, so that it skips tests (which we already have): `--no-test-framework`

## First iteration

### Tasks:

1. Models and Associations
* Use the model tests to guide your model associations
* There's a seed file with some data generated with the Faker gem.
* Some hints:
  * We're going to treat our shopping cart like a session; a cart is instantiated and marked as a session when we add our first item to our cart.
  * line_items are like join tables between items and carts. They come into existance when we add an item to our cart.
  * Orders are instantiated during checkout and belong to a cart. They will act as a join table between a user and a cart.
  * an Item has a title, price (integer, in cents), and inventory (integer)
  * a Category has a title
  * a Line item has a quantity
  * an Order has a status and total (integer, in cents, which comes from the cart's total)

2. Functionality through class and instance methods and controller actions
  * Use the tests to guide basic functionality
  * Our Cart should be able to:
    * add the same item more than once; the line_item's quantity should change in this event
    * display a total given the price/quantity of all line_items (think about keeping this logic out of the views!).
  * A user can buy items that they put in their cart, which changes the inventory of the item. Actual purchase functionality will come later through Stripe.
  * When a user checks out, an order object should be created. An order should have a status of "submitted" when checkout is complete, and its total should be set from the cart's total.

3. Views for Program Flow
  * Add to cart buttons for each item
  * Navigation bar for visiting store home page and cart
  * Cart link should only be visible if user has added items to the cart (you should build helper methods in the `application_controller` to accomplish this)
  * Checkout link (checkout should be a POST request method on the carts controller)
  * Create a helper module in the `app/helpers` directory that will be used in our views to display our item prices and order and cart totals in a readable currency number (if the price is 4000 cents, display it as a readable 40.00).

## Up Next

Stripe integration and order flow


text:
require 'test_helper'

module ActiveModel
  module Validations

    describe DateValidator do

      before do
        TestRecord.reset_callbacks(:validate)
      end

      it "checks validity of the arguments" do
        [3, "foo", 1..6].each do |wrong_argument|
          proc {
            TestRecord.validates(:expiration_date, date: { before: wrong_argument })
          }.must_raise(ArgumentError, ":before must be a time, a date, a time_with_zone, a symbol or a proc")
        end
      end

      it "complains when no options are provided" do
        I18n.backend.reload!
        TestRecord.validates :expiration_date,
                             date: { before: Time.now }

        model = TestRecord.new(nil)
        model.valid?.must_equal false
        model.errors[:expiration_date].must_equal(["is not a date"])
      end

      it "works with helper methods" do
        time = Time.now
        TestRecord.validates_date_of :expiration_date, before: time
        model = TestRecord.new(time + 20000)
        model.valid?.must_equal false
      end

      [:valid,:invalid].each do |must_be|
        _context = must_be == :valid ? 'when value validates correctly' : 'when value does not match validation requirements'

        describe _context do
          [:after, :before, :after_or_equal_to, :before_or_equal_to, :equal_to].each do |check|
              now = Time.now.to_datetime

              model_date = case check
                when :after              then must_be == :valid ? now + 21000 : now - 1
                when :before             then must_be == :valid ? now - 21000 : now + 1
                when :after_or_equal_to  then must_be == :valid ? now : now - 21000
                when :before_or_equal_to then must_be == :valid ? now : now + 21000
                when :equal_to           then must_be == :valid ? now : now + 21000
              end

              it "ensures that an attribute is #{must_be} when #{must_be == :valid ? 'respecting' : 'offending' } the #{check} check" do
                TestRecord.validates :expiration_date,
                                     date: {:"#{check}" => now}

                model = TestRecord.new(model_date)
                must_be == :valid ? model.valid?.must_equal(true) : model.valid?.must_equal(false)
              end

              if _context == 'when value does not match validation requirements'
                it "yields a default error message indicating that value must be #{check} validation requirements" do
                  TestRecord.validates :expiration_date,
                                       date: {:"#{check}" => now}

                  model = TestRecord.new(model_date)
                  model.valid?.must_equal false
                  model.errors[:expiration_date].must_equal(["must be " + check.to_s.gsub('_',' ') + " #{I18n.localize(now)}"])
                end
              end
          end

          if _context == 'when value does not match validation requirements'
            now = Time.now.to_datetime

            it "allows for a custom validation message" do
              TestRecord.validates :expiration_date,
                                   date: { before_or_equal_to: now,
                                           message: 'must be after Christmas' }

              model = TestRecord.new(now + 21000)
              model.valid?.must_equal false
              model.errors[:expiration_date].must_equal(["must be after Christmas"])
            end

            it "allows custom validation message to be handled by I18n" do
              custom_message = 'Custom Date Message'
              I18n.backend.store_translations('en', { errors: { messages: { not_a_date: custom_message }}})

              TestRecord.validates :expiration_date, date: true

              model = TestRecord.new(nil)
              model.valid?.must_equal false
              model.errors[:expiration_date].must_equal([custom_message])
            end
          end

        end
      end

      extra_types = [:proc, :symbol]
      extra_types.push(:date) if defined?(Date) and defined?(DateTime)
      extra_types.push(:time_with_zone) if defined?(ActiveSupport::TimeWithZone)

      extra_types.each do |type|
        it "accepts a #{type} as an argument to a check" do
          case type
            when :proc then
              TestRecord.validates(:expiration_date, date: { after: Proc.new {Time.now + 21000} }).must_be_kind_of Hash
            when :symbol then
              TestRecord.send(:define_method, :min_date, lambda { Time.now + 21000 })
              TestRecord.validates(:expiration_date, date: { after: :min_date }).must_be_kind_of Hash
            when :date then
              TestRecord.validates(:expiration_date, date: { after: Time.now.to_date }).must_be_kind_of Hash
            when :time_with_zone then
              Time.zone = "Hawaii"
              TestRecord.validates(:expiration_date, date: { before: Time.zone.parse((Time.now + 21000).to_s) }).must_be_kind_of Hash
          end
        end
      end

      it "gracefully handles an unexpected result from a proc argument evaluation" do
        TestRecord.validates :expiration_date,
                             date: { after: Proc.new { nil } }

        TestRecord.new(Time.now).valid?.must_equal false
      end

      it "gracefully handles an unexpected result from a symbol argument evaluation" do
        TestRecord.send(:define_method, :min_date, lambda { nil })
        TestRecord.validates :expiration_date,
                             date: { after: :min_date }

        TestRecord.new(Time.now).valid?.must_equal false
      end

      describe "with type cast attributes" do
        before do
          TestRecord.send(:define_method, :expiration_date_before_type_cast, lambda { 'last year' })
        end

        it "should detect invalid date expressions when nil is allowed" do
          TestRecord.validates(:expiration_date, date: true, allow_nil: true)
          TestRecord.new(nil).valid?.must_equal false
        end

        it "should detect invalid date expressions when blank is allowed" do
          TestRecord.validates(:expiration_date, date: true, allow_blank: true)
          TestRecord.new(nil).valid?.must_equal false
        end
      end
    end

  end
end


text:
from cloudify import ctx
from cloudify.decorators import operation

@operation
def install(**_):
    ctx.logger.warn(
        'Diamond plugin functionality is deprecated in Cloudify 5. '
        'Doing nothing.')

@operation
def uninstall(**_):
    ctx.logger.warn(
        'Diamond plugin functionality is deprecated in Cloudify 5. '
        'Doing nothing.')

@operation
def start(**_):
    ctx.logger.warn(
        'Diamond plugin functionality is deprecated in Cloudify 5. '
        'Doing nothing.')

@operation
def stop(**_):
    ctx.logger.warn(
        'Diamond plugin functionality is deprecated in Cloudify 5. '
        'Doing nothing.')

@operation
def add_collectors(**_):
    ctx.logger.warn(
        'Diamond plugin functionality is deprecated in Cloudify 5. '
        'Doing nothing.')

@operation
def del_collectors(**_):
    ctx.logger.warn(
        'Diamond plugin functionality is deprecated in Cloudify 5. '
        'Doing nothing.')


text:
FROM google/golang

ADD . /gopath/src/github.com/may215/go2aws
WORKDIR /gopath/src/github.com/may215/go2aws
RUN go get
RUN go install
RUN cp -r public /var/www

ENTRYPOINT ["/gopath/bin/go2aws"]
CMD ["-public", "/var/www"]


text:
import {SparkPlugin} from '@ciscospark/spark-core';
import {Context, Request, Response} from 'node-kms';
import KMSBatcher, {TIMEOUT_SYMBOL} from './kms-batcher';
import jose from 'node-jose';
import {omit} from 'lodash';

const contexts = new WeakMap();
const kmsDetails = new WeakMap();
const partialContexts = new WeakMap();

/**
 * @class
 */
const KMS = SparkPlugin.extend({
  namespace: `Encryption`,

  children: {
    batcher: KMSBatcher
  },

  /**
   * Binds a key to a resource
   * @param {Object} options
   * @param {KMSResourceObject} options.kro
   * @param {string} options.kroUri
   * @param {Key} options.key
   * @param {string} options.keyUri
   * @returns {Promise<Key>}
   */
  bindKey({kro, kroUri, key, keyUri}) {
    kroUri = kroUri || kro.uri;
    keyUri = keyUri || key.uri;

    this.logger.info(`kms: binding key to resource`);

    /* istanbul ignore if */
    if (!kroUri) {
      return Promise.reject(new Error(`\`kro\` or \`kroUri\` is required`));
    }

    /* istanbul ignore if */
    if (!keyUri) {
      return Promise.reject(new Error(`\`key\` or \`keyUri\` is required`));
    }

    return this.request({
      method: `update`,
      resourceUri: kroUri,
      uri: keyUri
    })
      .then((res) => {
        this.logger.info(`kms: bound key to resource`);
        return res.key;
      });
  },

  /**
   * Creates a new KMS Resource
   * @param {Object} options
   * @param {Array<string>} options.userIds
   * @param {Array<string>} options.keyUris
   * @param {Key} options.key
   * @param {Array<Keys>} options.keys
   * @returns {Promise<KMSResourceObject>}
   */
  createResource({userIds, keyUris, key, keys}) {
    keyUris = keyUris || [];
    /* istanbul ignore if */
    if (keys) {
      keyUris = keys.reduce((uris, k) => {
        uris.push(k.uri);
        return uris;
      }, keyUris);
    }

    /* istanbul ignore else */
    if (key) {
      keyUris.push(key.uri);
    }

    /* istanbul ignore if */
    if (keyUris.length === 0) {
      return Promise.reject(new Error(`Cannot create KMS Resource without at least one keyUri`));
    }

    this.logger.info(`kms: creating resource`);

    return this.request({
      method: `create`,
      uri: `/resources`,
      userIds,
      keyUris
    })
      .then((res) => {
        this.logger.info(`kms: created resource`);
        return res.resource;
      });
  },

  /**
   * Requests `count` unbound keys from the kms
   * @param {Object} options
   * @param {Number} options.count
   * @returns {Array<Key>}
   */
  createUnboundKeys({count}) {
    this.logger.info(`kms: request ${count} unbound keys`);

    /* istanbul ignore if */
    if (!count) {
      return Promise.reject(new Error(`\`options.count\` is required`));
    }

    return this.request({
      method: `create`,
      uri: `/keys`,
      count
    })
      .then((res) => {
        this.logger.info(`kms: received unbound keys`);
        return Promise.all(res.keys.map(this.asKey));
      });
  },

  /**
   * Fetches the specified key from the kms
   * @param {Object} options
   * @param {string} options.uri
   * @returns {Promise<Key>}
   */
  fetchKey({uri}) {
    /* istanbul ignore if */
    if (!uri) {
      return Promise.reject(new Error(`\`options.uri\` is required`));
    }

    this.logger.info(`kms: fetching key`);

    return this.request({
      method: `retrieve`,
      uri
    })
      .then((res) => {
        this.logger.info(`kms: fetched key`);
        return this.asKey(res.key);
      });
  },

  /**
   * Pings the kms. Mostly for testing
   * @returns {Promise}
   */
  ping() {
    return this.request({
      method: `update`,
      uri: `/ping`
    });
  },

  /**
   * Ensures a key obect is Key instance
   * @param {Object} key
   * @returns {Promise<Key>}
   */
  asKey(key) {
    return jose.JWK.asKey(key.jwk)
      .then((jwk) => {
        key.jwk = jwk;
        return key;
      });
  },

  /**
   * Adds appropriate metadata to the KMS request
   * @param {Object} payload
   * @returns {Promise<KMS.Request>}
   */
  prepareRequest(payload) {
    const isECDHRequest = payload.method === `create` && payload.uri.includes(`/ecdhe`);
    return Promise.resolve(isECDHRequest ? partialContexts.get(this) : this._getContext())
      .then((context) => {
        this.logger.info(`kms: wrapping ${isECDHRequest ? `ephemeral key` : `kms`} request`);
        const req = new Request(payload);
        return req.wrap(context, {serverKey: isECDHRequest})
          .then(() => {
            /* istanbul ignore else */
            if (process.env.NODE_ENV !== `production`) {
              this.logger.info(`kms: request payload`, omit(JSON.parse(JSON.stringify(req)), `wrapped`));
            }
            return req;
          });
      });
  },

  /**
   * Accepts a kms message event, decrypts it, and passes it to the batcher
   * @param {Object} event
   * @returns {Promise<Object>}
   */
  processKmsMessageEvent(event) {
    this.logger.info(`kms: received kms message`);
    return Promise.all(event.encryption.kmsMessages.map((kmsMessage, index) => this._isECDHEMessage(kmsMessage)
      .then((isECDHMessage) => {
        this.logger.info(`kms: received ${isECDHMessage ? `ecdhe` : `normal`} message`);
        const res = new Response(kmsMessage);
        return Promise.resolve(isECDHMessage ? partialContexts.get(this) : contexts.get(this))
          // eslint-disable-next-line max-nested-callbacks
          .then((context) => res.unwrap(context))
          // eslint-disable-next-line max-nested-callbacks
          .then(() => {event.encryption.kmsMessages[index] = res;})
          // eslint-disable-next-line max-nested-callbacks
          .then(() => res);
      })
    ))
      .then(() => this.batcher.processKmsMessageEvent(event))
      .catch((reason) => {
        this.logger.error(`kms: decrypt failed`, reason.stack);
        return Promise.reject(reason);
      })
      .then(() => event);
  },

  /**
   * Decrypts a kms message
   * @param {Object} kmsMessage
   * @returns {Promise<Object>}
   */
  decryptKmsMessage(kmsMessage) {
    const res = new Response(kmsMessage);
    return contexts.get(this)
      .then((context) => res.unwrap(context))
      .then(() => res.body);
  },

  /**
   * Determines if the kms message is an ecdhe message or a normal message
   * @param {Object} kmsMessage
   * @returns {Promise<boolean>}
   */
  _isECDHEMessage(kmsMessage) {
    return this._getKMSStaticPubKey()
      .then((kmsStaticPubKey) => {
        const fields = kmsMessage.split(`.`);

        if (fields.length !== 3) {
          return false;
        }

        const header = JSON.parse(jose.util.base64url.decode(fields[0]));

        return header.kid === kmsStaticPubKey.kid;
      });
  },

  /**
   * Sends a request to the kms
   * @param {Object} payload
   * @param {Number} timeout (internal)
   * @returns {Promise<Object>}
   */
  request(payload, timeout) {
    timeout = timeout || this.config.kmsInitialTimeout;

    // Note: this should only happen when we're using the async kms batcher;
    // once we implement the sync batcher, this'll need to be smarter.
    return this.spark.mercury.connect()
      .then(() => this.prepareRequest(payload))
      .then((req) => {
        req[TIMEOUT_SYMBOL] = timeout;
        return this.batcher.request(req);
      })
      .catch((reason) => {
        // Ideally, most or all of the code below would go in kms-batcher, but
        // but batching needs at least one more round of refactoring for that to
        // work.
        if (!reason.statusCode && !reason.status) {
          /* istanbul ignore else */
          if (process.env.NODE_ENV !== `production`) {
            /* istanbul ignore next: reason.stack vs stack difficult to control in test */
            this.logger.info(`kms: request error`, reason.stack || reason);
          }

          timeout = timeout * 2;

          if (timeout >= this.config.kmsMaxTimeout) {
            this.logger.info(`kms: exceeded maximum KMS request retries; negotiating new ecdh key`);

            /* istanbul ignore else */
            if (process.env.NODE_ENV !== `production`) {
              this.logger.info(`kms: timeout/maxtimeout`, timeout, this.config.kmsMaxTimeout);
            }

            contexts.delete(this);
            timeout = 0;
          }

          return this.request(payload, timeout);
        }

        return Promise.reject(reason);
      });
  },

  /**
   * @private
   * @returns {Promise<string>}
   */
  _getAuthorization() {
    // Remove the `Bearer` prefix from the token; we'll improve this when we add
    // token downscoping.
    return this.spark.credentials.getAuthorization()
      .then((authorization) => authorization.replace(/[Bb]earer\s+/, ``));
  },

  /**
   * @private
   * @returns {Promise<Object>}
   */
  _getContext() {
    let promise = contexts.get(this);
    if (!promise) {
      promise = this._prepareContext();
      contexts.set(this, promise);
      promise.then((context) => {
        const expiresIn = context.ephemeralKey.expirationDate - Date.now() - 30000;
        setTimeout(() => contexts.unset(this), expiresIn);
      });
    }

    return Promise.all([
      promise,
      this._getAuthorization()
    ])
      .then(([context, authorization]) => {
        context.clientInfo.credential.bearer = authorization;
        return context;
      });
  },

  /**
   * @private
   * @returns {Promise<Object>}
   */
  _getKMSCluster() {
    this.logger.info(`kms: retrieving KMS cluster`);
    return this._getKMSDetails()
      .then(({kmsCluster}) => kmsCluster);
  },

  /**
   * @private
   * @returns {Promise<Object>}
   */
  _getKMSDetails() {
    let details = kmsDetails.get(this);
    if (!details) {
      this.logger.info(`kms: fetching KMS details`);
      details = this.spark.request({
        service: `encryption`,
        resource: `/kms/${this.spark.device.userId}`
      })
        .then((res) => {
          this.logger.info(`kms: fetched KMS details`);
          const body = res.body;
          body.rsaPublicKey = JSON.parse(body.rsaPublicKey);
          return body;
        })
        .catch((reason) => {
          this.logger.error(`kms: failed to fetch KMS details`, reason);
          return Promise.reject(reason);
        });

      kmsDetails.set(this, details);
    }

    return details;
  },

  /**
   * @private
   * @returns {Promise<Object>}
   */
  _getKMSStaticPubKey() {
    this.logger.info(`kms: retrieving KMS static public key`);
    return this._getKMSDetails()
      .then(({rsaPublicKey}) => rsaPublicKey);
  },

  /**
   * @private
   * @returns {Promise<Object>}
   */
  _prepareContext() {
    this.logger.info(`kms: creating context`);
    const context = new Context();

    return Promise.all([
      this._getKMSStaticPubKey(),
      this._getAuthorization()
    ])
      .then(([kmsStaticPubKey, authorization]) => {
        context.clientInfo = {
          clientId: this.spark.device.url,
          credential: {
            userId: this.spark.device.userId,
            bearer: authorization
          }
        };

        context.serverInfo = {
          key: kmsStaticPubKey
        };

        this.logger.info(`kms: creating local ephemeral key`);
        return context.createECDHKey();
      })
      .then((localECDHKey) => {
        context.ephemeralKey = localECDHKey;
        partialContexts.set(this, context);
        return Promise.all([localECDHKey.asKey(), this._getKMSCluster()]);
      })
      .then(([localECDHKey, cluster]) => {
        this.logger.info(`kms: submitting ephemeral key request`);
        return this.request({
          uri: `${cluster}/ecdhe`,
          method: `create`,
          jwk: localECDHKey.toJSON()
        });
      })
      .then((res) => {
        this.logger.info(`kms: deriving final ephemeral key`);
        return context.deriveEphemeralKey(res.key);
      })
      .then((key) => {
        context.ephemeralKey = key;
        partialContexts.delete(this);
        this.logger.info(`kms: derived final ephemeral key`);
        return context;
      })
      .catch((reason) => {
        this.logger.error(`kms: failed to negotiate ephemeral key`, reason);
        return Promise.reject(reason);
      });
  }
});

export default KMS;


text:
import type {TeamGroup} from '.';
import {Client} from '../client';

export class TeamGroups extends Client {
  public async findAll(
    teamGroupsRequest?: TeamGroupsRequest
  ): Promise<TeamGroup[]> {
    return this.post('/teams/latLngGrp', teamGroupsRequest?.data());
  }
}

export class TeamGroupsRequestBuilder {
  #programIds?: number[];
  #seasonId?: number;
  #country?: string;
  #region?: string;

  public programIds(...value: number[]): TeamGroupsRequestBuilder {
    this.#programIds = value;
    return this;
  }

  public seasonId(value: number): TeamGroupsRequestBuilder {
    this.#seasonId = value;
    return this;
  }

  public location(country: string, region?: string): TeamGroupsRequestBuilder {
    this.#country = country;
    this.#region = region;
    return this;
  }

  public build(): TeamGroupsRequest {
    return new TeamGroupsRequestBuilder.TeamGroupsRequest(this);
  }

  static TeamGroupsRequest = class TeamGroupsRequest {
    public readonly programIds?: number[];
    public readonly seasonId?: number;
    public readonly country?: string;
    public readonly region?: string;

    constructor(builder: TeamGroupsRequestBuilder) {
      this.programIds = builder.#programIds;
      this.seasonId = builder.#seasonId;
      this.country = builder.#country;
      this.region = builder.#region;
    }

    public data(): TeamGroupsData {
      return {
        programs: this.programIds,
        season_id: this.seasonId,
        country: this.country,
        region: this.region,
        when: this.seasonId !== undefined ? When.PAST : undefined,
      };
    }
  };
}

export type TeamGroupsRequest =
  typeof TeamGroupsRequestBuilder.TeamGroupsRequest.prototype;

interface TeamGroupsData {
  programs?: number[];
  season_id?: number;
  country?: string;
  region?: string;
  when?: When;
}

enum When {
  FUTURE = 'future',
  PAST = 'past',
}


text:
from django.apps import AppConfig

class CandidatesConfig(AppConfig):
    name = 'candidates'


text:
package com.op.wunderbutton;

import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.mixpanel.android.mpmetrics.MixpanelAPI;
import com.op.wunderbutton.model.TokenRequest;
import com.op.wunderbutton.oauth2.WebApiHelper;
import com.op.wunderbutton.oauth2.tasks.LoadWebUrlAsyncTask;
import com.op.wunderbutton.oauth2.tasks.OnApiRequestListener;
import com.op.wunderbutton.requests.GetCodeRequest;
import com.op.wunderbutton.requests.GetListsRequest;
import com.op.wunderbutton.tools.Constants;
import com.op.wunderbutton.tools.MixpanelUtil;

import org.apache.http.protocol.HTTP;
import org.json.JSONObject;

import lombok.extern.java.Log;
import com.optimizely.Optimizely;

@Log
public class MainActivity extends ActionBarActivity {

    private MixpanelAPI mMixpanel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        log.info("init");

        Optimizely.startOptimizely("AAM7hIkAk9WQeP3RBPSmCMsQRRLzRKzb~2872823291", getApplication());

        mMixpanel = MixpanelAPI.getInstance(getApplicationContext(), Constants.MIXPANEL_TOKEN);
        setMixPIdentify();
        MixpanelUtil.sendMixPOpened(mMixpanel, "phoneModel", android.os.Build.MODEL);

        super.onCreate(savedInstanceState);

        if (redirectOnSecondLaunch()) {
            return;
        }

        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }

    }

    private void setMixPIdentify() {
        try {
            Cursor c = getApplication().getContentResolver().query(ContactsContract.Profile.CONTENT_URI, null, null, null, null);
            c.moveToFirst();
            if (mMixpanel != null) {
                mMixpanel.identify(c.getString(c.getColumnIndex("display_name")));
            }
            c.close();
        } catch (Exception ex){
            log.info(ex.getMessage());
        }
    }

    @Override
    protected void onDestroy() {
        mMixpanel.flush();
        super.onDestroy();
    }

    private boolean redirectOnSecondLaunch() {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        String preferenceValue = preferences.getString(Constants.LIST_ID, "0");
        if (Integer.parseInt(preferenceValue) != 0) {
            Intent i = new Intent(getApplicationContext(), AddProductActivity.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            getApplicationContext().startActivity(i);
            return true;
        }
        ;
        return false;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_change_list) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBackPressed() {
        MixpanelUtil.sendMixPOpened(mMixpanel, "back pressed", "");
        WebView webView = (WebView) this.findViewById(R.id.webpage);
        if (webView.canGoBack()) {
            webView.goBack();
        }
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        private WebView webView;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            webView = (WebView) rootView.findViewById(R.id.webpage);
            webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
            //webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setDefaultTextEncodingName(HTTP.UTF_8);
            webView.getSettings().setLoadWithOverviewMode(true);
            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setBuiltInZoomControls(true);
            webView.requestFocus(View.FOCUS_DOWN);
            webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
            GetCodeRequest request = new GetCodeRequest(getActivity());

               /* WebViewClient must be set BEFORE calling loadUrl! */
            webView.setWebViewClient(new WebViewClient() {

                @Override
                public void onPageFinished(WebView view, String url) {
//                    view.findViewById(R.id.imageLoading1).setVisibility(View.GONE);
                    //view.findViewById(R.id.webpage).setVisibility(View.VISIBLE);

                    OnApiRequestListener requestListener = new OnApiRequestListener() {

                        @Override
                        public void onStartRequest() {
                        }

                        @Override
                        public void onFinishRequest(String response) {

                            Intent i = new Intent(getActivity().getApplicationContext(), SelectListActivity.class);
                            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            i.putExtra(Constants.LISTS_JSON, response);
                            getActivity().getApplicationContext().startActivity(i);
                        }

                        @Override
                        public void onException(Exception ex) {
                        }
                    };

                    if (url.contains(Constants.LOCALHOST)) {
                        try {
                            if (url.contains(Constants.CODE_EQ)) {
                                WebView webView = (WebView) view.findViewById(R.id.webpage);
                                webView.destroy();

                                String code = url.substring(url.indexOf(Constants.CODE_EQ) + 5);
                                WebApiHelper.register(view.getContext());
                                WebApiHelper.getInstance().saveToSharedPreferences(view.getContext(), R.string.wunderlist_refresh_token, code);

                                TokenRequest tokenRequest = new TokenRequest();
                                tokenRequest.setClient_id(view.getContext().getResources().getString(R.string.wunderlist_client_id));
                                tokenRequest.setCode(code);
                                tokenRequest.setClient_secret(view.getContext().getResources().getString(R.string.wunderlist_client_secret));

                                WebApiHelper.getInstance().refreshAccessToken(new JSONObject(Constants.gson.toJson(tokenRequest)));

                                LoadWebUrlAsyncTask task = new LoadWebUrlAsyncTask();
                                GetListsRequest request = new GetListsRequest(view.getContext());
                                task.execute(request);
                                task.setOnWebRequestCallback(requestListener);

                            } else if (url.indexOf("error=") != -1) {
                                log.info("error in url:" + url);
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }

                }

            });

            webView.loadUrl(request.getEncodedUrl());//
            return rootView;
        }
    }
}


text:
.editor_focused:not(.editor_readonly):not(.editor_disabled) .input,
.editor_focused:not(.editor_readonly):not(.editor_disabled) .textarea,
.editor_focused:not(.editor_readonly):not(.editor_disabled) .editor_uri,
.editor_bubble:not(.editor_readonly):not(.editor_disabled) .bubbles.editor_focused,
.editor_checkbox.editor_focused:not(.editor_readonly):not(.editor_disabled) .checkbox,
.editor_date-time.editor_focused:not(.editor_readonly):not(.editor_disabled) {
    border-color: var(--input-active-border-color);
}

.editor_bubble:not(.editor_readonly):not(.editor_disabled) .bubbles.open.dropdown__wrp_down.editor_focused {
    border-bottom-color: transparent;
    box-shadow: 0 1px 3px var(--black-12), 0 -1px 2px var(--black-24);
    border-radius: 4px 4px 0 0;
}

.editor_bubble:not(.editor_readonly):not(.editor_disabled) .bubbles.open.dropdown__wrp_up.editor_focused {
    border-top-color: transparent;
    box-shadow: 0 1px 3px var(--black-12), 0 -1px 2px var(--black-24);
    border-radius: 0 0 4px 4px;
}

.focused input,
.focused textarea {
    border-color: var(--input-active-border-color);
}

.editor_disabled {
    cursor: auto;
}

.editor_disabled.editor_bubble--single .bubbles,
.editor_readonly.editor_bubble--single .bubbles {
    filter: alpha(opacity=60);
    cursor: auto;
}

.editor_disabled.editor_bubble:not(.editor_bubble--single) .bubbles__caret,
.editor_readonly.editor_bubble:not(.editor_bubble--single) .bubbles__caret {
    opacity: 0.7;
}

.editor_checked:not(.editor_readonly):not(.editor_disabled) .checkbox,
.editor_checked.checkbox {
    line-height: normal;
    font-size: 11px;
    color: var(--checkbox-checked-color);
    background: linear-gradient(var(--theme-colors__primary_fade), var(--theme-colors__primary));
    border-color: var(--checkbox-border-color);
}

.icon-false {
    color: var(--red-dark);
    font-size: 1.2em;
}

.icon-true,
.icon-false {
    margin: 0 auto;
    display: flex;
    width: 10px;
}

.tr-search__input {
    height: var(--input-height);
    background-size: 14px 14px;
    text-overflow: ellipsis;
}

.tr-search__clear .icon-remove {
    vertical-align: middle;
}

.radiobutton {
    color: var(--theme-colors__primary);
    border-color: var(--theme-colors__primary);
    background-color: var(--theme-colors__main);
}

.checkbox:hover,
.radiobutton:hover {
    box-shadow: 0 0 3px var(--theme-colors__primary_fadest);
}

.checkbox .svg-icons {
    width: 0.9em;
    height: 0.9em;
}

/* Buttons */
.btn.btn-icon svg {
    fill: currentColor;
    width: 1em;
    height: 1em;
    top: 0.125em;
    position: relative;
}

.btn.btn_arrow {
    background-position: 50%;
    background-repeat: no-repeat;
}

.btn.btn-small {
    padding: 2px 15px;
    font-size: 13px;
    font-weight: 600;
}

.btn.btn-large {
    padding: 4px 15px;
    font-size: 20px;
}

/* dropdown-list */

.subtext-list.selected .datalist-container-text,
.subtext-list.selected .datalist-container-subtext,
.subtext-list.selected .datalist-icon,
.dd-list__i.selected,
.selected .dd-list__i,
.dd-list__i:hover,
.time-dropdown__i:hover,
.popout-menu__i:hover .popout-menu__txt,
.popout-menu__i_selected .popout-menu__txt {
    color: var(--theme-colors__primary);
}

.subtext-list.selected .datalist-container-text,
.subtext-list.selected .datalist-container-subtext,
.dd-list__i.selected,
.selected .dd-list__i {
    font-weight: 600;
}

.bubbles .spinner {
    right: 25px;
}

.bubbles__form {
    padding: 2px 0;
}

.open.dropdown__wrp_down .bubbles {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.open.dropdown__wrp_up .bubbles {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.dropdown__wrp {
    border-radius: var(--border-radius);

    /* transform: translateY(-50px); */
    opacity: 0;
    transition: transform 0.1s linear, opacity 0.1s linear;
}

.datalist-panel.dropdown__wrp_down {
    border-radius: 0 0 var(--border-radius) var(--border-radius);
}

.datalist-panel.dropdown__wrp_up {
    border-radius: var(--border-radius) var(--border-radius) 0 0;
}

/* icons */

svg.svg-icons.svg-icons_remove {
    fill: var(--red-dark);
}

svg.svg-grid-icons.svg-icons_flag-yes {
    fill: var(--main-color);
}

svg.svg-grid-icons.svg-icons_flag-none {
    fill: var(--theme-colors__error);
}

/* Tabs */

.layout__tab-layout_move-button {
    font-size: 1em;
    padding: 0 10px;
}

.grid-toolbar-region {
    padding-right: 10px;
}

.grid-toolbar__search {
    order: 2;
}

/* ------------------ Form Label ------------------ */
.form-label__info-button,
.form-label__error-button {
    transition: color 0.3s;
}

.form-label__info-button {
    color: var(--theme-colors__main_fade);
}

.form-label__error-button {
    color: var(--theme-colors__error);
}

.form-label__info-button:hover {
    color: var(--theme-colors__text);
}

.form-label__error-button:hover {
    color: var(--theme-colors__error);
}

.form-label:not(.form-label_empty) + .editor_document,
.form-label:not(.form-label_empty) + .editor_checkbox {
    padding-left: var(--form-input-padding);
}

.error .form-label {
    color: var(--theme-colors__error);
}

.warning .form-label {
    color: var(--theme-colors__warning);
}

.required .form-label__txt,
.form-label_required .form-label__txt {
    padding-right: 10px;
}

.required .form-label__txt::after,
.form-label_required .form-label__txt::after {
    content: '*';
    color: var(--theme-colors__error);
    position: relative;
    right: 0;
}

.cell.required::before {
    content: '*';
    color: var(--theme-colors__error);
    position: absolute;
    top: 50%;
    left: 2px;
    transform: translateY(-50%);
}

.cell.error.required::before,
.cell.warning.required::before {
    display: none;
}

.layout__horizontal-layout > div:not(:last-child),
.layout__horizontal-layout-list-item:not(:last-child) {
    padding-right: 10px;
}

.layout__vertical-layout > *:not(:last-child),
.layout__vertical-layout-item:not(:last-child) {
    margin-bottom: 20px;
}

.group-toggle {
    order: 2;
}

.layout__configuration-panel-container > div {
    margin-top: 5px;
}

.configuration-panel .layout__vertical-layout-item,
.configuration-panel .layout__vertical-layout > div,
.dataset-configuration-panel .layout__vertical-layout-item, /*remove*/
.dataset-configuration-panel .layout__vertical-layout > div {/* remove */
    margin-bottom: 0;
}

.layout-group .layout-group__content > .layout-group .group-title {
    font-size: 15px;
    padding-left: 0;
}

.layout-group .layout-group__content > .layout-group .layout-group__content {
    background-color: var(--theme-colors__main);
}

.layout__popup-view-header-text {
    font-family: var(--headers-font-family);
    font-style: var(--headers-font-style);
    font-weight: var(--headers-font-weight);
    flex: 1 1 auto;
    padding-right: 10px;
}

.layout__popup-view-header__btn {
    opacity: 0.5;
}

.layout__popup-view-header__btn:hover {
    opacity: 1;
}

.layout__popup-view_mobile .layout__popup-view-header__btn,
.layout__popup-view_mobile-system-type .layout__popup-view-header__btn {
    display: none;
}

.layout__popup-view_mobile .layout__popup-view-header__btn_equate {
    display: inline-block;
}

.cell .date-view,
.cell .time-view,
.editable-grid-field {
    height: 100%;
}

.cell > .editor {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    padding: 0 15px;
}

.cell > .collapsible-btn + .editor {
    display: inline-flex;
    width: auto;
    padding: 0;
    position: static;
}

.cell > .context_select {
    position: static;
    padding: 4px 20px 4px 10px;
}

.cell.editor_date-time > .editor_date-time_date {
    width: auto;
    right: 50%;
    padding-right: 0;
}

.cell.editor_date-time > .editor_duration {
    width: auto;
    left: 50%;
    padding-left: 0;
}

.cell.editor .textarea {
    height: 100%;
    border: none;
    background: transparent;
}

.cell.editor_document {
    display: table-cell;
    padding: 0;
}

.cell.editor_document > form {
    max-height: 35px;
    overflow: hidden;
    display: none;
}

.cell > .editor.editor_document > .documents {
    margin-top: 0;
    margin-bottom: 0;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
}

.cell .drop-zone__text,
.cell .field-documents__more {
    display: none;
}

.cell .editor__drop-zone {
    height: auto;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    top: 0;
    background-color: transparent;
    cursor: pointer;
    font-family: 'Font Awesome 5 Free', 'Font Awesome 5 Pro'; /* stylelint-disable-line */
    font-weight: 900;
}

.cell .editor_empty .editor__drop-zone::before {
    content: "\F0C6";
    color: grey;
    position: absolute;
}

.layout__popup-view-content > .layout__form-view {
    display: flex;
}

.layout__popup-view-content .systemMessageBody {
    width: 100%;
    padding: 15px;
}

/* Document upload */
.editor_document {
    flex-direction: column;
    align-items: flex-start;
}

.btn.field-documents__more {
    width: auto;
    text-align: center;
    background-color: var(--theme-colors__main_fadest);
    color: var(--theme-colors__text);
}

.btn.field-documents__more:hover {
    background-color: var(--theme-colors__main_strong);
}

.show-more-counter:not(:empty) {
    border-radius: 10px;
    background-color: var(--theme-colors__main_fade);
    display: inline-flex;
    justify-content: center;
    align-items: center;
    font-size: 12px;
    padding: 2px 6px;
}

/* Date Time */

.editor_date-time.LongDate .editor_date-time_date {
    flex-basis: 250px;
}

.editor_date-time.ShortDate .editor_date-time_date,
.editor_date-time.DateIso .editor_date-time_date {
    flex-basis: 95px;
}

.editor_date-time.CondensedDate .editor_date-time_date {
    flex-basis: 130px;
}

.editor_date-time.YearMonth .editor_date-time_date {
    flex-basis: 140px;
}

.editor_date-time.ShortTime .editor_date-time_time .input {
    max-width: 60px;
}

.editor_date-time.LongTime .editor_date-time_time .input {
    max-width: 90px;
}

/* /Date Time/ */

.dev-code-editor-toolbar {
    background: var(--theme-colors__main);
    border: solid 1px var(--theme-colors__main_strongest);
    border-bottom: none;
}

.left-menu-view-switcher__container .toolbar-btn {
    font-size: 13px;
    padding: 8px 15px;
}

.toolbar-btn__text {
    vertical-align: inherit;
}


text:
require 'set'
require 'diplomat'
require 'flipper'

module Flipper
  module Adapters
    class Consul
      include Flipper::Adapter

      # Private: The key that stores the set of known features.
      FeaturesKey = :flipper_features

      # Public: The name of the adapter.
      attr_reader :name

      attr_reader :namespace

      def initialize(client, namespace=nil)
        @client = client
        @name = :consul
        if !namespace.nil?
          namespace = namespace.strip
          if namespace == ''
            namespace = nil
          elsif namespace.start_with? '/'
            namespace[0] = ''
          end
        end
        @namespace = namespace
      end

      # Public: The set of known features.
      def features
        read_multiple build_path "#{FeaturesKey}/features"
      end

      # Public: Adds a feature to the set of known features.
      def add(feature)
        @client.put build_path("#{FeaturesKey}/features/#{feature.key}"), '1'
        true
      end

      # Public: Removes a feature from the set of known features.
      def remove(feature)
        @client.delete build_path "#{FeaturesKey}/features/#{feature.key}"
        clear feature
        true
      end

      # Public: Clears the gate values for a feature.
      def clear(feature)
        @client.delete build_path(feature.key), recurse: true
        true
      end

      # Public: Gets the values for all gates for a given feature.
      #
      # Returns a Hash of Flipper::Gate#key => value.
      def get(feature)
        result = {}
        values = get_feature_values(feature)

        feature.gates.each do |gate|
          result[gate.key] = case gate.data_type
          when :boolean, :integer
            values[gate.key.to_s]
          when :set
            gate_values_as_set(values, gate)
          else
            unsupported_data_type gate.data_type
          end
        end

        result
      end

      # Public: Enables a gate for a given thing.
      #
      # feature - The Flipper::Feature for the gate.
      # gate - The Flipper::Gate to disable.
      # thing - The Flipper::Type being disabled for the gate.
      #
      # Returns true.
      def enable(feature, gate, thing)
        case gate.data_type
        when :boolean, :integer
          @client.put key(feature, gate), thing.value.to_s
        when :set
          @client.put set_member_key(feature, gate, thing), '1'
        else
          unsupported_data_type gate.data_type
        end

        true
      end

      # Public: Disables a gate for a given thing.
      #
      # feature - The Flipper::Feature for the gate.
      # gate - The Flipper::Gate to disable.
      # thing - The Flipper::Type being disabled for the gate.
      #
      # Returns true.
      def disable(feature, gate, thing)
        case gate.data_type
        when :boolean
          @client.delete build_path(feature), recurse: true
        when :integer
          @client.put key(feature, gate), thing.value.to_s
        when :set
          @client.delete set_member_key(feature, gate, thing)
        else
          unsupported_data_type gate.data_type
        end

        true
      end

      private

      # Private
      def key(feature, gate)
        build_path "#{feature.key}/#{gate.key}"
      end

      def set_member_key(feature, gate, thing)
        build_path "#{feature.key}/#{gate.key}/#{thing.value.to_s}"
      end

      def build_path(key)
        if namespace.nil?
          key
        else
          "#{namespace}/#{key}"
        end
      end

      def read_multiple(key_path)
        begin
          @client.get key_path, recurse: true
          values = @client.raw
          values = values.map do |item|
            item['Key'].sub!("#{key_path}/", '')
          end
          value = values.to_set
        rescue Diplomat::KeyNotFound
          value = {}.to_set
        end
        value
      end

      def get_feature_values(feature)
        begin
          key_path = build_path(feature.key)
          @client.get key_path, recurse: true
          values = @client.raw
          result = {}
          values.each do |item|
            result[item['Key'].sub!("#{key_path}/", '')] = item['Value']
          end
          result
        rescue Diplomat::KeyNotFound
          {}
        end
      end

      def gate_values_as_set(values, gate)
        regex = /^#{Regexp.escape(gate.key.to_s)}\//
        keys_for_gate = values.keys.grep regex
        values = keys_for_gate.map { |key| key.split('/', 2).last }
        values.to_set
      end

    end
  end
end


text:
namespace boost{ namespace gil {

/// pixel_bit_size metafunctions
/// \brief Accumulates the all channel size.
///
/// \code
/// using image_t = bit_aligned_image5_type<16, 16, 16, 8, 8, devicen_layout_t<5>>::type;
/// const int size = pixel_bit_size<image_t::view_t::reference>::value;
/// \endcode
template< typename PixelRef>
struct pixel_bit_size : std::integral_constant<int, 0> {};

template <typename B, typename C, typename L, bool M>
struct pixel_bit_size<bit_aligned_pixel_reference<B, C, L, M>>
    : mp11::mp_fold
    <
        C,
        std::integral_constant<int, 0>,
        mp11::mp_plus
    >
{};

template <typename B, typename C, typename L, bool M>
struct pixel_bit_size<bit_aligned_pixel_reference<B, C, L, M> const>
    : mp11::mp_fold
    <
        C,
        std::integral_constant<int, 0>,
        mp11::mp_plus
    >
{};

template <typename B, typename C, typename L>
struct pixel_bit_size<packed_pixel<B, C, L>>
    : mp11::mp_fold
    <
        C,
        std::integral_constant<int, 0>,
        mp11::mp_plus
    >

{};

template <typename B, typename C, typename L>
struct pixel_bit_size<const packed_pixel<B,C,L> >
    : mp11::mp_fold
    <
        C,
        std::integral_constant<int, 0>,
        mp11::mp_plus
    >
{};

}} // namespace boost::gil

#endif


text:
import io

class CancelledError(Exception):
    def __init__(self, msg):
        self.msg = msg
        Exception.__init__(self, msg)

    def __str__(self):
        return self.msg

    __repr__ = __str__

class BufferReader(io.BytesIO):
    def __init__(self, buf=b"", desc=None):
        self._len = len(buf)
        io.BytesIO.__init__(self, buf)
        self._progress = 0
        self._callback = progress(len(buf), desc=desc)

    def __len__(self):
        return self._len

    def read(self, n=-1):
        chunk = io.BytesIO.read(self, n)
        self._progress += len(chunk)
        if self._callback:
            try:
                self._callback(self._progress)
            except Exception as e:  # catches exception from the callback
                raise CancelledError("The upload was cancelled: {}".format(e))
        return chunk

def progress(total, desc):
    import tqdm  # type: ignore

    meter = tqdm.tqdm(total=total, unit_scale=True, desc=desc)

    def incr(progress):
        meter.n = progress
        if progress == total:
            meter.close()
        else:
            meter.refresh()

    return incr

def MB(i):
    return int(i // 1024**2)


text:
package com.facebook.buck.apple.toolchain.impl;

import com.facebook.buck.apple.AppleConfig;
import com.facebook.buck.apple.toolchain.AppleDeveloperDirectoryProvider;
import com.facebook.buck.apple.toolchain.AppleToolchain;
import com.facebook.buck.apple.toolchain.AppleToolchainProvider;
import com.facebook.buck.core.model.BuildTarget;
import com.facebook.buck.core.model.TargetConfiguration;
import com.facebook.buck.core.toolchain.ToolchainCreationContext;
import com.facebook.buck.core.toolchain.ToolchainFactory;
import com.facebook.buck.core.toolchain.ToolchainProvider;
import com.facebook.buck.core.util.log.Logger;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;

public class AppleToolchainProviderFactory implements ToolchainFactory<AppleToolchainProvider> {
  private static final Logger LOG = Logger.get(AppleToolchainProviderFactory.class);

  @Override
  public Optional<AppleToolchainProvider> createToolchain(
      ToolchainProvider toolchainProvider,
      ToolchainCreationContext context,
      TargetConfiguration toolchainTargetConfiguration) {
    AppleConfig appleConfig = context.getBuckConfig().getView(AppleConfig.class);
    Optional<BuildTarget> toolchainSetTarget =
        appleConfig.getAppleToolchainSetTarget(toolchainTargetConfiguration);
    if (toolchainSetTarget.isPresent()) {
      return Optional.empty();
    }

    Optional<Path> appleDeveloperDir =
        toolchainProvider
            .getByNameIfPresent(
                AppleDeveloperDirectoryProvider.DEFAULT_NAME,
                toolchainTargetConfiguration,
                AppleDeveloperDirectoryProvider.class)
            .map(AppleDeveloperDirectoryProvider::getAppleDeveloperDirectory);

    Optional<AppleToolchainProvider> appleToolchainProvider;
    try {
      ImmutableMap<String, AppleToolchain> appleToolchains =
          AppleToolchainDiscovery.discoverAppleToolchains(
              appleDeveloperDir, appleConfig.getExtraToolchainPaths());
      appleToolchainProvider = Optional.of(AppleToolchainProvider.of(appleToolchains));
    } catch (IOException e) {
      LOG.error(
          e,
          "Couldn't find the Apple build toolchain.\nPlease check that the SDK is installed properly.");
      appleToolchainProvider = Optional.empty();
    }
    return appleToolchainProvider;
  }
}


text:
=begin
#<
Configures 0 or more SQL Server instances using the sqlshell/sql_server/instances attribute.
#>
=end

include_recipe 'sqlshell::default'

def sq_priority(value)
  value.is_a?(Hash) && value['priority'] ? value['priority'] : 100
end

def sq_sort(hash)
  Hash[hash.sort_by {|key, value| "#{"%04d" % sq_priority(value)}#{key}"}]
end

sq_sort(node['sqlshell']['sql_server']['instances']).each_pair do |instance_key, definition|
  RealityForge::SqlServer.set_current_instance(node, instance_key)
  if definition['recipes'] && definition['recipes']['before']
    sq_sort(definition['recipes']['before']).each_pair do |recipe, config|
      Chef::Log.info "Including instance 'before' recipe '#{recipe}' Priority: #{sq_priority(config)}"
      include_recipe recipe
    end
  end
  RealityForge::SqlServer.set_current_instance(node, nil)
end

node['sqlshell']['sql_server']['instances'].each_pair do |instance_key, value|
  RealityForge::SqlServer.set_current_instance(node, instance_key)

  server_prefix = "sqlshell.sql_server.instances.#{instance_key}"
  jdbc_url = RealityForge::AttributeTools.ensure_attribute(value, 'jdbc.url', String, server_prefix)
  jdbc_driver = RealityForge::AttributeTools.ensure_attribute(value, 'jdbc.driver', String, server_prefix)
  extra_classpath = RealityForge::AttributeTools.ensure_attribute(value, 'jdbc.extra_classpath', Array, server_prefix)
  jdbc_properties = RealityForge::AttributeTools.ensure_attribute(value, 'jdbc.properties', Hash, server_prefix)

  delete_unmanaged_permissions = value['delete_unmanaged_permissions'].is_a?(TrueClass)
  delete_unmanaged_database_roles = value['delete_unmanaged_database_roles'].is_a?(TrueClass)
  delete_unmanaged_users = value['delete_unmanaged_users'].is_a?(TrueClass)
  delete_unmanaged_server_roles = value['delete_unmanaged_server_roles'].is_a?(TrueClass)
  delete_unmanaged_logins = value['delete_unmanaged_logins'].is_a?(TrueClass)
  delete_unmanaged_databases = value['delete_unmanaged_databases'].is_a?(TrueClass)

  if value['databases']
    sq_sort(value['databases']).each_pair do |database_name, database_config|
      is_database_managed = database_config['managed'].nil? ? false : database_config['managed']
      if is_database_managed && !['master', 'msdb', 'model', 'tempdb'].include?(database_name)
        sqlshell_ms_database "#{instance_key}-#{database_name}" do
          jdbc_url jdbc_url
          jdbc_driver jdbc_driver
          extra_classpath extra_classpath
          jdbc_properties jdbc_properties

          database database_name

          recovery_model database_config['recovery_model'] if database_config['recovery_model']
          collation database_config['collation'] if database_config['collation']
        end
      end
    end
  end

  if value['logins']
    sq_sort(value['logins']).each_pair do |login, login_config|
      sqlshell_ms_login "#{instance_key}-#{login}" do
        jdbc_url jdbc_url
        jdbc_driver jdbc_driver
        extra_classpath extra_classpath
        jdbc_properties jdbc_properties

        login login
        default_database login_config['default_database'] if login_config['default_database']
        default_language login_config['default_language'] if login_config['default_language']
        password login_config['password'] if login_config['password']
      end

      if login_config['server_roles']
        login_config['server_roles'].each_pair do |role, config|
          sqlshell_ms_server_role "#{instance_key}-#{login}-#{role}" do
            jdbc_url jdbc_url
            jdbc_driver jdbc_driver
            extra_classpath extra_classpath
            jdbc_properties jdbc_properties
            login login
            role role
          end
        end
      end
    end
  end

  if value['databases']
    sq_sort(value['databases']).each_pair do |database_name, database_config|
      database_prefix = "#{server_prefix}.databases.#{database_name}"

      is_database_managed = database_config['managed'].nil? ? false : database_config['managed']

      if database_config['users']
        database_config['users'].each_pair do |user, user_config|
          user_prefix = "#{database_prefix}.users.#{user}"

          sqlshell_ms_user "#{instance_key}-#{database_name}-#{user}" do
            jdbc_url jdbc_url
            jdbc_driver jdbc_driver
            extra_classpath extra_classpath
            jdbc_properties jdbc_properties
            login RealityForge::AttributeTools.ensure_attribute(user_config, 'login', String, user_prefix)
            database database_name
            user user
          end

          if user_config['database_roles']
            user_config['database_roles'].each_pair do |database_role, role_config|
              sqlshell_ms_database_role "#{instance_key}-ADD '#{user}' to role '#{database_role}' in '#{database_name}'" do
                jdbc_url jdbc_url
                jdbc_driver jdbc_driver
                extra_classpath extra_classpath
                jdbc_properties jdbc_properties
                user user
                database database_name
                role database_role
              end
            end
          end

          if user_config['permissions']
            sq_sort(user_config['permissions']).each_pair do |permission_key, permission_config|
              permission_prefix = "#{user_prefix}.permissions.#{permission_key}"
              permission = RealityForge::AttributeTools.ensure_attribute(permission_config, 'permission', String, permission_prefix)
              securable_type = RealityForge::AttributeTools.get_attribute(permission_config, 'securable_type', String, permission_prefix)
              securable = RealityForge::AttributeTools.get_attribute(permission_config, 'securable', String, permission_prefix)
              permission_action = RealityForge::AttributeTools.get_attribute(permission_config, 'permission_action', String, permission_prefix)

              sqlshell_ms_permission "#{instance_key}-#{database_name}-#{permission_action} #{permission} TO #{user} ON #{securable_type}::#{securable || database_name}" do
                jdbc_url jdbc_url
                jdbc_driver jdbc_driver
                extra_classpath extra_classpath
                jdbc_properties jdbc_properties
                user user
                database database_name
                securable_type securable_type
                securable securable
                permission permission
                action permission_action.downcase.to_sym if permission_action
              end
            end
          end
        end
      end

      sqlshell_exec "#{instance_key}-Remove historic permissions in #{database_name}" do
        jdbc_url jdbc_url
        jdbc_driver jdbc_driver
        extra_classpath extra_classpath
        jdbc_properties jdbc_properties
        command <<-SQL
          USE [#{database_name}];
          SELECT
            U.name AS [user],
            P.class_desc AS securable_type,
            P.permission_name AS permission,
            P.state_desc as permission_action,
            COALESCE(O.name,T.name) AS securable_name,
            S.name AS securable_schema
          FROM
            sys.database_permissions P
          JOIN sys.database_principals U ON P.grantee_principal_id = U.principal_id AND U.type_desc IN ('SQL_USER','WINDOWS_USER','WINDOWS_GROUP')
          JOIN sys.server_principals SP ON SP.sid = U.sid AND SP.is_disabled = 0 AND SP.name NOT LIKE 'NT AUTHORITY\\%' AND SP.name NOT LIKE 'NT SERVICE\\%'
          LEFT JOIN sys.all_objects O ON O.object_id = P.major_id
          LEFT JOIN sys.types T ON T.user_type_id = P.major_id
          LEFT JOIN sys.schemas S ON S.schema_id = COALESCE(O.schema_id,T.schema_id)
          WHERE
            P.class_desc IN ('DATABASE','TYPE','OBJECT_OR_COLUMN') AND
            U.name != 'dbo'
        SQL
        block do
          permissions = []
          database_config['users'].each_pair do |user, user_config|
            if user_config['permissions']
              user_config['permissions'].values.each do |permission_config|
                permission_action = (permission_config['permission_action'] || 'grant').upcase
                securable_type = (permission_config['securable_type'] == 'OBJECT' ? 'OBJECT_OR_COLUMN' : permission_config['securable_type']) || 'DATABASE'
                permission = permission_config['permission']
                securable = permission_config['securable'] ? permission_config['securable'].gsub('[','').gsub(']','') : database_name
                permissions << "#{user}-#{permission}-#{securable_type}-#{securable || database_name}-#{permission_action}".downcase
              end
            end
          end

          @sql_results.each do |row|
            user = row['user']
            permission = row['permission']
            securable_type = row['securable_type']
            securable = row['securable_schema'] ? "#{row['securable_schema']}.#{row['securable_name']}" : row['securable_name']
            permission_action = row['permission_action']

            permission_description = "#{user}-#{permission}-#{securable_type}-#{securable || database_name}-#{permission_action}".downcase

            if !permissions.include?(permission_description)
              if is_database_managed || delete_unmanaged_permissions
                Chef::Log.info "Removing historic permission #{permission_action} #{permission} TO #{user} ON #{securable_type}::#{securable || database_name}"

                sqlshell_ms_permission "#{instance_key}-Revoking ... #{permission_action} #{permission} TO #{user} ON #{securable_type}::#{securable || database_name}" do
                  jdbc_url jdbc_url
                  jdbc_driver jdbc_driver
                  extra_classpath extra_classpath
                  jdbc_properties jdbc_properties
                  user user
                  database database_name
                  securable_type(securable_type == 'OBJECT_OR_COLUMN' ? 'OBJECT' : securable_type)
                  securable securable
                  permission permission
                  action :revoke
                end
              else
                Chef::Log.error "Unmanaged permission '#{permission_action} #{permission} TO #{user} ON #{securable_type}::#{securable || database_name}' found"
              end
            end
          end
        end
      end

      sqlshell_exec "#{instance_key}-Remove historic database roles in #{database_name}" do
        jdbc_url jdbc_url
        jdbc_driver jdbc_driver
        extra_classpath extra_classpath
        jdbc_properties jdbc_properties
        command <<-SQL
          USE [#{database_name}];
          SELECT
            U.name AS [user],
            R.name AS [role]
           FROM
            sys.database_principals R
          JOIN sys.database_role_members RM ON RM.role_principal_id = R.principal_id
          JOIN sys.database_principals U ON RM.member_principal_id = U.principal_id
          WHERE
            R.is_fixed_role = 1 AND
            U.name != 'dbo'
        SQL
        block do
          role_map = {}
          database_config['users'].each_pair do |user, user_config|
            role_map[user] = user_config['database_roles'] ? user_config['database_roles'].keys : []
          end

          @sql_results.each do |row|
            user = row['user']
            database_role = row['role']

            if !role_map[user] || !role_map[user].include?(database_role)
              if is_database_managed || delete_unmanaged_database_roles
                Chef::Log.info "Removing historic database role '#{database_role}' from user '#{user}' in database ''#{database_name}''"

                sqlshell_ms_database_role "#{instance_key}-Remove '#{user}' from role '#{database_role}' in '#{database_name}'" do
                  jdbc_url jdbc_url
                  jdbc_driver jdbc_driver
                  extra_classpath extra_classpath
                  jdbc_properties jdbc_properties
                  user user
                  database database_name
                  role database_role
                  action :remove
                end
              else
                Chef::Log.error "Unmanaged database role '#{database_role} for #{user} in #{database_name}' found"
              end
            end
          end
        end
      end

      sqlshell_exec "#{instance_key}-Remove historic users in #{database_name}" do
        jdbc_url jdbc_url
        jdbc_driver jdbc_driver
        extra_classpath extra_classpath
        jdbc_properties jdbc_properties
        command <<-SQL
          USE [#{database_name}];
          SELECT
            U.name AS [user]
          FROM
            sys.database_principals U
          JOIN sys.server_principals SP ON SP.sid = U.sid AND SP.is_disabled = 0 AND SP.name NOT LIKE 'NT AUTHORITY\\%' AND SP.name NOT LIKE 'NT SERVICE\\%'
          WHERE
            U.name != 'dbo' AND
            U.type_desc IN ('SQL_USER','WINDOWS_USER','WINDOWS_GROUP')
        SQL
        block do
          @sql_results.each do |row|
            user = row['user']

            if !database_config['users'][user]
              if is_database_managed || delete_unmanaged_users
                Chef::Log.info "Removing historic user #{user} in #{database_name}"

                sqlshell_ms_user "#{instance_key}-#{database_name}-#{user}" do
                  jdbc_url jdbc_url
                  jdbc_driver jdbc_driver
                  extra_classpath extra_classpath
                  jdbc_properties jdbc_properties
                  database database_name
                  user user

                  action :drop
                end
              else
                Chef::Log.error "Unmanaged user '#{user}' in '#{database_name}' found"
              end
            end
          end
        end
      end
    end
  end

  if value['logins']
    sqlshell_exec "Remove historic Server Roles on instance #{instance_key}" do
      jdbc_url jdbc_url
      jdbc_driver jdbc_driver
      extra_classpath extra_classpath
      jdbc_properties jdbc_properties
      command <<-SQL
        SELECT
          P.name, RP.name as role
        FROM
          sys.server_principals P
        JOIN sys.server_role_members SRM ON SRM.member_principal_id = P.principal_id
        JOIN sys.server_principals RP ON RP.principal_id = SRM.role_principal_id AND RP.type_desc = 'SERVER_ROLE'
        WHERE
          P.is_disabled = 0 AND
          P.name NOT LIKE 'NT AUTHORITY\\%' AND
          P.name NOT LIKE 'NT SERVICE\\%' AND
          P.type_desc IN ('SQL_LOGIN', 'WINDOWS_GROUP', 'WINDOWS_LOGIN')
      SQL
      block do
        logins_with_roles = []
        role_map = {}
        value['logins'].each_pair do |login, login_config|
          if login_config['server_roles']
            logins_with_roles << login
            role_map[login] = (role_map[login] || []) + login_config['server_roles'].keys
          end
        end

        @sql_results.each do |row|
          next if row['name'] == jdbc_properties['user']

          login = row['name']
          role = row['role']

          if !logins_with_roles.include?(login) || !(role_map[login] && role_map[login].include?(role))
            if delete_unmanaged_server_roles
              Chef::Log.info "#{instance_key}-Removing historic server role #{role} from #{login}"
              sqlshell_ms_server_role login do
                jdbc_url jdbc_url
                jdbc_driver jdbc_driver
                extra_classpath extra_classpath
                jdbc_properties jdbc_properties
                role role

                action :remove
              end
            else
              Chef::Log.error "Unmanaged server role #{role} from #{login} found"
            end
          end
        end
      end
    end

    sqlshell_exec "Remove historic logins on instance #{instance_key}" do
      jdbc_url jdbc_url
      jdbc_driver jdbc_driver
      extra_classpath extra_classpath
      jdbc_properties jdbc_properties
      command <<-SQL
        SELECT
          SP.name, SP.type_desc
        FROM
          sys.syslogins L
        JOIN sys.server_principals SP ON SP.sid = L.sid
        WHERE
          SP.type_desc IN ('SQL_LOGIN', 'WINDOWS_GROUP', 'WINDOWS_LOGIN') AND
          SP.is_disabled = 0 AND
          SP.name NOT LIKE 'NT AUTHORITY\\%' AND
          SP.name NOT LIKE 'NT SERVICE\\%'
      SQL
      block do
        @sql_results.each do |row|
          login = row['name']
          if value['logins'][login].nil? && login != jdbc_properties['user']
            if delete_unmanaged_logins
              Chef::Log.info "#{instance_key}-Removing historic login #{login}"
              sqlshell_ms_login "##{instance_key}-#{login}" do
                jdbc_url jdbc_url
                jdbc_driver jdbc_driver
                extra_classpath extra_classpath
                jdbc_properties jdbc_properties

                login login

                action :drop
              end
            else
              Chef::Log.error "Unmanaged login #{login} found"
            end
          end
        end
      end
    end

    sqlshell_exec "Remove historic databases on instance #{instance_key}" do
      jdbc_url jdbc_url
      jdbc_driver jdbc_driver
      extra_classpath extra_classpath
      jdbc_properties jdbc_properties
      command <<-SQL
        SELECT name
        FROM sys.databases
        WHERE name NOT IN ('master','model','msdb','tempdb')
      SQL
      block do
        @sql_results.each do |row|
          database_name = row['name']
          if value['databases'].nil? || value['databases'][database_name].nil?
            if delete_unmanaged_databases
              Chef::Log.info "Removing historic database #{database_name}"
              sqlshell_ms_database "#{instance_key}-#{database_name}" do
                jdbc_url jdbc_url
                jdbc_driver jdbc_driver
                extra_classpath extra_classpath
                jdbc_properties jdbc_properties

                database database_name

                action :drop
              end
            else
              Chef::Log.error "Unmanaged database named '#{database_name}' found"
            end
          end
        end
      end
    end
  end
  RealityForge::SqlServer.set_current_instance(node, nil)
end

sq_sort(node['sqlshell']['sql_server']['instances']).each_pair do |instance_key, definition|
  RealityForge::SqlServer.set_current_instance(node, instance_key)
  if definition['recipes'] && definition['recipes']['after']
    sq_sort(definition['recipes']['after']).each_pair do |recipe, config|
      Chef::Log.info "Including instance 'after' recipe '#{recipe}' Priority: #{sq_priority(config)}"
      include_recipe recipe
    end
  end
  RealityForge::SqlServer.set_current_instance(node, nil)
end