text:
import traceback

import simplejson
import os
import shutil
import subprocess

import six
from threading import Thread, Lock
import time
import sys

from aetros.utils import invalid_json_values, setup_git_ssh, create_ssh_stream, read_home_config, is_debug2, is_debug3

class GitCommandException(Exception):
    pass

class Git:
    """
    This class is used to store and sync all job data to local git or (if online) stream files directly to AETROS Trainer server.

    Git.stream_file and Git.store_file both stream new data directly to the server. At the end (Git.end) we commit
    the files locally and (if online) store the blob on the server's git. On a `git push` git detects that the content
    is already on our server which eliminates useless content transmissions.

    In either way (online or offline) all job information is stored in the local git repository and can be pushed any
    time to the AETROS git server. If the training happened in offline modus, one can push the job's ref (e.g. git push origin refs/aetros/job/<id>)
    to make the job available in AETROS Trainer later on.

    Job id is created always in the local git, except the job has been created through the AETROS Trainer interface.
    If created in AETROS Trainer, we retrieve the initial configuration of the job using `git pull origin refs/aetros/job/<id>` and read
    its `aetros/job.json` blob of the head tree.
    """
    def __init__(self, logger, client, config, model_name, is_master):
        self.logger = logger
        self.client = client

        self.config = config
        self.git_host = config['host']
        self.storage_dir = config['storage_dir']

        self.model_name = model_name
        self.is_master = is_master

        if not self.storage_dir:
            raise Exception('No storage_dir given from home configuration.')

        if not model_name:
            raise Exception('No model_name given.')

        self.git_path = os.path.normpath(self.storage_dir + '/' + model_name + '.git')

        self.command_lock = Lock()
        self.stream_files_lock = Lock()
        self.index_lock = Lock()
        self.push_lock = Lock()

        self.debug = False
        self.last_push_time = 0
        self.active_push = False
        self.index_path = None

        self.job_id = None
        self.active_thread = False
        self.thread_push_instance = None

        self.synced_object_shas = {}

        self.git_batch_commit = False

        self.git_batch_commit_messages = []

        self.keep_stream_files = False

        self.streamed_files = {}
        self.store_files = {}

        git_not_found = 'Git binary not available. Please install Git >= 2.3.0 first and make it available in $PATH.'
        try:
            if subprocess.Popen(['git', '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() > 0:
                self.logger.error(git_not_found)
                sys.exit(2)
        except OSError:
            self.logger.error(git_not_found)
            sys.exit(2)

        ssh_not_found = 'SSH binary not available. Please install SSH first and make it available in $PATH.'
        try:
            if subprocess.Popen(['ssh', '-V'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() > 0:
                self.logger.error(ssh_not_found)
                sys.exit(2)
        except OSError:
            self.logger.error(ssh_not_found)
            sys.exit(2)

        self.delete_git_ssh = setup_git_ssh(config)
        self.logger.debug("GIT_SSH='" + str(os.getenv('GIT_SSH'))+"'")
        self.git_name = None
        self.git_email = None

        import getpass
        self.git_name = getpass.getuser()
        import socket
        self.git_email = self.git_name + '@' + socket.gethostname()

        # check if its a git repo
        if os.path.exists(self.git_path):
            out, code, err = self.command_exec(['remote'])
            if code != 0:
                raise Exception('Given git_path (%s) already exists and does not seem to be a git repository. Error: %s' % (self.git_path, err))
        else:
            os.makedirs(self.git_path)
            self.command_exec(['init'])
            self.command_exec(['remote', 'add', 'origin', self.git_url])

        # make sure its not called before git init
        if not os.path.exists(self.temp_path):
            os.makedirs(self.temp_path)

        # requires the temp folder
        self.prepare_index_file()

        # check if given repo_path is current folder.
        # check its origin remote and see if model_name matches
        self.origin_url = self.get_remote_url('origin')

        if self.origin_url and self.git_url not in self.origin_url:
            logger.warning("It seems you switched between aetros.com and an on-premise installation or updated host " \
                           "in your home configuration Given git_path (%s) points to a repository (%s) that is not "
                           "the git repo of the model (%s). " \
                           "We updated the remote origin automatically." \
                            % (self.git_path, self.origin_url, self.git_url))

            self.command_exec(['remote', 'remove', 'origin'])
            self.command_exec(['remote', 'add', 'origin', self.git_url])

    def get_remote_url(self, origin_name):
        output = self.command_exec(['remote', '-v'], allowed_to_fail=True)[0].decode('utf-8').strip().split('\n')

        for line in output:
            if line.startswith(origin_name):
                return line[len(origin_name)+1:line.index('.git')+4]

    @property
    def work_tree(self):
        return os.getenv('AETROS_GIT_WORK_DIR') or os.path.normpath(self.storage_dir + '/' + self.model_name + '/' + self.job_id)

    @property
    def env(self):
        my_env = os.environ.copy()
        if self.index_path:
            # todo, shouldn't it be the same as master's?
            my_env['GIT_INDEX_FILE'] = self.index_path

        my_env['GIT_SSH'] = os.getenv('GIT_SSH', '')

        return my_env

    @property
    def temp_path(self):
        return self.git_path + '/temp'

    @property
    def ref_head(self):
        return 'refs/aetros/job/' + self.job_id

    @property
    def git_url(self):
        return 'git@%s:%s.git' % (self.git_host, self.model_name)

    def get_base_command(self):
        base_command = ['git', '--bare', '--git-dir', self.git_path]
        base_command += ['-c', 'user.name=' + self.git_name]
        base_command += ['-c', 'user.email=' + self.git_email]

        return ' '.join(base_command)

    def command_exec(self, command, inputdata=None, allowed_to_fail=False, show_output=False, no_logging=False):
        interrupted = False

        if inputdata is not None and not isinstance(inputdata, six.binary_type):
            inputdata = inputdata.encode('utf-8')

        if command[0] != 'git':
            base_command = ['git', '--bare', '--git-dir', self.git_path]
            if command[0] == 'commit-tree' or command[0] == 'commit':
                base_command += ['-c', 'user.name=' + self.git_name]
                base_command += ['-c', 'user.email=' + self.git_email]
            command = base_command + command

        p = None
        stdoutdata = ''
        stderrdata = ''

        try:
            self.command_lock.acquire()

            if no_logging:
                p = subprocess.Popen(command, bufsize=0, stdin=subprocess.PIPE, env=self.env)
                p.communicate(inputdata)
            else:
                p = subprocess.Popen(
                    command, bufsize=0,
                    stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self.env
                )
                stdoutdata, stderrdata = p.communicate(inputdata)

                if show_output:
                    if stdoutdata:
                        sys.stdout.write(stdoutdata)
                    if stderrdata:
                        sys.stderr.write(stderrdata)
        except (KeyboardInterrupt, SystemExit):
            raise
        except TypeError as e:
            self.logger.error("Could not execute Git command: " + str(command))
            self.logger.error(str(self.env))
            self.logger.error(str(e))
            sys.exit(2)
        finally:
            if self.command_lock.locked():
                self.command_lock.release()

        try:
            stderrdata = stderrdata.decode('utf-8')
        except Exception: pass

        is_debug3() and self.logger.debug("Git command: " + (' '.join(command)))

        # When working on Git in several threads, sometimes it can not get the lock file, like:
        #
        #   fatal: Unable to create '/Users/marc/.aetros/marcj/debug:test.git/ORIG_HEAD.lock': File exists.
        #
        #   Another git process seems to be running in this repository, e.g.
        #   an editor opened by 'git commit'. Please make sure all processes
        #   are terminated then try again. If it still fails, a git process
        #   may have crashed in this repository earlier:
        #   remove the file manually to continue.
        #
        # We neeed to check for that error, and run the command again

        if 'Another git process' in stderrdata:
            time.sleep(0.3)
            return self.command_exec(command, inputdata, allowed_to_fail)

        if 'Connection refused' in stderrdata or 'Permission denied' in stderrdata:
            if 'Permission denied' in stderrdata:
                self.logger.warning("You have no permission to push to that model. Make sure your SSH key is properly"
                                    " configured.")

            self.logger.error(stderrdata)
            return '', 1, ''

        if not interrupted and not allowed_to_fail and p is not None and p.returncode != 0:
            raise GitCommandException('Command failed: ' + ' '.join(command) + ', code: ' + str(p.returncode)
                                      +"\nstdout: '" + str(stdoutdata)
                                      +"',\nstderr: '" + str(stderrdata)
                                      # +"', env="+str(self.env)
                                      +", input="+str(inputdata)[:50])

        return stdoutdata, p.returncode if p is not None else None, stderrdata

    def prepare_index_file(self):
        """
        Makes sure that GIT index file we use per job (by modifying environment variable GIT_INDEX_FILE)
        is not locked and empty. Git.fetch_job uses `git read-tree` to updates this index. For new jobs, we start
        with an empty index - that's why we delete it every time.
        """
        if os.getenv('AETROS_GIT_INDEX_FILE'):
            self.index_path = os.getenv('AETROS_GIT_INDEX_FILE')
            return

        import tempfile
        h, path = tempfile.mkstemp('aetros-git', '', self.temp_path)

        self.index_path = path

        # we give git a unique file path for that index. However, git expect it to be non-existent for empty indexes.
        # empty file would lead to "fatal: index file smaller than expected"
        os.close(h)
        os.unlink(self.index_path)

        self.logger.debug('GIT_INDEX_FILE created at ' + self.index_path)

    def fetch_job(self, job_id, checkout=False):
        """
        Fetch the current job reference (refs/aetros/job/<id>) from origin and (when checkout=True)read its tree to
        the current git index and checkout into working director.
        """
        self.job_id = job_id

        self.logger.debug("Git fetch job reference %s" % (self.ref_head, ))
        out, code, err = self.command_exec(['ls-remote', 'origin', self.ref_head])

        if code:
            self.logger.error('Could not find the job ' + job_id + ' on the server. Are you online and does the job exist?')
            sys.exit(1)

        try:
            self.command_exec(['fetch', '-f', '-n', 'origin', self.ref_head+':'+self.ref_head])
        except Exception:
            self.logger.error("Could not load job information for " + job_id + '. You need to be online to start pre-configured jobs.')
            raise

        self.read_job(job_id, checkout)

    def is_job_fetched(self, job_id):
        try:
            self.command_exec(['rev-parse', 'refs/aetros/job/' + job_id])[0].decode('utf-8').strip()
            return True
        except Exception:
            return False

    def read_job(self, job_id, checkout=False):
        """
        Reads head and reads the tree into index,
        and checkout the work-tree when checkout=True.

        This does not fetch the job from the actual server. It needs to be in the local git already.
        """
        self.job_id = job_id

        commit = self.get_head_commit()
        self.logger.debug('Job ref points to ' + commit)
        self.command_exec(['read-tree', self.ref_head])

        if checkout:
            self.logger.debug('Working directory in ' + self.work_tree)

            # make sure we have checked out all files we have added until now. Important for simple models,
            # so we have the actual model.py and dataset scripts.
            if os.path.exists(self.work_tree):
                shutil.rmtree(self.work_tree)

            os.makedirs(self.work_tree)

            # make the working tree reflect exactly the tree of ref_head.
            # since we removed the dir before, we have exactly the tree of the reference
            # '--', '.' is important to not update HEAD
            self.command_exec(['--work-tree', self.work_tree, 'checkout', self.ref_head, '--', '.'])

    def read_tree(self, ref):
        """
        Reads the ref into the current index.

        :param ref: the actual git reference
        :return:
        """
        self.command_exec(['read-tree', ref])

    # def restart_job(self):
    #     if not self.job_id:
    #         raise Exception('Could not restart unknown job. fetch_job() it first.')
    #
    #     self.command_exec(['update-ref', self.ref_head, self.job_id])
    #
    #     self.command_exec(['read-tree', self.ref_head])
    #
    #     # make sure we have checked out all files we have added until now. Important for simple models, so we have the
    #     # actual model.py and dataset scripts.
    #     if not os.path.exists(self.work_tree):
    #         os.makedirs(self.work_tree)
    #
    #     # updates index and working tree
    #     # this leaves other files in self.work_tree alone, which needs to be because this is also the working tree
    #     # of files checked out by start.py (custom models)
    #     self.command_exec(['--work-tree', self.work_tree, 'reset', '--hard', self.ref_head])

    # def create_task_id(self, job_id, data):
    #     """
    #     Creates a new task id and reference (refs/aetros/task/<id>) by creating a new commit with the same tree
    #     as job_id's and added aetros/task.json file. As parent commit the job_id is used.
    #     """
    #     self.read_tree(job_id)
    #     self.add_file('aetros/task.json', simplejson.dumps(data, indent=4))
    #     tree_id = self.write_tree()
    #
    #     task_id = self.command_exec(['commit-tree', '-m', "TASK_CREATED", tree_id, '-p', job_id])[0].decode('utf-8').strip()
    #
    #     ref = 'refs/aetros/task/' + task_id
    #     self.command_exec(['update-ref', ref, task_id])
    #
    #     return task_id

    def create_job_id(self, data):
        """
        Create a new job id and reference (refs/aetros/job/<id>) by creating a new commit with empty tree. That
        root commit is the actual job id. A reference is then created to the newest (head) commit of this commit history.
        The reference will always be updated once a new commit is added.
        """
        self.add_file('aetros/job.json', simplejson.dumps(data, indent=4))
        tree_id = self.write_tree()

        self.job_id = self.command_exec(['commit-tree', '-m', "JOB_CREATED", tree_id])[0].decode('utf-8').strip()

        out, code, err = self.command_exec(['show-ref', self.ref_head], allowed_to_fail=True)
        if not code:
            self.logger.warning("Generated job id already exists, because exact same experiment values given. Ref " + self.ref_head)

        self.command_exec(['update-ref', self.ref_head, self.job_id])

        # make sure we have checkedout all files we have added until now. Important for simple models, so we have the
        # actual model.py and dataset scripts.
        if not os.path.exists(self.work_tree):
            os.makedirs(self.work_tree)

        # updates index and working tree
        # '--', '.' is important to not update HEAD
        self.command_exec(['--work-tree', self.work_tree, 'checkout', self.ref_head, '--', '.'])

        # every caller needs to make sure to call git.push
        return self.job_id

    def start_push_sync(self):
        """
        Starts the detection of unsynced Git data.
        """
        self.active_thread = True
        self.active_push = True

        self.thread_push_instance = Thread(target=self.thread_push)
        self.thread_push_instance.daemon = True
        self.thread_push_instance.start()

    def stop(self):
        """
        Stops the `git push` thread and commits all streamed files (Git.store_file and Git.stream_file), followed
        by a final git push.

        You can not start the process again.
        """
        self.active_thread = False

        if self.thread_push_instance and self.thread_push_instance.isAlive():
            self.thread_push_instance.join()

        with self.batch_commit('STREAM_END'):
            for path, handle in six.iteritems(self.streamed_files.copy()):
                # open again and read full content
                full_path = os.path.normpath(self.temp_path + '/stream-blob/' + self.job_id + '/' + path)
                self.logger.debug('Git stream end for file: ' + full_path)

                del self.streamed_files[path]

                # make sure its written to the disk
                try:
                    self.stream_files_lock.acquire()
                    if not handle.closed:
                        handle.flush()
                        handle.close()
                finally:
                    self.stream_files_lock.release()

                with open(full_path, 'r') as f:
                    self.commit_file(path, path, f.read())

                if not self.keep_stream_files:
                    os.unlink(full_path)

        with self.batch_commit('STORE_END'):
            for path, bar in six.iteritems(self.store_files.copy()):
                full_path = os.path.normpath(self.temp_path + '/store-blob/' + self.job_id + '/' + path)
                self.logger.debug('Git store end for file: ' + full_path)

                del self.store_files[path]

                try:
                    self.stream_files_lock.acquire()
                    self.commit_file(path, path, open(full_path, 'r').read())
                finally:
                    self.stream_files_lock.release()

                if not self.keep_stream_files:
                    os.unlink(full_path)

    def clean_up(self):
        self.logger.debug("Git: clean up")

        if os.path.exists(self.index_path):
            os.remove(self.index_path)

        if self.delete_git_ssh:
            self.delete_git_ssh()
            self.delete_git_ssh = None

    def batch_commit(self, message):
        """
        Instead of committing a lot of small commits you can batch it together using this controller.

        Example:

        with git.batch_commit('BATCHED'):
            git.commit_file('my commit 1', 'path/to/file', 'content from file')
            git.commit_json_file('[1, 2, 3]', 'path/to/file2', 'json array')

        Withing the `with` block you can use group the method calls of `commit_file` and `commit_json_file`, and every other
        method calling this two methods.

        :type message: str
        :return: with controller to be used with Python's `with git.batch_commit():`
        """
        class controlled_execution:
            def __init__(self, git, message):
                self.git = git
                self.message = message

            def __enter__(self):
                self.git.git_batch_commit = True

                if self.git.job_id:
                    # make sure we're always on the tip tree
                    self.git.read_tree(self.git.ref_head)

            def __exit__(self, type, value, traceback):
                self.git.git_batch_commit = False

                # if nothing committed, we return early
                if not self.git.git_batch_commit_messages: return

                commit_message = self.message
                if self.git.git_batch_commit_messages:
                    commit_message = commit_message + "\n\n" + "\n".join(self.git.git_batch_commit_messages)
                self.git.git_batch_commit_messages = []

                self.git.commit_index(commit_message)

        return controlled_execution(self, message)

    def get_empty_tree_id(self):
        """
        Returns the famous empty tree id. To be used in creating a new empty root commit without any files.
        4b825dc642cb6eb9a060e54bf8d69288fbee4904

        :rtype: str
        """
        return self.command_exec(['hash-object', '--stdin', '-ttree'], '')[0].decode('utf-8').strip()

    def store_file(self, path, data, fast_lane=True):
        """
        Store the file in temp folder and stream it to server if online.

        This makes sure that we have all newest data of this file on the server directly.

        This method always overwrites the content of path. If you want to append always the content,
        use Git.stream_file() instead.

        At the end of the job, the content the server received is stored as git blob on the server. It is then committed
        locally and pushed. Git detects that the server already has the version (through the continuous streaming)
        and won't push it again.
        """

        self.stream_files_lock.acquire()
        try:

            full_path = os.path.normpath(self.temp_path + '/store-blob/' + self.job_id + '/' + path)
            if not os.path.exists(os.path.dirname(full_path)):
                os.makedirs(os.path.dirname(full_path))

            if hasattr(data, 'encode'):
                data = data.encode("utf-8", 'replace')

            already_set = path in self.store_files and self.store_files[path] == data

            if is_debug3():
                sys.__stderr__.write('git:store_file(%s, %s, %s), already_set=%s\n'
                                     % (str(path), str(data)[0:180], str(fast_lane), str(already_set)))

            if already_set:
                return

            open(full_path, 'wb').write(data)
            self.store_files[path] = data

            if self.client.online is not False:
                self.client.send({'type': 'store-blob', 'path': path, 'data': data}, channel='' if fast_lane else 'files')
        finally:
            self.stream_files_lock.release()

    def stream_file(self, path, fast_lane=True):
        """
        Create a temp file, stream it to the server if online and append its content using the write() method.
        This makes sure that we have all newest data of this file on the server directly.

        At the end of the job, the content the server received is stored as git blob on the server. It is then committed
        locally and pushed. Git detects that the server already has the version (through the continuous streaming)
        and won't push it again. Very handy for rather large files that will append over time (like channel data, logs)

        Example:

        self.log_stream = git.stream_file('log.txt')

        self.log_stream.write("new line\n");
        self.log_stream.write("another line\n");
        """

        # create temp file
        # open temp file

        # register stream file and write locally
        # on end() git_commit that file locally

        # create socket connection to server
        # stream file to server
        # on end() send server end signal, so he can store its content in git as blob as well.
        # A git push would detect that both sides have the same content already,
        # except when server connection broke between start() and end().
        # Result -> already transmitted logs/channel data (probably many MBs) won't transfered twice
        # when doing a git-push.

        # return handler to write to this file

        full_path = os.path.normpath(self.temp_path + '/stream-blob/' + self.job_id + '/' + path)
        if not os.path.exists(os.path.dirname(full_path)):
            os.makedirs(os.path.dirname(full_path))

        handle = open(full_path, 'wb')
        self.streamed_files[path] = handle

        class Stream():
            def __init__(self, git):
                self.git = git

            def write(self, data):
                if path not in self.git.streamed_files:
                    # already committed to server
                    return

                if hasattr(data, 'encode'):
                    data = data.encode("utf-8", 'replace')

                try:
                    self.git.stream_files_lock.acquire()
                    if not handle.closed:
                        handle.write(data)
                        handle.flush()
                except IOError as e:
                    handle.close()

                    if 'No space left' in e.__str__():
                        sys.stderr.write(traceback.format_exc() + '\n')
                        self.git.logger.error(e.__str__())
                finally:
                    self.git.stream_files_lock.release()

                if self.git.client.online is not False:
                    self.git.client.send({'type': 'stream-blob', 'path': path, 'data': data}, channel='' if fast_lane else 'files')

        return Stream(self)

    def write_blob(self, content):
        return self.command_exec(['hash-object', '-w', "--stdin"], content)[0].decode('utf-8').strip()

    def add_index(self, mode, blob_id, path):
        """
        Add new entry to the current index
        :param tree:
        :return:
        """
        self.command_exec(['update-index', '--add', '--cacheinfo', mode, blob_id, path])

    def write_tree(self):
        """
        Writes the current index into a new tree
        :return: the tree sha
        """
        return self.command_exec(['write-tree'])[0].decode('utf-8').strip()

    def commit_json_file(self, message, path, content):
        return self.commit_file(message, path + '.json', simplejson.dumps(content, default=invalid_json_values))

    def lock_write(self):
        class Controller():
            def __init__(self, git):
                self.git = git

            def __enter__(self):
                self.git.index_lock.acquire()

                if self.git.job_id:
                    # make sure we're always on the tip tree
                    self.git.read_tree(self.git.ref_head)

            def __exit__(self, type, value, traceback):
                self.git.index_lock.release()

        return Controller(self)

    def add_file(self, git_path, content):
        """
        Add a new file as blob in the storage and add its tree entry into the index.

        :param git_path: str
        :param content: str
        """
        blob_id = self.write_blob(content)
        self.add_index('100644', blob_id, git_path)

    def add_file_path(self, git_path, local_path):
        with open(local_path, 'rb') as f:
            self.add_file(git_path, f.read())

    def add_file_path_in_work_tree(self, path, work_tree, verbose=True):
        """
        Add a new file as blob in the storage and add its tree entry into the index.
        """
        args = ['--work-tree', work_tree, 'add', '-f']
        if verbose:
            args.append('--verbose')
        args.append(path)
        self.command_exec(args, show_output=verbose)

    def add_local_file(self, path):
        with open(path, 'r') as f:
            self.add_file(path, f.read())

    def commit_file(self, message, path, content):
        """
        Add a new file as blob in the storage, add its tree entry into the index and commit the index.

        :param message: str
        :param path: str
        :param content: str
        :return:
        """
        if self.git_batch_commit:
            self.add_file(path, content)
            self.git_batch_commit_messages.append(message)
        else:
            with self.lock_write():
                if self.job_id:
                    self.read_tree(self.ref_head)

                self.add_file(path, content)

                return self.commit_index(message)

    def diff_objects(self, latest_commit_sha):
        """
                Push all changes to origin, based on objects, not on commits.
                Important: Call this push after every new commit, or we lose commits.
                """
        base = ['git', '--bare', '--git-dir', self.git_path]

        object_shas = []
        summary = {'commits': [], 'trees': [], 'files': []}

        def read_parents_and_tree_from(commit):
            if commit in self.synced_object_shas or commit in object_shas:
                # this commit has already been synced or read
                return None, None

            self.synced_object_shas[commit] = True
            summary['commits'].append(commit)
            object_shas.append(commit)

            object_content = subprocess.check_output(base + ['cat-file', '-p', commit]).decode('utf-8').strip()
            parents = []
            tree = ''
            for line in object_content.splitlines():
                if line.startswith('tree '):
                    tree = line[len('tree '):]
                if line.startswith('parent '):
                    parents.append(line[len('parent '):])

            return parents, tree

        def collect_files_from_tree(tree):
            if tree in self.synced_object_shas or tree in object_shas:
                # we have exactly this tree already synced or read, meaning all its objects as well
                return

            self.synced_object_shas[tree] = True
            summary['trees'].append(tree)
            object_shas.append(tree)

            object_content = subprocess.check_output(base + ['ls-tree', '-r', '-t', tree]).decode('utf-8').strip()

            for line in object_content.splitlines():
                exploded = line.split(' ')

                if len(exploded) < 3:
                    sys.stderr.write("Error: Wrong line format of ls-tree for %s: %s\n" % (tree, line,))
                    sys.exit(1)

                object_to_add = str(exploded[2][:40])
                path = str(exploded[2][41:])

                if object_to_add in self.synced_object_shas or object_to_add in object_shas:
                    # have it already in the list or already synced
                    continue

                object_shas.append(object_to_add)
                self.synced_object_shas[object_to_add] = True
                summary['files'].append([object_to_add, path])

        commits_to_check = [latest_commit_sha]

        while len(commits_to_check):
            sha = commits_to_check.pop(0)
            parents, tree = read_parents_and_tree_from(sha)

            if parents:
                for parent in parents:
                    if parent not in commits_to_check:
                        commits_to_check.append(parent)

            if tree:
                collect_files_from_tree(tree)

        is_debug2() and self.logger.debug("shas_to_check %d: %s " % (len(object_shas), str(object_shas),))

        if not object_shas:
            return [], summary

        try:
            is_debug2() and self.logger.debug("Do git-cat-file-check.sh")

            ssh_stream = create_ssh_stream(read_home_config(), exit_on_failure=False)
            channel = ssh_stream.get_transport().open_session()
            channel.exec_command('git-cat-file-check.sh "%s"' % (self.model_name + '.git',))
            channel.sendall('\n'.join(object_shas))
            channel.shutdown_write()

            def readall(c):
                content = b''
                while True:
                    try:
                        chunk = c.recv(1024)
                        if chunk == b'':
                            break
                        content += chunk
                    except (KeyboardInterrupt, SystemExit):
                        return

                return content

            missing_objects = readall(channel).decode('utf-8').splitlines()
            channel.close()
            ssh_stream.close()

            # make sure we have in summary only SHAs we actually will sync
            for stype in six.iterkeys(summary):
                ids = summary[stype][:]
                for sha in ids:
                    if stype == 'files':
                        if sha[0] not in missing_objects:
                            summary[stype].remove(sha)
                    else:
                        if sha not in missing_objects:
                            summary[stype].remove(sha)

            return missing_objects, summary
        except (KeyboardInterrupt, SystemExit):
            raise
        except Exception as e:
            self.logger.error("Failed to generate diff_objects: %s" % (str(e),))
            for sha in object_shas:
                if sha in self.synced_object_shas:
                    del self.synced_object_shas[sha]
            return None, None

    def get_head_commit(self):
        return self.command_exec(['rev-parse', self.ref_head])[0].decode('utf-8').strip()

    def push(self):
        self.push_lock.acquire()
        missing_object_sha = []

        try:
            commit_sha = self.get_head_commit()
            missing_object_sha, summary = self.diff_objects(commit_sha)
            base = ['git', '--bare', '--git-dir', self.git_path]

            if not missing_object_sha:
                return False

            is_debug2() and self.logger.debug("Found %d missing objects" % (len(missing_object_sha),))
            is_debug2() and self.logger.debug(str(summary))

            if missing_object_sha:
                is_debug2() and self.logger.debug("Git push")
                try:
                    opts = [
                        '--no-reuse-delta',
                        '--compression=0',
                    ]
                    pack_process = subprocess.Popen(base + ['pack-objects', '--stdout'] + opts, stderr=subprocess.PIPE,
                                                    stdin=subprocess.PIPE, stdout=subprocess.PIPE)
                    pack_content, stderr = pack_process.communicate(('\n'.join(missing_object_sha)).encode())

                    if pack_process.returncode:
                        self.logger.error("Git pack-objects failed: %s, error: %s" % (pack_content, stderr))
                        self.synced_object_shas = {}
                        return False

                    message = {
                        'type': 'git-unpack-objects',
                        'ref': self.ref_head,
                        'commit': commit_sha,
                        'pack': pack_content,
                        'objects': summary,
                    }
                    size = self.client.send(message, 'files')
                    is_debug2() and self.logger.debug("Git pack of size %d is on the way" % (size,))
                except (KeyboardInterrupt, SystemExit):
                    raise
                except Exception:
                    # next push we check again all objects in that job history
                    self.synced_object_shas = {}
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            import traceback
            self.logger.error(traceback.format_exc())
            return False
        finally:
            self.push_lock.release()

        return missing_object_sha

    def thread_push(self):
        last_synced_head = self.get_head_commit()

        while self.active_thread:
            try:
                head = self.get_head_commit()
                if last_synced_head != head:
                    self.logger.debug("Git head moved from %s to %s" % (last_synced_head, head))
                    if self.push() is not False:
                        last_synced_head = head

                time.sleep(0.5)
            except (SystemExit, KeyboardInterrupt):
                return
            except Exception as e:
                time.sleep(5)

    def commit_index(self, message):
        """
        Commit the current index.
        :param message: str
        :return: str the generated commit sha
        """
        tree_id = self.write_tree()

        args = ['commit-tree', tree_id, '-p', self.ref_head]

        # todo, this can end in a race-condition with other processes adding commits
        commit = self.command_exec(args, message)[0].decode('utf-8').strip()
        self.command_exec(['update-ref', self.ref_head, commit])

        return commit

    def has_file(self, path):
        try:
            out, code, err = self.command_exec(['cat-file', '-p', self.ref_head+':'+path])

            return code == 0
        except Exception:
            return False

    def contents(self, path):
        """
        Reads the given path of current ref_head and returns its content as utf-8
        """
        try:
            out, code, err = self.command_exec(['cat-file', '-p', self.ref_head+':'+path])
            if not code:
                return out.decode('utf-8')
        except Exception:
            pass

        return None

    def git_read(self, path):
        return self.command_exec(['cat-file', '-p', self.ref_head+':'+path])


text:
namespace org {
  namespace apache {
    namespace lucene {
      namespace index {
        class Term;
        class IndexReader;
      }
      namespace search {
        class IndexSearcher;
        class Weight;
      }
    }
  }
}
namespace java {
  namespace lang {
    class Class;
    class Cloneable;
    class String;
  }
  namespace util {
    class Set;
  }
  namespace io {
    class IOException;
  }
}
template<class T> class JArray;

namespace org {
  namespace apache {
    namespace lucene {
      namespace search {

        class Query : public ::java::lang::Object {
        public:
          enum {
            mid_init$_54c6a166,
            mid_clone_97e3851a,
            mid_createWeight_367763cb,
            mid_equals_290588e2,
            mid_extractTerms_fb4f2b26,
            mid_getBoost_54c6a176,
            mid_hashCode_54c6a179,
            mid_rewrite_7edcaa43,
            mid_setBoost_06298cab,
            mid_toString_14c7b5c5,
            mid_toString_97a5258f,
            max_mid
          };

          static ::java::lang::Class *class$;
          static jmethodID *mids$;
          static bool live$;
          static jclass initializeClass(bool);

          explicit Query(jobject obj) : ::java::lang::Object(obj) {
            if (obj != NULL)
              env->getClass(initializeClass);
          }
          Query(const Query& obj) : ::java::lang::Object(obj) {}

          Query();

          Query clone() const;
          ::org::apache::lucene::search::Weight createWeight(const ::org::apache::lucene::search::IndexSearcher &) const;
          jboolean equals(const ::java::lang::Object &) const;
          void extractTerms(const ::java::util::Set &) const;
          jfloat getBoost() const;
          jint hashCode() const;
          Query rewrite(const ::org::apache::lucene::index::IndexReader &) const;
          void setBoost(jfloat) const;
          ::java::lang::String toString() const;
          ::java::lang::String toString(const ::java::lang::String &) const;
        };
      }
    }
  }
}

#include <Python.h>

namespace org {
  namespace apache {
    namespace lucene {
      namespace search {
        extern PyTypeObject PY_TYPE(Query);

        class t_Query {
        public:
          PyObject_HEAD
          Query object;
          static PyObject *wrap_Object(const Query&);
          static PyObject *wrap_jobject(const jobject&);
          static void install(PyObject *module);
          static void initialize(PyObject *module);
        };
      }
    }
  }
}

#endif

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Tradecraft, LLC</title>

    <link href="css/bootstrap.css" rel="stylesheet">

    <link href="css/modern-business.css" rel="stylesheet">

    <link href="font-awesome-4.2.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">

Software Product Development

Web Development

Vulnerability Research

Mobile App Development

iOS Andriod

Tradecraft is dedicated to technical excellence, software automation, and iterative deliveries to maximize customer satisfaction.

Tradecraft was founded to fulfill a need for quality crafted software and information technology solutions; a need that was not previously being met for customers with heightened security requirements in the healthcare, financial, intelligence, and defense fields. Tradecraft founders are experts in the fields of vulnerability analysis, computer network operations, and software engineering.

Vulnerability Research and Vulnerability Analysis

Web Development (JavaScript, Ruby, Rails, Node.js, PHP, Git, Tomcat, Nginx)

Software Engineering (Accumulo, Java, Cloud, Hadoop)

DevOps & Automation (RPM's, Capistrano, Jenkins, Open Stack, Chef, Puppet)

Systems Administration (Linux, Windows)

Database Development & Administration (MySQL, MongoDB, Oracle)

IT Project Management (PMI-PMP Certified)

Agile Coaching & Training (PMI-ACP Certified)

Software and Product Development

Web Development

JavaScript Ruby Rails NodeJS PHP Git Tomcat Nginx HTML5 CSS3

Mobile App Development

Android iOS

DevOps & Automation

RPM's Docker Jenkins Chef Puppet
 System Health Monitoring

System Administration

Linux Windows iOS

Software Engineering

Java Accumulo Hadoop C++ Data-Cloud Data-Analytics

Database Development & Administration

MongoDB MySQL Postgres Oracle MariaDB

Cloud Solutions

PAAS SAAS IAAS AWS
OpenStack GovCloud ICITE

Game Development

Unity Unreal-Engine CryEngine GameMaker

PMI Certified

Project Management Professional
 Agile Certified Practitioner

			Culture

						Leadership

						Leadership is not a rank or title, it's a decision to mentor and look after co-workers and customers

						Collaboration

						Work together, Ask questions, Be Curious, Take Risk, and do whats right

						Integrity

						Admit When You are Wrong. Then work as a team figure out how to fix it

Partners


text:
NSString * const ZSLRecorderViewCancelRecordTipsString = @"手指上滑,取消录音";
NSString * const ZSLRecorderViewWillCancelRecordTipsString = @"松开手指,取消录音";
NSString * const ZSLRecorderViewWaitingTipsString = @"正在处理...";

@interface ZSLRecorderView()
{
    UIWindow *_rootWindow;
}

@property (weak, nonatomic) IBOutlet UIControl *backgroundView;
@property (weak, nonatomic) IBOutlet UIView *boxView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UILabel *tipsLabel;

@property (strong, nonatomic) ZSLwaveMaker *waveMarker;

@end

@implementation ZSLRecorderView

+ (instancetype)view
{
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"ZSLRecorderButton" ofType:@"bundle"];
    ZSLRecorderView *view = [[[NSBundle bundleWithPath:bundlePath] loadNibNamed:@"ZSLRecorderView" owner:nil options:nil] lastObject];
    return view;
}

- (ZSLwaveMaker *)waveMarker
{
    if (!_waveMarker) {
        _waveMarker = [[ZSLwaveMaker alloc] init];
        _waveMarker.animationView = self.backgroundView;
        _waveMarker.spanScale = 3.0f;
        _waveMarker.originRadius = self.imageView.frame.size.width/2.0f;
        _waveMarker.waveColor = [UIColor colorWithRed:0.284 green:0.447 blue:1.000 alpha:0.2];
        _waveMarker.animationDuration = 6.0f;

    }
    return _waveMarker;
}

- (void)awakeFromNib
{
    self.active = YES;
    self.fullscreen = NO;
    self.backgroundView.alpha = 0.0f;
    self.tipsString = ZSLRecorderViewCancelRecordTipsString;
    _rootWindow = [self p_window];
}

- (void)setActive:(BOOL)active
{
    _active = active;
    self.imageView.highlighted = !_active;
}

- (void)setTipsString:(NSString *)tipsString
{
    _tipsString = tipsString;
    self.tipsLabel.text = _tipsString;
}

- (void)show
{
    if (!self.superview) {
        [_rootWindow addSubview:self];

        if (self.isFullscreenStyle) {
            self.frame = _rootWindow.bounds;
        } else {
            CGFloat widht = _rootWindow.frame.size.width - 40;
            self.frame = CGRectMake(0, 0, widht, widht);
            self.center = _rootWindow.center;
            self.clipsToBounds = YES;
            self.layer.cornerRadius = 20.0f;
        }

        [self layoutSubviews];
        [self layoutIfNeeded];

        CGPoint center =  [self.boxView convertPoint:self.imageView.center toView:self.backgroundView];
        self.waveMarker.waveCenter = center;

    }

    [self p_show];
}

- (void)dismiss
{
    [self p_hide];
}

#pragma mark- Private Methos

- (UIWindow *)p_window
{
    NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
    UIScreen *mainScreen = UIScreen.mainScreen;

    for (UIWindow *window in frontToBackWindows) {
        if (window.screen == mainScreen && window.windowLevel == UIWindowLevelNormal) {
            return window;
            break;
        }
    }

    return nil;
}

- (void)p_show
{
    self.tipsString = ZSLRecorderViewCancelRecordTipsString;
    [UIView animateWithDuration:0.4 animations:^{
        self.backgroundView.alpha = 1.0f;
    } completion:^(BOOL finished) {
        if (finished) {
            [self.waveMarker spanWaveContinuallyWithTimeInterval:0.8];
        }
    }];
}

- (void)p_hide
{
    [UIView animateWithDuration:0.4 animations:^{
        self.backgroundView.alpha = 0.0f;
    } completion:^(BOOL finished) {
        if (finished) {
            [self removeFromSuperview];
        }
    }];

    [self.waveMarker stopWave];
}

@end


text:
package org.keycloak.models.sessions.infinispan;

import org.infinispan.commons.api.BasicCache;
import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.SamlArtifactSessionMappingStoreProvider;
import org.keycloak.models.SamlArtifactSessionMappingStoreProviderFactory;

import java.util.UUID;
import java.util.function.Supplier;
import static org.keycloak.models.sessions.infinispan.InfinispanAuthenticationSessionProviderFactory.PROVIDER_PRIORITY;

/**
 * @author mhajas
 */
public class InfinispanSamlArtifactSessionMappingStoreProviderFactory implements SamlArtifactSessionMappingStoreProviderFactory {

    private static final Logger LOG = Logger.getLogger(InfinispanSamlArtifactSessionMappingStoreProviderFactory.class);

    // Reuse "actionTokens" infinispan cache for now
    private volatile Supplier<BasicCache<UUID, String[]>> codeCache;

    @Override
    public SamlArtifactSessionMappingStoreProvider create(KeycloakSession session) {
        lazyInit(session);
        return new InfinispanSamlArtifactSessionMappingStoreProvider(codeCache);
    }

    private void lazyInit(KeycloakSession session) {
        if (codeCache == null) {
            synchronized (this) {
                if (codeCache == null) {
                    this.codeCache = InfinispanSingleUseTokenStoreProviderFactory.getActionTokenCache(session);
                }
            }
        }
    }

    @Override
    public void init(Config.Scope config) {

    }

    @Override
    public void postInit(KeycloakSessionFactory factory) {

    }

    @Override
    public void close() {

    }

    @Override
    public String getId() {
        return "infinispan";
    }

    @Override
    public int order() {
        return PROVIDER_PRIORITY;
    }
}


text:
using System.ComponentModel;
using System.IO;
using System.Text;
using NLog.Config;
using NLog.Internal;

#if !SILVERLIGHT
namespace NLog.LayoutRenderers
{
    /// <summary>
    /// The call site source file name. Full callsite <see cref="CallSiteLayoutRenderer"/>
    /// </summary>
    [LayoutRenderer("callsite-filename")]
    [ThreadAgnostic]
    [ThreadSafe]
    public class CallSiteFileNameLayoutRenderer : LayoutRenderer, IUsesStackTrace
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="CallSiteFileNameLayoutRenderer" /> class.
        /// </summary>
        public CallSiteFileNameLayoutRenderer()
        {
            IncludeSourcePath = true;
        }

        /// <summary>
        /// Gets or sets a value indicating whether to include source file path.
        /// </summary>
        /// <docgen category='Rendering Options' order='10' />
        [DefaultValue(true)]
        public bool IncludeSourcePath { get; set; }

        /// <summary>
        /// Gets or sets the number of frames to skip.
        /// </summary>
        /// <docgen category='Rendering Options' order='10' />
        [DefaultValue(0)]
        public int SkipFrames { get; set; }

        /// <summary>
        /// Gets the level of stack trace information required by the implementing class.
        /// </summary>
        StackTraceUsage IUsesStackTrace.StackTraceUsage => StackTraceUsage.WithSource;

        /// <summary>
        /// Renders the call site and appends it to the specified <see cref="StringBuilder" />.
        /// </summary>
        /// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
        /// <param name="logEvent">Logging event.</param>
        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            if (logEvent.CallSiteInformation != null)
            {
                string fileName = logEvent.CallSiteInformation.GetCallerFilePath(SkipFrames);
                if (!string.IsNullOrEmpty(fileName))
                {
                    if (IncludeSourcePath)
                    {
                        builder.Append(fileName);
                    }
                    else
                    {
                        builder.Append(Path.GetFileName(fileName));
                    }
                }
            }
        }
    }
}
#endif


text:
layout: 404layout
title: Page not found!
---

Uh oh! Page not found!


text:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Login extends CI_Controller{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('m_login'); //memasukkan file model m_login.php ke dalam controller
        $this->load->helper('form');
		$this->load->library('form_validation');
    }

    public function index()
    {
        $session = $this->session->userdata('isLogin'); //mengabil dari session apakah sudah login atau belum
        if($session == FALSE) //jika session false maka akan menampilkan halaman login
        {
            $this->load->view('login_form');
        }else //jika session true maka di redirect ke halaman dashboard
        {
            redirect('dashboard');
        }
    }

    public function do_login()
    {
        $username = $this->input->post("uname");
        $password = $this->input->post("pass");

        $cek = $this->m_login->cek_user($username,md5($password)); //melakukan persamaan data dengan database
        if(count($cek) == 1){ //cek data berdasarkan username & pass
            foreach ($cek as $cek) {
                $level = $cek['user_level']; //mengambil data(level/hak akses) dari database
                $nameuser = $cek['user_name'];
            }
            $this->session->set_userdata(array(
                'isLogin'   => TRUE, //set data telah login
                'uname'  => $username, //set session username
                'lvl'      => $level, //set session hak akses
                'name'     => $nameuser,
            ));
            $this->session->set_flashdata('info', '
Selamat Datang '. $_SESSION['name'].'<button type="button" class="close" data-dismiss="alert" aria-label="Close">×</button>
');
            redirect('dashboard','refresh');  //redirect ke halaman dashboard
        }else{ //jika data tidak ada yng sama dengan database
            echo "";
            redirect('login','refresh');
        }

    }
}


text:
define([
  'aeris/util',
  'aeris/maps/animations/abstractanimation',
  'sinon'
], function(_, Animation) {
  var sinon = require('sinon');

  function TestFactory(opt_options) {
    var options = _.extend({
      to: new Date(99999999999)
    }, opt_options);
    var animationOptions = _.pick(options, [
      'timestep',
      'from',
      'to',
      'speed',
      'opacity',
      'endDelay'
    ]);

    this.animation = new Animation(animationOptions);

    spyOn(this.animation, 'goToTime').andCallThrough();
  }

  describe('AbstractAnimation', function() {
    var clock;

    beforeEach(function() {
      clock = sinon.useFakeTimers();
    });

    afterEach(function() {
      clock.restore();
    });

    beforeEach(function() {
      spyOn(Animation.prototype, 'pause').andCallThrough();
      spyOn(Animation.prototype, 'start').andCallThrough();

      this.addMatchers({
        toHaveBeenRestarted: function() {
          var animation = this.actual;
          var wasPaused = !!animation.pause.callCount;
          var wasStarted = !!animation.start.callCount;
          var isAnimating = animation.isAnimating();

          return wasPaused && wasStarted && isAnimating;
        }
      });
    });

    describe('start', function() {

      it('should animate at a specified speed (simple)', function() {
        var options = {
          from: new Date(0),
          timestep: 1000 * 60,      // one minute
          speed: 5                  // animates 5 timesteps per second
        };
        var test = new TestFactory(options);

        test.animation.start();

        _.times(25, function(i) {
          var seconds = i + 1;
          clock.tick(1000);
          // After each second, should animate up by 5 minutes
          // Because our timer interval might not be divisible
          // by 1000, we may be off by a timestep.
          expect(test.animation.goToTime.mostRecentCall.args[0]).
            toBeNear(options.timestep * options.speed * seconds, options.timestep);
        });
      });

      it('should animate at a specified speed (arbitrary)', function() {
        var options = {
          from: new Date(0),
          timestep: 37,
          speed: 57.6
        };
        var test = new TestFactory(options);

        test.animation.start();

        _.times(25, function(i) {
          var seconds = i + 1;
          clock.tick(1000);
          // After each second, should animate up by timestep * speed
          expect(test.animation.goToTime.mostRecentCall.args[0]).
            toBeNear(options.timestep * options.speed * seconds, options.timestep);
        });
      });

      it('should loop, after a delay', function() {
        var options = {
          from: new Date(0),
          to: new Date(100),
          endDelay: 1000,
          timestep: 10,
          speed: 1
        };
        var test = new TestFactory(options);
        var lastCallCount;
        test.animation.start();

        clock.tick(1000 * 10); // 10 seconds

        // Shouldn't do anything during endDelay
        lastCallCount = test.animation.goToTime.callCount;
        clock.tick(1000);
        expect(test.animation.goToTime.callCount).toEqual(lastCallCount);

        // After endDelay, should go back to the start
        clock.tick(1000);
        expect(test.animation.goToTime).toHaveBeenCalledWith(options.from.getTime());

        // Should continue animating
        clock.tick(1000);
        expect(test.animation.goToTime.callCount).toBeGreaterThan(5);
      });

      it('should not create duplicate animations', function() {
        var options = {
          from: new Date(0),
          to: new Date(5000),
          endDelay: 100,
          timestep: 1000,
          speed: 1
        };
        var test = new TestFactory(options);
        var callsPerSecond;
        var seconds = 0;

        function checkCallCount() {
          expect(test.animation.goToTime.callCount).toBeNear(callsPerSecond * seconds, 1);
        }

        function tickSeconds(s) {
          clock.tick(1000 * s);
          seconds += s;
        }

        test.animation.start();

        // Get a baseline expectation for number of calls per second.
        tickSeconds(1);
        callsPerSecond = test.animation.goToTime.callCount;

        test.animation.start();

        tickSeconds(1);
        checkCallCount();
      });

    });

    describe('pause', function() {

      it('should stop animating', function() {
        var test = new TestFactory();
        var lastCallCount;

        test.animation.start();

        clock.tick(500);
        expect(test.animation.goToTime).toHaveBeenCalled();
        lastCallCount = test.animation.goToTime.callCount;

        test.animation.pause();
        clock.tick(500);
        expect(test.animation.goToTime.callCount).toEqual(lastCallCount);
      });

    });

    describe('stop', function() {

      it('should call pause', function() {
        var test = new TestFactory();
        test.animation.start();

        test.animation.stop();
        expect(test.animation.pause).toHaveBeenCalled();
      });

      it('should go to the most recent time', function() {
        var options = {
          to: new Date(500)
        };
        var test = new TestFactory(options);

        test.animation.start();

        test.animation.stop();
        expect(test.animation.goToTime).toHaveBeenCalledWith(options.to.getTime());
      });

    });

    describe('setSpeed', function() {
      var SPEED_ORIG = 1;
      var animation;

      beforeEach(function() {
        animation = new TestFactory({
          timestep: 100,
          speed: SPEED_ORIG,
          to: new Date(9999999999999999),
          from: new Date(0)
        }).animation;
      });

      it('should change the animation speed', function() {
        function getLastTime() {
          return animation.goToTime.mostRecentCall.args[0];
        }

        animation.start();

        clock.tick(1000);
        expect(getLastTime()).toEqual(100);

        animation.setSpeed(2);
        clock.tick(1000);
        expect(getLastTime()).toEqual(300);

        animation.setSpeed(0.5);
        clock.tick(1000);
        expect(getLastTime()).toEqual(350);

        animation.setSpeed(-1);
        clock.tick(1000);
        expect(getLastTime()).toEqual(250);
      });

      it('should reject invalid numbers', function() {
        expect(animation.setSpeed.bind(animation, 'foo')).toThrowType('InvalidArgumentError');
      });

      describe('if the speed has changed', function() {

        describe('if the animating is currently playing', function() {

          beforeEach(function() {
            animation.start();
          });

          it('should restart the animation', function() {
            animation.setSpeed(SPEED_ORIG + 100);

            expect(animation).toHaveBeenRestarted();
          });

        });

        describe('if the animation is not currently playing', function() {

          it('should not restart the animation', function() {
            animation.setSpeed(SPEED_ORIG + 100);

            expect(animation).not.toHaveBeenRestarted();
          });

        });

      });

      describe('if the speed has not changed', function() {

        describe('if the animation is playing', function() {

          it('should not restart the animation', function() {
            animation.start();
            animation.setSpeed(SPEED_ORIG);

            expect(animation).not.toHaveBeenRestarted();
          });

        });

        describe('if the animation is not playing', function() {

          it('should not restart the animation', function() {
            expect(animation).not.toHaveBeenRestarted();
          });

        });

      });

    });

    describe('setTimestep', function() {
      var SPEED_ORIG = 1, TIMESTEP_ORIG = 100;
      var animation;

      beforeEach(function() {
        animation = new TestFactory({
          timestep: TIMESTEP_ORIG,
          speed: SPEED_ORIG,
          to: new Date(9999999999999999),
          from: new Date(0)
        }).animation;
      });

      it('should change the animation timestep', function() {
        function getLastTime() {
          return animation.goToTime.mostRecentCall.args[0];
        }

        animation.start();

        clock.tick(1000);
        expect(getLastTime()).toEqual(100);

        animation.setTimestep(200);
        clock.tick(1000);
        expect(getLastTime()).toEqual(300);

        animation.setTimestep(50);
        clock.tick(1000);
        expect(getLastTime()).toEqual(350);

        animation.setTimestep(-100);
        clock.tick(1000);
        expect(getLastTime()).toEqual(250);
      });

      describe('when the animation is playing', function() {

        beforeEach(function() {
          animation.start();
        });

        describe('if a different timestep is set', function() {

          it('should restart the animation', function() {
            animation.setTimestep(TIMESTEP_ORIG + 100);

            expect(animation).toHaveBeenRestarted();
          });

        });

        describe('if the same timestep is set', function() {

          it('should not restart the animation', function() {
            animation.setTimestep(TIMESTEP_ORIG);

            expect(animation).not.toHaveBeenRestarted();
          });

        });

      });

      describe('when the animation is not playing', function() {

        describe('if a different timestep is set', function() {

          it('should not restart the animation', function() {
            animation.setTimestep(TIMESTEP_ORIG + 100);

            expect(animation).not.toHaveBeenRestarted();
          });

        });

        describe('if the same timestep is set', function() {

          it('should not restart the animation', function() {
            animation.setTimestep(TIMESTEP_ORIG);

            expect(animation).not.toHaveBeenRestarted();
          });

        });

      });

    });

    describe('isAnimating', function() {

      beforeEach(function() {
        this.addMatchers({
          toBeAnimating: function() {
            return this.actual.isAnimating();
          }
        });
      });

      it('should tell us when it\'s animating', function() {
        var test = new TestFactory();

        expect(test.animation).not.toBeAnimating();

        test.animation.start();
        expect(test.animation).toBeAnimating();

        test.animation.pause();
        expect(test.animation).not.toBeAnimating();
      });

    });

    describe('setFrom', function() {
      var timestamp, animation;

      beforeEach(function() {
        animation = new Animation();
        timestamp = Math.round(Math.random() * 100);
      });

      it('should accept a timestamp', function() {
        animation.setFrom(timestamp);

        expect(animation.getFrom().getTime()).toEqual(timestamp);
      });

      it('should accept a date', function() {
        animation.setFrom(new Date(timestamp));

        expect(animation.getFrom().getTime()).toEqual(timestamp);
      });

      it('should trigger a \'change:from\' event', function() {
        var onChangeFrom = jasmine.createSpy('onChangeFrom');
        animation.on('change:from', onChangeFrom);

        animation.setFrom(timestamp);

        expect(onChangeFrom).toHaveBeenCalled();
        expect(onChangeFrom.mostRecentCall.args[0].getTime()).toEqual(timestamp);
      });

      it('should not trigger a \'change:from\' event when setting the same time', function() {
        var onChangeFrom = jasmine.createSpy('onChangeFrom');
        animation.on('change:from', onChangeFrom);

        animation.setFrom(timestamp);
        animation.setFrom(timestamp);

        expect(onChangeFrom.callCount).toEqual(1);
      });

      describe('if new `from` time is later than current time', function() {

        it('should go to the new `from` time', function() {
          animation.goToTime(100);
          spyOn(animation, 'goToTime').andCallThrough();

          animation.setFrom(200);

          expect(animation.goToTime).toHaveBeenCalledWith(new Date(200));
          expect(animation.getCurrentTime().getTime()).toEqual(200);
        });

      });

    });

    describe('setTo', function() {
      var timestamp, animation;

      beforeEach(function() {
        animation = new Animation();
        timestamp = Math.round(Math.random() * 100);
      });

      it('should accept a timestamp', function() {
        animation.setTo(timestamp);

        expect(animation.getTo().getTime()).toEqual(timestamp);
      });

      it('should accept a date', function() {
        animation.setTo(new Date(timestamp));

        expect(animation.getTo().getTime()).toEqual(timestamp);
      });

      it('should trigger a \'change:to\' event', function() {
        var onChangeTo = jasmine.createSpy('onChangeTo');
        animation.on('change:to', onChangeTo);

        animation.setTo(timestamp);

        expect(onChangeTo).toHaveBeenCalled();
        expect(onChangeTo.mostRecentCall.args[0].getTime()).toEqual(timestamp);
      });

      it('should not trigger a \'change:to\' event when setting the same time', function() {
        var onChangeTo = jasmine.createSpy('onChangeTo');
        animation.on('change:to', onChangeTo);

        animation.setTo(timestamp);
        animation.setTo(timestamp);

        expect(onChangeTo.callCount).toEqual(1);
      });

      describe('if new `to` time is earlier than current time', function() {

        it('should go to the new `to` time', function() {
          animation.goToTime(200);
          spyOn(animation, 'goToTime').andCallThrough();

          animation.setTo(100);

          expect(animation.goToTime).toHaveBeenCalledWith(new Date(100));
          expect(animation.getCurrentTime().getTime()).toEqual(100);
        });

      });

    });

  });
});


text:
define(
//begin v1.x content
{
	"BRE_displayName": "cruzeiro brasiler (1990-1993)",
	"DEM_displayName": "marc alemany",
	"CUP_displayName": "peso cubà",
	"PYG_displayName": "guaraní paraguaià",
	"CLE_displayName": "escut xilè",
	"MDC_displayName": "cupó moldau",
	"MDL_displayName": "leu moldau",
	"DOP_displayName": "peso dominicà",
	"NGN_displayName": "naira nigerià",
	"KZT_displayName": "tenge kazakh",
	"MXV_displayName": "unidad de inversión (UDI) mexicana",
	"LTT_displayName": "talonas lituà",
	"LAK_displayName": "kip laosià",
	"LKR_displayName": "rupia de Sri Lanka",
	"AOR_displayName": "kwanza angolès reajustat (1995-1999)",
	"XEU_displayName": "unitat de moneda europea",
	"XOF_symbol": "XOF",
	"USS_displayName": "dòlar dels Estats Units (mateix dia)",
	"MNT_displayName": "tögrög mongol",
	"RHD_displayName": "dòlar rhodesià",
	"MOP_displayName": "pataca de Macau",
	"TJR_displayName": "ruble tadjik",
	"LUC_displayName": "franc convertible luxemburguès",
	"LUL_displayName": "franc financer luxemburguès",
	"AON_displayName": "nou kwanza angolès (1990-2000)",
	"TWD_symbol": "NT$",
	"BEF_displayName": "franc belga",
	"GHS_displayName": "cedi ghanès",
	"IEP_displayName": "lliura irlandesa",
	"SBD_displayName": "dòlar de les illes Salomó",
	"KRO_displayName": "antic won sud-coreà",
	"GRD_displayName": "dracma grega",
	"NIC_displayName": "córdoba nicaragüenca",
	"AZM_displayName": "manat azerbaidjanès (1993-2006)",
	"CNY_symbol": "¥",
	"MTP_displayName": "lliura maltesa",
	"MKN_displayName": "denar macedoni (1992-1993)",
	"LVR_displayName": "ruble letó",
	"GNF_displayName": "franc guineà",
	"GIP_displayName": "lliura de Gibraltar",
	"SRG_displayName": "florí de Surinam",
	"BAD_displayName": "dinar de Bòsnia i Hercegovina (1992-1994)",
	"FJD_displayName": "dòlar fijià",
	"BAM_displayName": "marc convertible de Bòsnia i Hercegovina",
	"XBB_displayName": "unitat monetària europea",
	"CDF_displayName": "franc congolès",
	"HRD_displayName": "dinar croat",
	"BZD_displayName": "dòlar de Belize",
	"MLF_displayName": "franc malià",
	"EGP_displayName": "lliura egípcia",
	"MVR_displayName": "rupia de les Maldives",
	"BAN_displayName": "nou dinar de Bòsnia i Hercegovina (1994-1997)",
	"TRY_displayName": "lira turca",
	"ILR_displayName": "xéquel israelià",
	"SDP_displayName": "antiga lliura sudanesa",
	"XRE_displayName": "fons RINET",
	"ARM_displayName": "peso argentí (1981-1970)",
	"NPR_displayName": "rupia nepalesa",
	"PHP_displayName": "peso filipí",
	"WST_displayName": "tala samoà",
	"TRL_displayName": "lira turca (1922-2005)",
	"JPY_displayName": "ien japonès",
	"TMM_displayName": "manat turcman (1993-2009)",
	"BGN_displayName": "lev búlgar",
	"KYD_displayName": "dòlar de les illes Caiman",
	"VUV_displayName": "vatu de Vanuatu",
	"IRR_displayName": "rial iranià",
	"DJF_displayName": "franc de Djibouti",
	"XDR_displayName": "drets especials de gir",
	"ECS_displayName": "sucre equatorià",
	"HKD_symbol": "HK$",
	"NLG_displayName": "florí neerlandès",
	"ISJ_displayName": "corona islandesa antiga",
	"MWK_displayName": "kwacha malawià",
	"HTG_displayName": "gourde haitià",
	"PES_displayName": "sol peruà",
	"LYD_displayName": "dinar libi",
	"BRR_displayName": "cruzeiro brasiler",
	"XXX_displayName": "moneda desconeguda/no vàlida",
	"IDR_displayName": "rupia indonèsia",
	"USD_displayName": "dòlar dels Estats Units",
	"KGS_displayName": "som kirguís",
	"BRN_displayName": "cruzado novo brasiler",
	"CHF_displayName": "franc suís",
	"ISK_displayName": "corona islandesa",
	"LUF_displayName": "franc luxemburguès",
	"MXN_symbol": "MXN",
	"SVC_displayName": "colón salvadorenc",
	"ZMK_displayName": "kwacha zambià (1968-2012)",
	"ZWR_displayName": "dòlar zimbabuès (2008)",
	"TOP_displayName": "pa'anga tongà",
	"ITL_displayName": "lira italiana",
	"USN_displayName": "dòlar dels Estats Units (dia següent)",
	"VND_symbol": "₫",
	"KWD_displayName": "dinar kuwaitià",
	"NIO_displayName": "córdoba oro nicaragüenca",
	"KMF_displayName": "franc de les Comores",
	"UYI_displayName": "peso uruguaià en unitats indexades",
	"MYR_displayName": "ringgit de Malàisia",
	"XFU_displayName": "franc UIC francès",
	"GMD_displayName": "dalasi gambià",
	"LVL_displayName": "lats letó",
	"AUD_displayName": "dòlar australià",
	"XPF_displayName": "franc CFP",
	"LBP_displayName": "lliura libanesa",
	"ALK_displayName": "lek albanès (1946-1965)",
	"BYB_displayName": "nou ruble bielorús (1994-1999)",
	"MKD_displayName": "denar macedoni",
	"GWP_displayName": "peso de Guinea Bissau",
	"CNY_displayName": "iuan renmimbi xinès",
	"MAF_displayName": "franc marroquí",
	"JOD_displayName": "dinar jordà",
	"OMR_displayName": "rial omanita",
	"BOV_displayName": "MVDOL bolivià",
	"XPT_displayName": "platí",
	"AUD_symbol": "AU$",
	"NOK_displayName": "corona noruega",
	"SCR_displayName": "rupia de les Seychelles",
	"XBA_displayName": "unitat compensatòria europea",
	"CSK_displayName": "corona forta txecoslovaca",
	"PLZ_displayName": "zloty polonès (1950-1995)",
	"UAK_displayName": "karbóvanets ucraïnès",
	"MGF_displayName": "franc malgaix",
	"GNS_displayName": "syli guineà",
	"YUN_displayName": "dinar convertible iugoslau",
	"GYD_displayName": "dòlar de Guyana",
	"QAR_displayName": "riyal de Qatar",
	"ALL_displayName": "lek albanès",
	"BBD_displayName": "dòlar de Barbados",
	"ESP_pattern": "¤ #,##0.00",
	"RON_displayName": "leu romanès",
	"XCD_symbol": "XCD",
	"AMD_displayName": "dram armeni",
	"ARL_displayName": "peso ley argentí (1970-1983)",
	"CYP_displayName": "lliura xipriota",
	"GBP_symbol": "£",
	"SEK_displayName": "corona sueca",
	"MMK_displayName": "kyat de Myanmar",
	"ZAR_displayName": "rand sud-africà",
	"ECV_displayName": "unidad de valor constante (UVC) equatoriana",
	"BGM_displayName": "lev socialista búlgar",
	"AWG_displayName": "florí d'Aruba",
	"STD_displayName": "dobra de São Tomé i Príncipe",
	"CAD_displayName": "dòlar canadenc",
	"ADP_displayName": "pesseta andorrana",
	"MRO_displayName": "ouguiya maurità",
	"ESB_displayName": "pesseta espanyola (compte convertible)",
	"LSL_displayName": "loti de Lesotho",
	"TND_displayName": "dinar tunisià",
	"USD_symbol": "US$",
	"BRC_displayName": "cruzado brasiler",
	"BMD_displayName": "dòlar de les Bermudes",
	"BRL_displayName": "real brasiler",
	"JMD_displayName": "dòlar jamaicà",
	"SOS_displayName": "xíling somali",
	"SAR_displayName": "riyal saudita",
	"PEI_displayName": "inti peruà",
	"ESP_displayName": "pesseta espanyola",
	"HKD_displayName": "dòlar de Hong Kong",
	"ESP_symbol": "₧",
	"BWP_displayName": "pula de Botswana",
	"TTD_displayName": "dòlar de Trinitat i Tobago",
	"BRZ_displayName": "antic cruzeiro brasiler",
	"BSD_displayName": "dòlar de les Bahames",
	"BIF_displayName": "franc de Burundi",
	"FRF_displayName": "franc francès",
	"DKK_displayName": "corona danesa",
	"AED_displayName": "dirhem dels Emirats Àrabs Units",
	"AOK_displayName": "kwanza angolès (1977-1991)",
	"ATS_displayName": "xíling austríac",
	"PEN_displayName": "nou sol peruà",
	"CRC_displayName": "colón costa-riqueny",
	"ESP_decimal": ",",
	"PAB_displayName": "balboa panameny",
	"CHE_displayName": "euro WIR",
	"GQE_displayName": "ekwele de Guinea Equatorial",
	"DZD_displayName": "dinar algerià",
	"EEK_displayName": "corona estoniana",
	"YDD_displayName": "dinar iemenita",
	"GHC_displayName": "cedi ghanès (1979-2007)",
	"MXP_displayName": "peso de plata mexicà (1861-1992)",
	"XPD_displayName": "pal·ladi",
	"KRH_displayName": "hwan sud-coreà (1953-1962)",
	"XAG_displayName": "plata",
	"AFN_displayName": "afgani afganès",
	"XFO_displayName": "franc or francès",
	"GWE_displayName": "escut de la Guinea Portuguesa",
	"BOB_displayName": "boliviano bolivià",
	"CAD_symbol": "CA$",
	"VND_displayName": "dong vietnamita",
	"AFA_displayName": "afgani afganès (1927-2002)",
	"ZWD_displayName": "dòlar zimbabuès (1980-2008)",
	"JPY_symbol": "JP¥",
	"SRD_displayName": "dòlar de Surinam",
	"ZRN_displayName": "nou zaire zairès",
	"XAU_displayName": "or",
	"KRW_symbol": "₩",
	"BOP_displayName": "peso bolivià",
	"XBD_displayName": "unitat de compte europea (XBD)",
	"TZS_displayName": "xíling tanzà",
	"BOL_displayName": "boliviano bolivià (1863-1963)",
	"XPF_symbol": "XPF",
	"ROL_displayName": "antic leu romanès",
	"VNN_displayName": "dong vietnamita (1978-1985)",
	"LRD_displayName": "dòlar liberià",
	"KRW_displayName": "won sud-coreà",
	"SHP_displayName": "lliura de Santa Helena",
	"MZE_displayName": "escut moçambiquès",
	"MZN_displayName": "metical moçambiquès",
	"SDD_displayName": "dinar sudanès",
	"HRK_displayName": "kuna croata",
	"FKP_displayName": "lliura de les illes Malvines",
	"COP_displayName": "peso colombià",
	"YUD_displayName": "dinar fort iugoslau",
	"YUM_displayName": "nou dinar iugoslau",
	"THB_displayName": "baht tailandès",
	"UZS_displayName": "som uzbek",
	"MGA_displayName": "ariary malgaix",
	"COU_displayName": "unidad de valor real colombiana",
	"TWD_displayName": "nou dòlar de Taiwan",
	"UGS_displayName": "xíling ugandès (1966-1987)",
	"YUR_displayName": "dinar iugoslau reformat (1992-1993)",
	"ZAL_displayName": "rand sud-africà (financer)",
	"GEL_displayName": "lari georgià",
	"ILP_displayName": "lliura israeliana",
	"DDM_displayName": "marc de l'Alemanya Oriental",
	"KES_displayName": "xíling kenyà",
	"CUC_displayName": "peso convertible cubà",
	"CZK_displayName": "corona txeca",
	"UGX_displayName": "xíling ugandès",
	"ILS_symbol": "₪",
	"TMT_displayName": "manat turcman",
	"THB_symbol": "฿",
	"BGL_displayName": "lev fort búlgar",
	"ARP_displayName": "peso argentí (1983-1985)",
	"RUR_displayName": "ruble rus (1991-1998)",
	"ERN_displayName": "nakfa eritreu",
	"ESA_displayName": "pesseta espanyola (compte A)",
	"CLF_displayName": "unidad de fomento xilena",
	"BRB_displayName": "cruzeiro novo brasiler (1967-1986)",
	"BHD_displayName": "dinar de Bahrain",
	"SYP_displayName": "lliura síria",
	"SZL_displayName": "lilangeni swazi",
	"INR_displayName": "rupia índia",
	"PTE_displayName": "escut portuguès",
	"KPW_displayName": "won nord-coreà",
	"XOF_displayName": "franc CFA BCEAO",
	"MXN_displayName": "peso mexicà",
	"RWF_displayName": "franc rwandès",
	"ETB_displayName": "birr etíop",
	"LTL_displayName": "litas lituà",
	"BND_displayName": "dòlar de Brunei",
	"SUR_displayName": "ruble soviètic",
	"SKK_displayName": "corona eslovaca",
	"AOA_displayName": "kwanza angolès",
	"CVE_displayName": "escut de Cap Verd",
	"BRL_symbol": "BRL",
	"XTS_displayName": "codi reservat per a proves",
	"CLP_displayName": "peso xilè",
	"HUF_displayName": "fòrint hongarès",
	"TJS_displayName": "somoni tadjik",
	"GBP_displayName": "lliura esterlina britànica",
	"TPE_displayName": "escut de Timor",
	"BDT_displayName": "taka de Bangla Desh",
	"SGD_displayName": "dòlar de Singapur",
	"SLL_displayName": "leone de Sierra Leone",
	"XAF_displayName": "franc CFA BEAC",
	"MTL_displayName": "lira maltesa",
	"KHR_displayName": "riel cambodjà",
	"ZRZ_displayName": "zaire zairès",
	"RSD_displayName": "dinar serbi",
	"BEC_displayName": "franc belga (convertible)",
	"BEL_displayName": "franc belga (financer)",
	"AZN_displayName": "manat azerbaidjanès",
	"FIM_displayName": "marc finlandès",
	"ZWL_displayName": "dòlar zimbabuès (2009)",
	"PKR_displayName": "rupia pakistanesa",
	"UYP_displayName": "peso uruguaià (1975-1993)",
	"CHW_displayName": "franc WIR",
	"ZMW_displayName": "kwacha zambià",
	"XAF_symbol": "XAF",
	"PLN_displayName": "zloty polonès",
	"UAH_displayName": "hrívnia ucraïnesa",
	"BTN_displayName": "ngultrum de Bhutan",
	"YER_displayName": "rial iemenita",
	"UYU_displayName": "peso uruguaià",
	"CSD_displayName": "dinar serbi antic",
	"VEF_displayName": "bolívar veneçolà",
	"PGK_displayName": "kina de Papua Nova Guinea",
	"XBC_displayName": "unitat de compte europea (XBC)",
	"EUR_displayName": "euro",
	"MUR_displayName": "rupia de Maurici",
	"MAD_displayName": "dírham marroquí",
	"SDG_displayName": "lliura sudanesa",
	"BYR_displayName": "ruble bielorús",
	"VEB_displayName": "bolívar veneçolà (1871-2008)",
	"IQD_displayName": "dinar iraquià",
	"MZM_displayName": "antic metical moçambiquès",
	"NZD_symbol": "NZ$",
	"SIT_displayName": "tolar eslovè",
	"XCD_displayName": "dòlar del Carib Oriental",
	"RUB_displayName": "ruble rus",
	"BUK_displayName": "kyat birmà",
	"ILS_displayName": "nou xéquel israelià",
	"INR_symbol": "₹",
	"NAD_displayName": "dòlar namibià",
	"ESP_group": ".",
	"HNL_displayName": "lempira hondurenya",
	"GTQ_displayName": "quetzal guatemalenc",
	"MCF_displayName": "franc monegasc",
	"GEK_displayName": "cupó de lari georgià",
	"EUR_symbol": "€",
	"NZD_displayName": "dòlar neozelandès",
	"BGO_displayName": "lev búlgar (1879-1952)",
	"ARA_displayName": "austral argentí",
	"ARS_displayName": "peso argentí",
	"ANG_displayName": "florí de les Antilles Neerlandeses"
}
//end v1.x content
);


text:
/*
 * Twitter API definition.
 *
 * This script defines API objects to "Twitter.API".
 * A piece of API object means "API method" and It has properties listed below.
 *
 *   name : API method name. (like 'statuses/public_timeline')
 *   description: Description of this method.
 *   url: Method URL. (The format(or id) has not been applied yet.)
 *   formats: Array of acceptable formats. ('xml', 'json', etc)
 *   method: HTTP method for this API method.
 *   auth: Requires Authentication or not.
 *   params: Available parameters.
 *   oparams: Additional OAuth parameters. (OAuth API only.)
 *   detectError: Function to validate parameters. If it detects error, returns error infomation object.
 *
 * For API details, please refer to Twitter API Documentation. ( http://apiwiki.twitter.com/Twitter-API-Documentation )
 */
var Twitter;
if (typeof Twitter     == 'undefined') Twitter = {};
if (typeof Twitter.API == 'undefined') Twitter.API = {};

(function() {

var API = [
    //Favorite Methods.
    {
        name: 'favorites/list',
        description: 'Returns the 20 most recent Tweets favorited by the authenticating or specified user. ',
        url: 'https://api.twitter.com/1.1/favorites/list.json',
        method: 'GET',
        auth: true,
        params: {
            'user_id': null,
            'screen_name': null,
            'count': null,
            'since_id': null,
            'max_id': null,
            'include_entities': null
        }
    },
    {
        name: 'favorites/destroy',
        description: 'Un-favorites the status specified in the ID parameter as the authenticating user. Returns the un-favorited status in the requested format when successful. ',
        url: 'https://api.twitter.com/1.1/favorites/destroy.json',
        method: 'POST',
        auth: true,
        params: {
            'id': null,
            'include_entities': null
        },
        detectError: function() {
            this.error = null;
            if (!this.params.id) {
                return this.error = { 'id': { 'type': 'required' } };
            }
        }
    },
    {
        name: 'favorites/create',
        description: 'Favorites the status specified in the ID parameter as the authenticating user. Returns the favorite status when successful. ',
        url: 'https://api.twitter.com/1.1/favorites/create.json',
        method: 'POST',
        auth: true,
        params: {
            'id': null,
            'include_entities': null
        },
        detectError: function() {
            this.error = null;
            if (!this.params.id) {
                return this.error = { 'id': { 'type': 'required' } };
            }
        }
    }
];

for (var i = 0; i < API.length; i++) {
    var api = API[i];
    Twitter.API[api.name] = api;
}

//utils
function bover(str, len) {
    var b = 0;
    for(var i = 0, len = str.length; i < len; ++i) {
        ++b; if (str.charCodeAt(i) >= 128) ++b;
        if (b > len) return true;
    }
    return false;
}

})();


text:
require 'spec_helper'

module Morpheus
  module Adapters
    describe Solr do
    end
  end
end


text:
SUBDIR= misc store

.include <bsd.subdir.mk>


text:
"""
Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""

import os

from lib.core.common import randomInt
from lib.core.data import kb
from lib.core.data import logger
from lib.core.exception import SqlmapUnsupportedFeatureException
from lib.request import inject
from plugins.generic.filesystem import Filesystem as GenericFilesystem

class Filesystem(GenericFilesystem):
    def __init__(self):
        self.oid = None

        GenericFilesystem.__init__(self)

    def stackedReadFile(self, rFile):
        infoMsg = "fetching file: '%s'" % rFile
        logger.info(infoMsg)

        self.initEnv()

        return self.udfEvalCmd(cmd=rFile, udfName="sys_fileread")

    def unionWriteFile(self, wFile, dFile, fileType, forceCheck=False):
        errMsg = "PostgreSQL does not support file upload with UNION "
        errMsg += "query SQL injection technique"
        raise SqlmapUnsupportedFeatureException(errMsg)

    def stackedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
        wFileSize = os.path.getsize(wFile)

        if wFileSize > 8192:
            errMsg = "on PostgreSQL it is not possible to write files "
            errMsg += "bigger than 8192 bytes at the moment"
            raise SqlmapUnsupportedFeatureException(errMsg)

        self.oid = randomInt()

        debugMsg = "creating a support table to write the base64 "
        debugMsg += "encoded file to"
        logger.debug(debugMsg)

        self.createSupportTbl(self.fileTblName, self.tblField, "text")

        logger.debug("encoding file to its base64 string value")
        fcEncodedList = self.fileEncode(wFile, "base64", False)

        debugMsg = "forging SQL statements to write the base64 "
        debugMsg += "encoded file to the support table"
        logger.debug(debugMsg)

        sqlQueries = self.fileToSqlQueries(fcEncodedList)

        logger.debug("inserting the base64 encoded file to the support table")

        for sqlQuery in sqlQueries:
            inject.goStacked(sqlQuery)

        debugMsg = "create a new OID for a large object, it implicitly "
        debugMsg += "adds an entry in the large objects system table"
        logger.debug(debugMsg)

        # References:
        # http://www.postgresql.org/docs/8.3/interactive/largeobjects.html
        # http://www.postgresql.org/docs/8.3/interactive/lo-funcs.html
        inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
        inject.goStacked("SELECT lo_create(%d)" % self.oid)

        debugMsg = "updating the system large objects table assigning to "
        debugMsg += "the just created OID the binary (base64 decoded) UDF "
        debugMsg += "as data"
        logger.debug(debugMsg)

        # Refereces:
        # * http://www.postgresql.org/docs/8.3/interactive/catalog-pg-largeobject.html
        # * http://lab.lonerunners.net/blog/sqli-writing-files-to-disk-under-postgresql
        #
        # NOTE: From PostgreSQL site:
        #
        #   "The data stored in the large object will never be more than
        #   LOBLKSIZE bytes and might be less which is BLCKSZ/4, or
        #   typically 2 Kb"
        #
        # As a matter of facts it was possible to store correctly a file
        # large 13776 bytes, the problem arises at next step (lo_export())
        #
        # Inject manually into PostgreSQL system table pg_largeobject the
        # base64-decoded file content. Note that PostgreSQL >= 9.0 does
        # not accept UPDATE into that table for some reason.
        self.getVersionFromBanner()
        banVer = kb.bannerFp["dbmsVersion"]

        if banVer >= "9.0":
            inject.goStacked("INSERT INTO pg_largeobject VALUES (%d, 0, DECODE((SELECT %s FROM %s), 'base64'))" % (self.oid, self.tblField, self.fileTblName))
        else:
            inject.goStacked("UPDATE pg_largeobject SET data=(DECODE((SELECT %s FROM %s), 'base64')) WHERE loid=%d" % (self.tblField, self.fileTblName, self.oid))

        debugMsg = "exporting the OID %s file content to " % fileType
        debugMsg += "file '%s'" % dFile
        logger.debug(debugMsg)

        # NOTE: lo_export() exports up to only 8192 bytes of the file
        # (pg_largeobject 'data' field)
        inject.goStacked("SELECT lo_export(%d, '%s')" % (self.oid, dFile), silent=True)

        written = self.askCheckWrittenFile(wFile, dFile, forceCheck)

        inject.goStacked("SELECT lo_unlink(%d)" % self.oid)

        return written


text:
class RailsAdminBase::UploadFile < ActiveRecord::Base
  self.table_name = "upload_files"
  DESTINATION_DIRECTORY = Rails.root.join("public","upload_files")

  before_destroy :delete_stored_file

  def file_url
   "/#{file_path.split("/").drop_while{|path| path != "public"}.last(2).join("/")}"
  end

  def store_file(params_file)
    FileUtils.mkdir_p(DESTINATION_DIRECTORY) unless FileTest::directory?(DESTINATION_DIRECTORY)
    #time_stamp = Time.now.strftime("%Y%m%d%H%M%S") + Time.now.usec.to_s
    #path = DESTINATION_DIRECTORY.join("#{data_file_name}_#{time_stamp}")
    path = DESTINATION_DIRECTORY.join("#{data_file_name}")
    File.open(path, "wb") do |f|
      f.write(params_file.read)
    end
    self.file_path = path
  end

  private
  def delete_stored_file
    File.delete(file_path)
  end
end


text:
'use strict';

var
  yargs,
  libDinghy,
  argv,
  cmd;

yargs = require('yargs');

libDinghy = require('../lib/dinghy');

argv = yargs.usage('dh soe <command>')
  .command('start', 'Start the Docker host', function (yargs) {
    libDinghy.start();
  })
  .command('stop', 'Stop the host', function (yargs) {
    libDinghy.stop();
  })
  .command('restart', 'Restart the host', function (yargs) {
    libDinghy.restart();
  })
  .command('status', 'Show host status', function (yargs) {
    libDinghy.status();
  })
  .option('d', {
    alias: 'debug',
    description: 'Display debug messages.'
  })
  .demand(1, '')
  .check(function (argv, opts) {
    if (!argv._[0].match(/start|stop|restart|status/)) {
      throw new Error('please provide a valid command');
    }
  })
  .help('h')
  .alias('h', 'help')
  .argv;


text:
package sflow

import (
	"errors"
	"net"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"

	"github.com/redhat-cip/skydive/analyzer"
	"github.com/redhat-cip/skydive/config"
	"github.com/redhat-cip/skydive/flow"
	"github.com/redhat-cip/skydive/flow/mappings"
	"github.com/redhat-cip/skydive/logging"
)

const (
	maxDgramSize = 1500
)

var (
	AgentAlreadyAllocated error = errors.New("agent already allocated for this uuid")
)

type SFlowAgent struct {
	UUID                string
	Addr                string
	Port                int
	AnalyzerClient      *analyzer.Client
	flowTable           *flow.Table
	FlowMappingPipeline *mappings.FlowMappingPipeline
	FlowProbePathSetter flow.FlowProbePathSetter
	running             atomic.Value
	wg                  sync.WaitGroup
	flush               chan bool
	flushDone           chan bool
}

type SFlowAgentAllocator struct {
	sync.RWMutex
	AnalyzerClient      *analyzer.Client
	FlowMappingPipeline *mappings.FlowMappingPipeline
	FlowProbePathSetter flow.FlowProbePathSetter
	Addr                string
	MinPort             int
	MaxPort             int
	allocated           map[int]*SFlowAgent
}

func (sfa *SFlowAgent) GetTarget() string {
	target := []string{sfa.Addr, strconv.FormatInt(int64(sfa.Port), 10)}
	return strings.Join(target, ":")
}

func (sfa *SFlowAgent) feedFlowTable(conn *net.UDPConn) {
	var buf [maxDgramSize]byte
	_, _, err := conn.ReadFromUDP(buf[:])
	if err != nil {
		conn.SetDeadline(time.Now().Add(1 * time.Second))
		return
	}

	p := gopacket.NewPacket(buf[:], layers.LayerTypeSFlow, gopacket.Default)
	sflowLayer := p.Layer(layers.LayerTypeSFlow)
	sflowPacket, ok := sflowLayer.(*layers.SFlowDatagram)
	if !ok {
		return
	}

	if sflowPacket.SampleCount > 0 {
		for _, sample := range sflowPacket.FlowSamples {
			flows := flow.FlowsFromSFlowSample(sfa.flowTable, &sample, sfa.FlowProbePathSetter)
			logging.GetLogger().Debugf("%d flows captured", len(flows))
		}
	}
}

func (sfa *SFlowAgent) asyncFlowPipeline(flows []*flow.Flow) {
	if sfa.FlowMappingPipeline != nil {
		sfa.FlowMappingPipeline.Enhance(flows)
	}
	if sfa.AnalyzerClient != nil {
		sfa.AnalyzerClient.SendFlows(flows)
	}
}

func (sfa *SFlowAgent) start() error {
	addr := net.UDPAddr{
		Port: sfa.Port,
		IP:   net.ParseIP(sfa.Addr),
	}
	conn, err := net.ListenUDP("udp", &addr)
	if err != nil {
		logging.GetLogger().Errorf("Unable to listen on port %d: %s", sfa.Port, err.Error())
		return err
	}
	defer conn.Close()
	conn.SetDeadline(time.Now().Add(1 * time.Second))

	sfa.wg.Add(1)
	defer sfa.wg.Done()

	sfa.running.Store(true)

	sfa.flowTable = flow.NewTable()
	defer sfa.flowTable.UnregisterAll()

	cfgFlowtable_expire := config.GetConfig().GetInt("agent.flowtable_expire")
	sfa.flowTable.RegisterExpire(sfa.asyncFlowPipeline, time.Duration(cfgFlowtable_expire)*time.Second)

	cfgFlowtable_update := config.GetConfig().GetInt("agent.flowtable_update")
	sfa.flowTable.RegisterUpdated(sfa.asyncFlowPipeline, time.Duration(cfgFlowtable_update)*time.Second)

	for sfa.running.Load() == true {
		select {
		case now := <-sfa.flowTable.GetExpireTicker():
			sfa.flowTable.Expire(now)
		case now := <-sfa.flowTable.GetUpdatedTicker():
			sfa.flowTable.Updated(now)
		case <-sfa.flush:
			sfa.flowTable.ExpireNow()
			sfa.flushDone <- true
		default:
			sfa.feedFlowTable(conn)
		}
	}

	return nil
}

func (sfa *SFlowAgent) Start() {
	go sfa.start()
}

func (sfa *SFlowAgent) Stop() {
	if sfa.running.Load() == true {
		sfa.running.Store(false)
		sfa.wg.Wait()
	}
}

func (sfa *SFlowAgent) Flush() {
	logging.GetLogger().Critical("Flush() MUST be called for testing purpose only, not in production")
	sfa.flush <- true
	<-sfa.flushDone
}

func (sfa *SFlowAgent) SetFlowProbePathSetter(p flow.FlowProbePathSetter) {
	sfa.FlowProbePathSetter = p
}

func NewSFlowAgent(u string, a string, p int, c *analyzer.Client, m *mappings.FlowMappingPipeline) *SFlowAgent {
	return &SFlowAgent{
		UUID:                u,
		Addr:                a,
		Port:                p,
		AnalyzerClient:      c,
		FlowMappingPipeline: m,
		flush:               make(chan bool),
		flushDone:           make(chan bool),
	}
}

func NewSFlowAgentFromConfig(u string, a *analyzer.Client, m *mappings.FlowMappingPipeline) (*SFlowAgent, error) {
	addr, port, err := config.GetHostPortAttributes("sflow", "listen")
	if err != nil {
		return nil, err
	}

	return NewSFlowAgent(u, addr, port, a, m), nil
}

func (a *SFlowAgentAllocator) Agents() []*SFlowAgent {
	a.Lock()
	defer a.Unlock()

	agents := make([]*SFlowAgent, 0)

	for _, agent := range a.allocated {
		agents = append(agents, agent)
	}

	return agents
}

func (a *SFlowAgentAllocator) Release(uuid string) {
	a.Lock()
	defer a.Unlock()

	for i, agent := range a.allocated {
		if uuid == agent.UUID {
			agent.Stop()

			delete(a.allocated, i)
		}
	}
}

func (a *SFlowAgentAllocator) ReleaseAll() {
	a.Lock()
	defer a.Unlock()

	for i, agent := range a.allocated {
		agent.Stop()

		delete(a.allocated, i)
	}
}

func (a *SFlowAgentAllocator) Alloc(uuid string, p flow.FlowProbePathSetter) (*SFlowAgent, error) {
	address := config.GetConfig().GetString("sflow.bind_address")
	if address == "" {
		address = "127.0.0.1"
	}

	min := config.GetConfig().GetInt("sflow.port_min")
	if min == 0 {
		min = 6345
	}

	max := config.GetConfig().GetInt("sflow.port_max")
	if max == 0 {
		max = 6355
	}

	a.Lock()
	defer a.Unlock()

	// check if there is an already allocated agent for this uuid
	for _, agent := range a.allocated {
		if uuid == agent.UUID {
			return agent, AgentAlreadyAllocated
		}
	}

	for i := min; i != max+1; i++ {
		if _, ok := a.allocated[i]; !ok {
			s := NewSFlowAgent(uuid, address, i, a.AnalyzerClient, a.FlowMappingPipeline)
			s.SetFlowProbePathSetter(p)

			a.allocated[i] = s

			s.Start()

			return s, nil
		}
	}

	return nil, errors.New("sflow port exhausted")
}

func NewSFlowAgentAllocator(a *analyzer.Client, m *mappings.FlowMappingPipeline) *SFlowAgentAllocator {
	return &SFlowAgentAllocator{
		AnalyzerClient:      a,
		FlowMappingPipeline: m,
		allocated:           make(map[int]*SFlowAgent),
	}
}


text:
package org.jetbrains.idea.svn.browse;

import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.api.BaseNodeDescription;
import org.jetbrains.idea.svn.api.NodeKind;
import org.jetbrains.idea.svn.checkin.CommitInfo;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNURL;

import java.util.Comparator;
import java.util.Date;

import static java.util.Comparator.comparing;

public class DirectoryEntry extends BaseNodeDescription implements Comparable<DirectoryEntry> {

  public static final Comparator<DirectoryEntry> CASE_INSENSITIVE_ORDER =
    comparing(DirectoryEntry::getKind).thenComparing(entry -> entry.getUrl().toDecodedString(), String.CASE_INSENSITIVE_ORDER);

  private final String myName;
  @NotNull private final CommitInfo myCommitInfo;
  private final String myPath;
  private final SVNURL myUrl;
  private final SVNURL myRepositoryRoot;

  @NotNull
  public static DirectoryEntry create(@NotNull SVNDirEntry entry) {
    return new DirectoryEntry(entry.getURL(), entry.getRepositoryRoot(), entry.getName(), NodeKind.from(entry.getKind()),
                              new CommitInfo.Builder(entry.getRevision(), entry.getDate(), entry.getAuthor()).build(),
                              entry.getRelativePath());
  }

  public DirectoryEntry(SVNURL url,
                        SVNURL repositoryRoot,
                        String name,
                        @NotNull NodeKind kind,
                        @Nullable CommitInfo commitInfo,
                        String path) {
    super(kind);
    myUrl = url;
    myRepositoryRoot = repositoryRoot;
    myName = name;
    myCommitInfo = ObjectUtils.notNull(commitInfo, CommitInfo.EMPTY);
    myPath = path;
  }

  public SVNURL getUrl() {
    return myUrl;
  }

  public SVNURL getRepositoryRoot() {
    return myRepositoryRoot;
  }

  public String getName() {
    return myName;
  }

  @NotNull
  public NodeKind getKind() {
    return myKind;
  }

  public Date getDate() {
    return myCommitInfo.getDate();
  }

  public long getRevision() {
    return myCommitInfo.getRevision();
  }

  public String getAuthor() {
    return myCommitInfo.getAuthor();
  }

  public String getRelativePath() {
    return myPath == null ? myName : myPath;
  }

  @Override
  public int compareTo(@NotNull DirectoryEntry o) {
    int result = getKind().compareTo(o.getKind());

    return result != 0 ? result : myUrl.toString().compareTo(o.getUrl().toString());
  }
}