text:
"""isort.py.

Exposes a simple library to sort through imports within Python code

usage:
    SortImports(file_name)
or:
    sorted = SortImports(file_contents=file_contents).output

Copyright (C) 2013  Timothy Edmund Crosley

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

"""
from __future__ import absolute_import, division, print_function, unicode_literals

import codecs
import copy
import io
import itertools
import os
import re
import sys
from collections import namedtuple
from datetime import datetime
from difflib import unified_diff
from sys import path as PYTHONPATH
from sys import stderr, stdout

from . import settings
from .natural import nsorted
from .pie_slice import *

KNOWN_SECTION_MAPPING = {
    'STDLIB': 'STANDARD_LIBRARY',
    'FUTURE': 'FUTURE_LIBRARY',
    'FIRSTPARTY': 'FIRST_PARTY',
    'THIRDPARTY': 'THIRD_PARTY',
}

class SortImports(object):
    incorrectly_sorted = False
    skipped = False

    def __init__(self, file_path=None, file_contents=None, write_to_stdout=False, check=False,
                 show_diff=False, settings_path=None, ask_to_apply=False,  **setting_overrides):
        if not settings_path and file_path:
            settings_path = os.path.dirname(os.path.abspath(file_path))
        settings_path = settings_path or os.getcwd()

        self.config = settings.from_path(settings_path).copy()
        for key, value in itemsview(setting_overrides):
            access_key = key.replace('not_', '').lower()
            # The sections config needs to retain order and can't be converted to a set.
            if access_key != 'sections' and type(self.config.get(access_key)) in (list, tuple):
                if key.startswith('not_'):
                    self.config[access_key] = list(set(self.config[access_key]).difference(value))
                else:
                    self.config[access_key] = list(set(self.config[access_key]).union(value))
            else:
                self.config[key] = value

        indent = str(self.config['indent'])
        if indent.isdigit():
            indent = " " * int(indent)
        else:
            indent = indent.strip("'").strip('"')
            if indent.lower() == "tab":
                indent = "\t"
        self.config['indent'] = indent

        self.place_imports = {}
        self.import_placements = {}
        self.remove_imports = [self._format_simplified(removal) for removal in self.config.get('remove_imports', [])]
        self.add_imports = [self._format_natural(addition) for addition in self.config.get('add_imports', [])]
        self._section_comments = ["# " + value for key, value in itemsview(self.config) if
                                  key.startswith('import_heading') and value]

        self.file_encoding = 'utf-8'
        file_name = file_path
        self.file_path = file_path or ""
        if file_path:
            file_path = os.path.abspath(file_path)
            if settings.should_skip(file_path, self.config):
                self.skipped = True
                if self.config['verbose']:
                    print("WARNING: {0} was skipped as it's listed in 'skip' setting"
                          " or matches a glob in 'skip_glob' setting".format(file_path))
                file_contents = None
            elif not file_contents:
                self.file_path = file_path
                self.file_encoding = coding_check(file_path)
                with codecs.open(file_path, encoding=self.file_encoding) as file_to_import_sort:
                    file_contents = file_to_import_sort.read()

        if file_contents is None or ("isort:" + "skip_file") in file_contents:
            return

        self.in_lines = file_contents.split("\n")
        self.original_length = len(self.in_lines)
        if (self.original_length > 1 or self.in_lines[:1] not in ([], [""])) or self.config.get('force_adds', False):
            for add_import in self.add_imports:
                self.in_lines.append(add_import)
        self.number_of_lines = len(self.in_lines)

        self.out_lines = []
        self.comments = {'from': {}, 'straight': {}, 'nested': {}, 'above': {'straight': {}, 'from': {}}}
        self.imports = {}
        self.as_map = {}

        section_names = self.config.get('sections')
        self.sections = namedtuple('Sections', section_names)(*[n for n in section_names])
        for section in itertools.chain(self.sections, self.config['forced_separate']):
            self.imports[section] = {'straight': set(), 'from': {}}

        self.index = 0
        self.import_index = -1
        self._first_comment_index_start = -1
        self._first_comment_index_end = -1
        self._parse()
        if self.import_index != -1:
            self._add_formatted_imports()

        self.length_change = len(self.out_lines) - self.original_length
        while self.out_lines and self.out_lines[-1].strip() == "":
            self.out_lines.pop(-1)
        self.out_lines.append("")

        self.output = "\n".join(self.out_lines)
        if self.config.get('atomic', False):
            try:
                compile(self._strip_top_comments(self.out_lines), self.file_path, 'exec', 0, 1)
            except SyntaxError:
                self.output = file_contents
                self.incorrectly_sorted = True
                try:
                    compile(self._strip_top_comments(self.in_lines), self.file_path, 'exec', 0, 1)
                    print("ERROR: {0} isort would have introduced syntax errors, please report to the project!". \
                          format(self.file_path))
                except SyntaxError:
                    print("ERROR: {0} File contains syntax errors.".format(self.file_path))

                return
        if check:
            if self.output == file_contents:
                if self.config['verbose']:
                    print("SUCCESS: {0} Everything Looks Good!".format(self.file_path))
            else:
                print("ERROR: {0} Imports are incorrectly sorted.".format(self.file_path))
                self.incorrectly_sorted = True
                if show_diff or self.config.get('show_diff', False) is True:
                    self._show_diff(file_contents)
            return

        if show_diff or self.config.get('show_diff', False) is True:
            self._show_diff(file_contents)
        elif write_to_stdout:
            stdout.write(self.output)
        elif file_name:
            if ask_to_apply:
                if self.output == file_contents:
                    return
                self._show_diff(file_contents)
                answer = None
                while answer not in ('yes', 'y', 'no', 'n', 'quit', 'q'):
                    answer = input("Apply suggested changes to '{0}' [Y/n/q]?".format(self.file_path)).lower()
                    if answer in ('no', 'n'):
                        return
                    if answer in ('quit', 'q'):
                        sys.exit(1)
            with codecs.open(self.file_path, encoding=self.file_encoding, mode='w') as output_file:
                output_file.write(self.output)

    def _show_diff(self, file_contents):
        for line in unified_diff(
            file_contents.splitlines(1),
            self.output.splitlines(1),
            fromfile=self.file_path + ':before',
            tofile=self.file_path + ':after',
            fromfiledate=str(datetime.fromtimestamp(os.path.getmtime(self.file_path))),
            tofiledate=str(datetime.now())
        ):
            stdout.write(line)

    @staticmethod
    def _strip_top_comments(lines):
        """Strips # comments that exist at the top of the given lines"""
        lines = copy.copy(lines)
        while lines and lines[0].startswith("#"):
            lines = lines[1:]
        return "\n".join(lines)

    def place_module(self, moduleName):
        """Tries to determine if a module is a python std import, third party import, or project code:

        if it can't determine - it assumes it is project code

        """
        for forced_separate in self.config['forced_separate']:
            if moduleName.startswith(forced_separate) or moduleName.startswith("." + forced_separate):
                return forced_separate

        if moduleName.startswith("."):
            return self.sections.LOCALFOLDER

        # Try to find most specific placement instruction match (if any)
        parts = moduleName.split('.')
        module_names_to_check = ['.'.join(parts[:first_k]) for first_k in range(len(parts), 0, -1)]
        for module_name_to_check in module_names_to_check:
            for placement in reversed(self.sections):
                known_placement = KNOWN_SECTION_MAPPING.get(placement, placement)
                config_key = 'known_{0}'.format(known_placement.lower())
                if module_name_to_check in self.config.get(config_key, []):
                    return placement

        paths = PYTHONPATH
        virtual_env = os.environ.get('VIRTUAL_ENV', None)
        if virtual_env:
            paths = list(paths)
            for version in ((2, 6), (2, 7), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4)):
                paths.append("{0}/lib/python{1}.{2}/site-packages".format(virtual_env, version[0], version[1]))

        for prefix in paths:
            module_path = "/".join((prefix, moduleName.replace(".", "/")))
            package_path = "/".join((prefix, moduleName.split(".")[0]))
            if (os.path.exists(module_path + ".py") or os.path.exists(module_path + ".so") or
               (os.path.exists(package_path) and os.path.isdir(package_path))):
                if "site-packages" in prefix or "dist-packages" in prefix:
                    return self.sections.THIRDPARTY
                elif "python2" in prefix.lower() or "python3" in prefix.lower():
                    return self.sections.STDLIB
                else:
                    return self.sections.FIRSTPARTY

        return self.config['default_section']

    def _get_line(self):
        """Returns the current line from the file while incrementing the index."""
        line = self.in_lines[self.index]
        self.index += 1
        return line

    @staticmethod
    def _import_type(line):
        """If the current line is an import line it will return its type (from or straight)"""
        if "isort:skip" in line:
            return
        elif line.startswith('import '):
            return "straight"
        elif line.startswith('from '):
            return "from"

    def _at_end(self):
        """returns True if we are at the end of the file."""
        return self.index == self.number_of_lines

    @staticmethod
    def _module_key(module_name, config, sub_imports=False):
        prefix = ""
        module_name = str(module_name)
        if sub_imports and config['order_by_type']:
            if module_name.isupper():
                prefix = "A"
            elif module_name[0:1].isupper():
                prefix = "B"
            else:
                prefix = "C"
        module_name = module_name.lower()
        return "{0}{1}{2}".format(module_name in config['force_to_top'] and "A" or "B", prefix,
                                  config['length_sort'] and (str(len(module_name)) + ":" + module_name) or module_name)

    def _add_comments(self, comments, original_string=""):
        """
            Returns a string with comments added
        """
        return comments and "{0}  # {1}".format(self._strip_comments(original_string)[0],
                                                "; ".join(comments)) or original_string

    def _wrap(self, line):
        """
            Returns an import wrapped to the specified line-length, if possible.
        """
        wrap_mode = self.config.get('multi_line_output', 0)
        if len(line) > self.config['line_length'] and wrap_mode != settings.WrapModes.NOQA:
            for splitter in ("import", "."):
                exp = r"\b" + re.escape(splitter) + r"\b"
                if re.search(exp, line) and not line.strip().startswith(splitter):
                    line_parts = re.split(exp, line)
                    next_line = []
                    while (len(line) + 2) > (self.config['wrap_length'] or self.config['line_length']) and line_parts:
                        next_line.append(line_parts.pop())
                        line = splitter.join(line_parts)
                    if not line:
                        line = next_line.pop()

                    cont_line = self._wrap(self.config['indent'] + splitter.join(next_line).lstrip())
                    if self.config['use_parentheses']:
                        return "{0}{1} (\n{2})".format(line, splitter, cont_line)
                    return "{0}{1} \\\n{2}".format(line, splitter, cont_line)
        elif len(line) > self.config['line_length'] and wrap_mode == settings.WrapModes.NOQA:
            if "# NOQA" not in line:
                return "{0}  # NOQA".format(line)

        return line

    def _add_straight_imports(self, straight_modules, section, section_output):
        for module in straight_modules:
            if module in self.remove_imports:
                continue

            if module in self.as_map:
                import_definition = "import {0} as {1}".format(module, self.as_map[module])
            else:
                import_definition = "import {0}".format(module)

            comments_above = self.comments['above']['straight'].pop(module, None)
            if comments_above:
                section_output.extend(comments_above)
            section_output.append(self._add_comments(self.comments['straight'].get(module), import_definition))

    def _add_from_imports(self, from_modules, section, section_output):
        for module in from_modules:
            if module in self.remove_imports:
                continue

            import_start = "from {0} import ".format(module)
            from_imports = list(self.imports[section]['from'][module])
            from_imports = nsorted(from_imports, key=lambda key: self._module_key(key, self.config, True))
            if self.remove_imports:
                from_imports = [line for line in from_imports if not "{0}.{1}".format(module, line) in
                                self.remove_imports]

            for from_import in copy.copy(from_imports):
                submodule = module + "." + from_import
                import_as = self.as_map.get(submodule, False)
                if import_as:
                    import_definition = "{0} as {1}".format(from_import, import_as)
                    if self.config['combine_as_imports'] and not ("*" in from_imports and
                                                                    self.config['combine_star']):
                        from_imports[from_imports.index(from_import)] = import_definition
                    else:
                        import_statement = self._wrap(import_start + import_definition)
                        comments = self.comments['straight'].get(submodule)
                        import_statement = self._add_comments(comments, import_statement)
                        section_output.append(import_statement)
                        from_imports.remove(from_import)

            if from_imports:
                comments = self.comments['from'].pop(module, ())
                if "*" in from_imports and self.config['combine_star']:
                    import_statement = self._wrap(self._add_comments(comments, "{0}*".format(import_start)))
                elif self.config['force_single_line']:
                    import_statements = []
                    for from_import in from_imports:
                        single_import_line = self._add_comments(comments, import_start + from_import)
                        comment = self.comments['nested'].get(module, {}).pop(from_import, None)
                        if comment:
                            single_import_line += "{0} {1}".format(comments and ";" or "  #", comment)
                        import_statements.append(self._wrap(single_import_line))
                        comments = None
                    import_statement = "\n".join(import_statements)
                else:
                    star_import = False
                    if "*" in from_imports:
                        section_output.append(self._add_comments(comments, "{0}*".format(import_start)))
                        from_imports.remove('*')
                        star_import = True
                        comments = None

                    for from_import in copy.copy(from_imports):
                        comment = self.comments['nested'].get(module, {}).pop(from_import, None)
                        if comment:
                            single_import_line = self._add_comments(comments, import_start + from_import)
                            single_import_line += "{0} {1}".format(comments and ";" or "  #", comment)
                            above_comments = self.comments['above']['from'].pop(module, None)
                            if above_comments:
                                section_output.extend(above_comments)
                            section_output.append(self._wrap(single_import_line))
                            from_imports.remove(from_import)
                            comments = None

                    if star_import:
                        import_statement = import_start + (", ").join(from_imports)
                    else:
                        import_statement = self._add_comments(comments, import_start + (", ").join(from_imports))
                    if not from_imports:
                        import_statement = ""
                    if len(from_imports) > 1 and (
                        len(import_statement) > self.config['line_length']
                        or self.config.get('force_grid_wrap')
                    ):
                        output_mode = settings.WrapModes._fields[self.config.get('multi_line_output',
                                                                                0)].lower()
                        formatter = getattr(self, "_output_" + output_mode, self._output_grid)
                        dynamic_indent = " " * (len(import_start) + 1)
                        indent = self.config['indent']
                        line_length = self.config['wrap_length'] or self.config['line_length']
                        import_statement = formatter(import_start, copy.copy(from_imports),
                                                    dynamic_indent, indent, line_length, comments)
                        if self.config['balanced_wrapping']:
                            lines = import_statement.split("\n")
                            line_count = len(lines)
                            if len(lines) > 1:
                                minimum_length = min([len(line) for line in lines[:-1]])
                            else:
                                minimum_length = 0
                            new_import_statement = import_statement
                            while (len(lines[-1]) < minimum_length and
                                    len(lines) == line_count and line_length > 10):
                                import_statement = new_import_statement
                                line_length -= 1
                                new_import_statement = formatter(import_start, copy.copy(from_imports),
                                                                dynamic_indent, indent, line_length, comments)
                                lines = new_import_statement.split("\n")
                    elif len(import_statement) > self.config['line_length']:
                        import_statement = self._wrap(import_statement)

                if import_statement:
                    above_comments = self.comments['above']['from'].pop(module, None)
                    if above_comments:
                        section_output.extend(above_comments)
                    section_output.append(import_statement)

    def _add_formatted_imports(self):
        """Adds the imports back to the file.

        (at the index of the first import) sorted alphabetically and split between groups

        """
        if self.config.get('force_alphabetical_sort', False):
            from_output = []
            straight_output = []
            for section in itertools.chain(self.sections, self.config['forced_separate']):
                straight_modules = list(self.imports[section]['straight'])
                from_modules = list(self.imports[section]['from'].keys())

                self._add_from_imports(from_modules, section, from_output)
                self._add_straight_imports(straight_modules, section, straight_output)

            new_from_output = []
            new_straight_output = []
            for line in from_output:
                for element in line.split('\n'):
                    new_from_output.append(element)
            for line in straight_output:
                for element in line.split('\n'):
                    new_straight_output.append(element)

            sorted_from = sorted(new_from_output, key=lambda import_string: import_string.lower())
            sorted_straight = sorted(new_straight_output, key=lambda import_string: import_string.lower())
            output = (sorted_from + [''] + sorted_straight) if (sorted_from and sorted_straight) else \
                     (sorted_from or sorted_straight)
        else:
            output = []
            for section in itertools.chain(self.sections, self.config['forced_separate']):
                straight_modules = list(self.imports[section]['straight'])
                straight_modules = nsorted(straight_modules, key=lambda key: self._module_key(key, self.config))
                from_modules = sorted(list(self.imports[section]['from'].keys()))
                from_modules = nsorted(from_modules, key=lambda key: self._module_key(key, self.config, ))

                section_output = []
                if self.config.get('from_first', False):
                    self._add_from_imports(from_modules, section, section_output)
                    self._add_straight_imports(straight_modules, section, section_output)
                else:
                    self._add_straight_imports(straight_modules, section, section_output)
                    self._add_from_imports(from_modules, section, section_output)

                if self.config.get('force_sort_within_sections', False):
                    def by_module(line):
                        line = re.sub('^from ', '', line)
                        line = re.sub('^import ', '', line)
                        if not self.config['order_by_type']:
                            line = line.lower()
                        return line
                    section_output = nsorted(section_output, key=by_module)

                if section_output:
                    section_name = section
                    if section_name in self.place_imports:
                        self.place_imports[section_name] = section_output
                        continue

                    section_title = self.config.get('import_heading_' + str(section_name).lower(), '')
                    if section_title:
                        section_comment = "# {0}".format(section_title)
                        if not section_comment in self.out_lines[0:1]:
                            section_output.insert(0, section_comment)
                    output += section_output + ['']

        while [character.strip() for character in output[-1:]] == [""]:
            output.pop()

        output_at = 0
        if self.import_index < self.original_length:
            output_at = self.import_index
        elif self._first_comment_index_end != -1 and self._first_comment_index_start <= 2:
            output_at = self._first_comment_index_end
        self.out_lines[output_at:0] = output

        imports_tail = output_at + len(output)
        while [character.strip() for character in self.out_lines[imports_tail: imports_tail + 1]] == [""]:
            self.out_lines.pop(imports_tail)

        if len(self.out_lines) > imports_tail:
            next_construct = ""
            self._in_quote = False
            for line in self.out_lines[imports_tail:]:
                if not self._skip_line(line) and not line.strip().startswith("#") and line.strip():
                    next_construct = line
                    break

            if self.config['lines_after_imports'] != -1:
                self.out_lines[imports_tail:0] = ["" for line in range(self.config['lines_after_imports'])]
            elif next_construct.startswith("def") or next_construct.startswith("class") or \
               next_construct.startswith("@"):
                self.out_lines[imports_tail:0] = ["", ""]
            else:
                self.out_lines[imports_tail:0] = [""]

        if self.place_imports:
            new_out_lines = []
            for index, line in enumerate(self.out_lines):
                new_out_lines.append(line)
                if line in self.import_placements:
                    new_out_lines.extend(self.place_imports[self.import_placements[line]])
                    if len(self.out_lines) <= index or self.out_lines[index + 1].strip() != "":
                        new_out_lines.append("")
            self.out_lines = new_out_lines

    def _output_grid(self, statement, imports, white_space, indent, line_length, comments):
        statement += "(" + imports.pop(0)
        while imports:
            next_import = imports.pop(0)
            next_statement = self._add_comments(comments, statement + ", " + next_import)
            if len(next_statement.split("\n")[-1]) + 1 > line_length:
                statement = (self._add_comments(comments, "{0},".format(statement)) +
                             "\n{0}{1}".format(white_space, next_import))
                comments = None
            else:
                statement += ", " + next_import
        return statement + ("," if self.config['include_trailing_comma'] else "") + ")"

    def _output_vertical(self, statement, imports, white_space, indent, line_length, comments):
        first_import = self._add_comments(comments, imports.pop(0) + ",") + "\n" + white_space
        return "{0}({1}{2}{3})".format(
            statement,
            first_import,
            (",\n" + white_space).join(imports),
            "," if self.config['include_trailing_comma'] else "",
        )

    def _output_hanging_indent(self, statement, imports, white_space, indent, line_length, comments):
        statement += imports.pop(0)
        while imports:
            next_import = imports.pop(0)
            next_statement = self._add_comments(comments, statement + ", " + next_import)
            if len(next_statement.split("\n")[-1]) + 3 > line_length:
                next_statement = (self._add_comments(comments, "{0}, \\".format(statement)) +
                                  "\n{0}{1}".format(indent, next_import))
                comments = None
            statement = next_statement
        return statement

    def _output_vertical_hanging_indent(self, statement, imports, white_space, indent, line_length, comments):
        return "{0}({1}\n{2}{3}{4}\n)".format(
            statement,
            self._add_comments(comments),
            indent,
            (",\n" + indent).join(imports),
            "," if self.config['include_trailing_comma'] else "",
         )

    def _output_vertical_grid_common(self, statement, imports, white_space, indent, line_length, comments):
        statement += self._add_comments(comments, "(") + "\n" + indent + imports.pop(0)
        while imports:
            next_import = imports.pop(0)
            next_statement = "{0}, {1}".format(statement, next_import)
            if len(next_statement.split("\n")[-1]) + 1 > line_length:
                next_statement = "{0},\n{1}{2}".format(statement, indent, next_import)
            statement = next_statement
        if self.config['include_trailing_comma']:
            statement += ','
        return statement

    def _output_vertical_grid(self, statement, imports, white_space, indent, line_length, comments):
        return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments) + ")"

    def _output_vertical_grid_grouped(self, statement, imports, white_space, indent, line_length, comments):
        return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments) + "\n)"

    def _output_noqa(self, statement, imports, white_space, indent, line_length, comments):
        retval = '{0}{1}'.format(statement, ' '.join(imports))
        comment_str = ' '.join(comments)
        if comments:
            if len(retval) + 4 + len(comment_str) <= line_length:
                return '{0}  # {1}'.format(retval, comment_str)
        else:
            if len(retval) <= line_length:
                return retval
        if comments:
            if "NOQA" in comments:
                return '{0}  # {1}'.format(retval, comment_str)
            else:
                return '{0}  # NOQA {1}'.format(retval, comment_str)
        else:
            return '{0}  # NOQA'.format(retval)

    @staticmethod
    def _strip_comments(line, comments=None):
        """Removes comments from import line."""
        if comments is None:
            comments = []

        new_comments = False
        comment_start = line.find("#")
        if comment_start != -1:
            comments.append(line[comment_start + 1:].strip())
            new_comments = True
            line = line[:comment_start]

        return line, comments, new_comments

    @staticmethod
    def _format_simplified(import_line):
        import_line = import_line.strip()
        if import_line.startswith("from "):
            import_line = import_line.replace("from ", "")
            import_line = import_line.replace(" import ", ".")
        elif import_line.startswith("import "):
            import_line = import_line.replace("import ", "")

        return import_line

    @staticmethod
    def _format_natural(import_line):
        import_line = import_line.strip()
        if not import_line.startswith("from ") and not import_line.startswith("import "):
            if not "." in import_line:
                return "import {0}".format(import_line)
            parts = import_line.split(".")
            end = parts.pop(-1)
            return "from {0} import {1}".format(".".join(parts), end)

        return import_line

    def _skip_line(self, line):
        skip_line = self._in_quote
        if self.index == 1 and line.startswith("#"):
            self._in_top_comment = True
            return True
        elif self._in_top_comment:
            if not line.startswith("#"):
                self._in_top_comment = False
                self._first_comment_index_end = self.index

        if '"' in line or "'" in line:
            index = 0
            if self._first_comment_index_start == -1:
                self._first_comment_index_start = self.index
            while index < len(line):
                if line[index] == "\\":
                    index += 1
                elif self._in_quote:
                    if line[index:index + len(self._in_quote)] == self._in_quote:
                        self._in_quote = False
                        if self._first_comment_index_end < self._first_comment_index_start:
                            self._first_comment_index_end = self.index
                elif line[index] in ("'", '"'):
                    long_quote = line[index:index + 3]
                    if long_quote in ('"""', "'''"):
                        self._in_quote = long_quote
                        index += 2
                    else:
                        self._in_quote = line[index]
                elif line[index] == "#":
                    break
                index += 1

        return skip_line or self._in_quote or self._in_top_comment

    def _strip_syntax(self, import_string):
        import_string = import_string.replace("_import", "[[i]]")
        for remove_syntax in ['\\', '(', ')', ',']:
            import_string = import_string.replace(remove_syntax, " ")
        import_list = import_string.split()
        for key in ('from', 'import'):
            if key in import_list:
                import_list.remove(key)
        import_string = ' '.join(import_list)
        import_string = import_string.replace("[[i]]", "_import")
        return import_string.replace("{ ", "{|").replace(" }", "|}")

    def _parse(self):
        """Parses a python file taking out and categorizing imports."""
        self._in_quote = False
        self._in_top_comment = False
        while not self._at_end():
            line = self._get_line()
            skip_line = self._skip_line(line)

            if line in self._section_comments and not skip_line:
                if self.import_index == -1:
                    self.import_index = self.index - 1
                continue

            if "isort:" + "imports-" in line and line.startswith("#"):
                section = line.split("isort:" + "imports-")[-1].split()[0]
                self.place_imports[section.upper()] = []
                self.import_placements[line] = section.upper()

            if ";" in line:
                for part in (part.strip() for part in line.split(";")):
                    if part and not part.startswith("from ") and not part.startswith("import "):
                        skip_line = True

            import_type = self._import_type(line)
            if not import_type or skip_line:
                self.out_lines.append(line)
                continue

            for line in (line.strip() for line in line.split(";")):
                import_type = self._import_type(line)
                if not import_type:
                    self.out_lines.append(line)
                    continue

                line = line.replace("\t", " ")
                if self.import_index == -1:
                    self.import_index = self.index - 1

                nested_comments = {}
                import_string, comments, new_comments = self._strip_comments(line)
                stripped_line = [part for part in self._strip_syntax(import_string).strip().split(" ") if part]

                if import_type == "from" and len(stripped_line) == 2 and stripped_line[1] != "*" and new_comments:
                    nested_comments[stripped_line[-1]] = comments[0]

                if "(" in line and not self._at_end():
                    while not line.strip().endswith(")") and not self._at_end():
                        line, comments, new_comments = self._strip_comments(self._get_line(), comments)
                        stripped_line = self._strip_syntax(line).strip()
                        if import_type == "from" and stripped_line and not " " in stripped_line and new_comments:
                            nested_comments[stripped_line] = comments[-1]
                        import_string += "\n" + line
                else:
                    while line.strip().endswith("\\"):
                        line, comments, new_comments = self._strip_comments(self._get_line(), comments)
                        stripped_line = self._strip_syntax(line).strip()
                        if import_type == "from" and stripped_line and not " " in stripped_line and new_comments:
                            nested_comments[stripped_line] = comments[-1]
                        if import_string.strip().endswith(" import") or line.strip().startswith("import "):
                            import_string += "\n" + line
                        else:
                            import_string = import_string.rstrip().rstrip("\\") + line.lstrip()

                if import_type == "from":
                    parts = import_string.split(" import ")
                    from_import = parts[0].split(" ")
                    import_string = " import ".join([from_import[0] + " " + "".join(from_import[1:])] + parts[1:])

                imports = [item.replace("{|", "{ ").replace("|}", " }") for item in
                           self._strip_syntax(import_string).split()]
                if "as" in imports and (imports.index('as') + 1) < len(imports):
                    while "as" in imports:
                        index = imports.index('as')
                        if import_type == "from":
                            module = imports[0] + "." + imports[index - 1]
                            self.as_map[module] = imports[index + 1]
                        else:
                            module = imports[index - 1]
                            self.as_map[module] = imports[index + 1]
                        if not self.config['combine_as_imports']:
                            self.comments['straight'][module] = comments
                            comments = []
                        del imports[index:index + 2]
                if import_type == "from":
                    import_from = imports.pop(0)
                    placed_module = self.place_module(import_from)
                    if placed_module == '':
                        print(
                            "WARNING: could not place module {0} of line {1} --"
                            " Do you need to define a default section?".format(import_from, line)
                        )
                    root = self.imports[placed_module][import_type]
                    for import_name in imports:
                        associated_commment = nested_comments.get(import_name)
                        if associated_commment:
                            self.comments['nested'].setdefault(import_from, {})[import_name] = associated_commment
                            comments.pop(comments.index(associated_commment))
                    if comments:
                        self.comments['from'].setdefault(import_from, []).extend(comments)

                    if len(self.out_lines) > max(self.import_index, self._first_comment_index_end, 1) - 1:
                        last = self.out_lines and self.out_lines[-1].rstrip() or ""
                        while last.startswith("#") and not last.endswith('"""') and not last.endswith("'''"):
                            self.comments['above']['from'].setdefault(import_from, []).insert(0, self.out_lines.pop(-1))
                            if len(self.out_lines) > max(self.import_index - 1, self._first_comment_index_end, 1) - 1:
                                last = self.out_lines[-1].rstrip()
                            else:
                                last = ""
                        if self.index - 1 == self.import_index:
                            self.import_index -= len(self.comments['above']['from'].get(import_from, []))

                    if root.get(import_from, False):
                        root[import_from].update(imports)
                    else:
                        root[import_from] = set(imports)
                else:
                    for module in imports:
                        if comments:
                            self.comments['straight'][module] = comments
                            comments = None

                        if len(self.out_lines) > max(self.import_index, self._first_comment_index_end, 1) - 1:
                            last = self.out_lines and self.out_lines[-1].rstrip() or ""
                            while last.startswith("#") and not last.endswith('"""') and not last.endswith("'''"):
                                self.comments['above']['straight'].setdefault(module, []).insert(0,
                                                                                self.out_lines.pop(-1))
                                if len(self.out_lines) > max(self.import_index - 1, self._first_comment_index_end,
                                                             1) - 1:
                                    last = self.out_lines[-1].rstrip()
                                else:
                                    last = ""
                            if self.index - 1 == self.import_index:
                                self.import_index -= len(self.comments['above']['straight'].get(module, []))
                        placed_module = self.place_module(module)
                        if placed_module == '':
                            print(
                                "WARNING: could not place module {0} of line {1} --"
                                " Do you need to define a default section?".format(import_from, line)
                            )
                        self.imports[placed_module][import_type].add(module)

def coding_check(fname, default='utf-8'):

    # see https://www.python.org/dev/peps/pep-0263/
    pattern = re.compile(br'coding[:=]\s*([-\w.]+)')

    coding = default
    with io.open(fname, 'rb') as f:
        for line_number, line in enumerate(f, 1):
            groups = re.findall(pattern, line)
            if groups:
                coding = groups[0].decode('ascii')
                break
            if line_number > 2:
                break

    return coding


To give the Sony RX1R II a little more of a workout, I decided to drive up to Franconia Notch in the White Mountain National Forest in NH. On the way up, I pulled over a few times to grab some scenes that were catching my eyes.
The first stop was the Blair Bridge in Campton, NH. It's a cool looking covered bridge that we used to go tubing under when I was in college. I liked the view of this best from the woods - with that end of foliage colors just tickling the frame.
From there, I continued north into Lincoln, NH where there was this cool little school house that was converted into a shop. I poked around there a bit, then finally continued the adventure.
Eventually, I made it up into the Notch. It was chilly, to say the least. When I parked at the trailhead, the car was reading 31º F and it was just starting to snow.
I probably hiked for half the morning, just enjoying the quietness. No one else was out here and the trails were just surreal with the snow cover.
Below are the few shots I took while on my adventure this morning. They are all taken on the RX1R II and was using the compressed RAW files. They were all edited with Rebecca's Lightroom Pro Set IV. Mostly just one-click and done for these images.


text:
Michael Glenmullen
Michael grew up just outside of Harvard Square in Cambridge, MA. He played football, wrestled, and rowed for the crew team in high school. He also founded and acted as editor-in-chief of a newspaper dedicated solely to sports and school spirit. After high school, Michael taught English as a second language to students in Ecuador, during a gap year before college. He then went on to earn his BA in French from Yale University. While at Yale, Michael continuing rowing for the crew team, this time as part an NCAA Division I program. He also worked as a private tutor and volunteered at New Haven Reads, mentoring underprivileged students to achieve their academic goals.
After college, Michael taught scuba diving for two years in Florida, Mexico, and Honduras. An avid diver, he is passionate about oceanic life and exploring its natural beauty. Michael is also a big-time dog/animal lover. He volunteers as a rescue dog walker at the Amanda Foundation in Beverly Hills. His teaching philosophy is centered on understanding each individual's learning style and tailoring the material to foster enthusiasm for learning. Michael is thrilled to be joining the TREE community!
michael.glenmullen@treeacademy.org

redpajama_set_name: RedPajamaCommonCrawl


text:
#PollVault: Congress Pivots to Income Guarantee, Rattled BJP Calls NYAY 'Deception'
A repository of the day's major election-related developments.
26/Mar/2019
Every morning till the elections, The Wire's reporters and editors bring you Poll Vault – a summary of the most important political developments, all in one place. To get it straight in your mailbox, sign up here.
New Delhi: Congress president Rahul Gandhi finally breathed some life into his party's election campaign on Monday with the promise of a guaranteed minimum income for the poorest quintile of the population, a move senior Bharatiya Janata Party leader and finance minister Chowkidar Arun Jaitley promptly declared to be a "bluff".
Ever since the Jaish-e-Mohammad's suicide bombing of the CRPF convoy at Pulwama, the Congress has struggled to find its feet. The party which had parlayed its victories in the assembly elections of Chhattisgarh, Madhya Pradesh and Rajasthan into a determined push for opposition unity across several states found itself on the defensive. Worse, it has allowed short-term considerations to come in the way of the kind of alliances it needs to establish in Delhi, Uttar Pradesh, Haryana, Gujarat and even Rajasthan and Madhya Pradesh if it is to make a serious dent in the BJP's seat tally.
Against this backdrop, the Congress desperately needed a forward-looking issue to build its election campaign around and the Nyuntam Aay Yojana, or NYAY, could well be what the doctor ordered.
To be sure, the practical aspects of implementation appear formidable. It is not clear how the beneficiaries will be selected and their incomes measured. What is on offer is a guarantee of a minimum monthly income of Rs 12,000 per poor family based on a fixed handout of Rs 6,000 a month for a family that is assumed to be already earning Rs 6,000.
But as a promise, it has been made with a lot more commitment and detail than the 'jumlas' about job creation or the return of black money Chowkidar Narendra Modi threw into the mix during the 2014 campaign. The 'Rs 15 lakh in every person's bank account' never made it to the BJP's manifesto and the truth is that Modi himself also spoke about it in a purely rhetorical vein; yet the parivar's footsoldiers took that assurance to the masses, thereby sowing the seeds of discontent at the betrayal which inevitably followed.
What gives the Congress proposal added traction is that Modi himself had broached the idea of a minimum guaranteed income (for farmers) in the government's last budget, albeit pegged at such a low level as to be virtually meaningless. By contrast, Rs 6,000 a month will be seen by most poor families as a substantial sum.
The big question, of course, is what existing social welfare programmes would a Congress-led government gut in order to pay for NYAY? Since the figure of Rs 6,000 is pegged on the target family already earning a similar amount from a scheme like NREGA, the employment guarantee programme can surely not be considered expendable. But the public distribution system (PDS) may come under pressure, with the removal of subsidised foodgrain prices adding to the inflationary effect of the cash infusion.
Also read | The Time for a Minimum Income Guarantee in India Has Come
Apart from the attractiveness of the proposed yojana itself, NYAY has the added benefit of bringing the spotlight back to the plight of India's poor and away from the national security focus that Modi and his ministers are trying to push. The opposition parties know the BJP is vulnerable on the issue of unemployment and rural distress, and that is where they would like to train their guns.
Having decided on his key campaign theme, Rahul Gandhi now has to decide whom he wants to direct that campaign against. Even as the task of clinching an alliance with the Aam Aadmi Party in Delhi remains unfinished, the Congress president has been busy campaigning in Kerala and West Bengal against the Left and the Trinamool Congress – whose support the Congress will surely need if it should ever come close to forming the next government.
In Assam, without much effort from the Congress itself, the problem of dividing the anti-BJP votes has been contained somewhat by the All India United Democratic Front declaring that it will only be contesting the Barpeta, Dhubri and Karimganj seats. In the 2014 election, the Congress lost to the BJP in two seats – Nowgong and Mangaldoi – thanks to a strong showing by the AIUDF. Similarly, the absence of an AUDF candidate from seats like Silchar and Kaliabor, which the Congress won in 2014, will make it easier for the party to retain them again this time.
Partisan governor, and airline
As BJP chief minister of Uttar Pradesh when the Babri Masjid was demolished back in December 1992, Kalyan Singh demonstrated his contempt for the law and constitution and had his knuckles gently rapped by the Supreme Court for contempt.
As governor of Rajasthan, he demonstrated his contempt towards constitutional propriety when he told reporters, "Hum sabhi log BJP ke karyakarta hain aur iss naatey se hum zaroor chahengey ke BJP vijayee ho. Sab chahengey ek baar phir sey kendra mein Modi-ji pradhanmantri banein. Modi-ji ka pradhanmantri ban-na ye desh ke liye avashyak hai, samaaj ke liye avashyak hai (We are all BJP workers, so we will want the BJP to win. Everyone will want Modi to become the PM again. Modi becoming the PM is necessary for the nation and the society)."
Though governors are political appointees, they are expected to remain politically neutral and not take a stand in favour of one party or another.
On Monday, the national carrier, Air India, also courted controversy by printing photographs of Prime Minister Narendra Modi and Gujarat chief minister Vijay Rupani on boarding passes, ostensibly as an advertisement for the Vibrant Gujarat summit.
At New Delhi airport today March 25th, 2019.
My Air India Boarding Pass, prominently flashes Narendra Modi, "Vibrant Gujrat" & Vijay Rupani. Picture of boarding pass is below.
Wonder why we are wasting public money on this Election Commission, which doesn't see, hears or speak… pic.twitter.com/7t49cNIlAR
— Shashi Kant IPS (@shashikantips54) March 25, 2019
After an outcry, the airline said it would stop this practice, which may said was a violation of the model code of conduct in force for the elections.
A novel form of protest
PTI reports that farmers in Nizamabad, Telangana, have hit upon a novel form of protest against the policies of Prime Minister Narendra Modi and chief minister K. Chandrasekhara Rao: "Over 200 tumeric and 'jowar' (sorghum) farmers filed their nominations in Nizamabad protesting the 'failure' of the Centre and the state government to ensure remunerative prices for their produce, taking the total number of candidates in the constituency to 245."
In the 1996 Lok Sabha election, 480 people from Nalgonda filed their nominations as a form of protest against the lack of government attention towards water quality in the region. Shortly thereafter, the Election Commission hiked the value of the deposit a candidate must make in order to file his or her nomination as a means of discouraging such protests.


The Nanaimo RCMP has followed through on a threat to raid marijuana dispensaries if they didn't shut down. On Tuesday, the police announced they raided three dispensaries they had warned to close.
The RCMP would not reveal the name of the stores or what they found. They also declined to explain whether there were concerns over organized crime that would make the raids necessary, or whether the action was in keeping with practices at other RCMP detachments.
However, Travis Lane, the general manager of Trees Dispensary, said his store, along with ones owned by Phoenix Pain Management Society and Nature's Source Society were served with search warrants executed. In a post on its Facebook page, Phoenix Pain Management said two of its members, both seniors, had been arrested.
RCMP did not indicate if they had arrested anyone. However, in a long note posted on its website said it had received "several complaints" from the public about illegal marijuana storefronts, including one from a grandmother who believes her 15-year-old grandchild had bought pot from a storefront.
In mid-November, the Nanaimo RCMP sent warning letters to at least 10 shops selling marijuana, ordering them to shut down. It said the sale of the drug was not permitted. It said on Tuesday that two shops had shut down, but would not say if police were now going after the rest.
The RCMP's actions in Nanaimo are in stark contrast to the way the city of Vancouver is handling the proliferation of marijuana shops. Earlier this year the city decided to issue business licences for shops that comply with certain zoning requirements. It undertook the program after more than 100 illegal shops opened, some near schools.
Although marijuana remains illegal, the city said it would use land use and zoning bylaws to control where shops could open. After council approved the plan in June, the city received 177 applications. In October it announced that 11 applications had passed the first stage and could now apply for development permit applications. Those sites are at least 300 metres away from schools, community centres and neighbourhood centres.
Andreea Toma, Vancouver's licensing director said on Tuesday that another 20 applications are within 300 metres of each other and the city is "going through a declustering exercise" that may see six or seven locations approved.
The rest have been told they are not within approved zones or are too close to schools, community centres and neighbourhood centres. They have six months to shut down. A handful are able to appeal their rejections to the Board of Variance, which has scheduled appeal hearings starting in February.
Toma said the city is working with police to identify problem applicants but so far it hasn't run into problems. "There have been no injunctions yet, and surprisingly the industry is working with us," she said. "They appear to be trying to convince the federal government we are working together."
Vancouver Coun. Kerry Jang has said in the past he expects the city has the capacity for about 30 pot shops.
In Nanaimo, however, there appears to be no similar appetite for cooperation by the RCMP.
In a statement Monday, the RCMP said "there is no legal mechanism in Canada which allows for "medicinal marijuana dispensaries" or "compassion clubs" to sell or gift to the public."
Instead, it likened the illegal sale of marijuana to that of alcohol.
"We do not permit people to sell legal or illegal liquor or prescription medicine on a street corner and similarly, we cannot permit an illegal substance to be sold in a similar manner, particularly when people have complained about it," the RCMP said in a statement Tuesday.
"When I have reports of storefronts selling marijuana to youth and concerned community members approaching me about it, we are compelled to take enforcement action. Our approach has always been to address public concerns, consult our contracting partners, stakeholders and allow for our investigations to determine the way forward. That was done in this case," Supt. Mark Fisher, the officer in charge of the Nanaimo detachment, said in the press release. He said the police would make no further comment.
The Trudeau government has said its plan to legalize marijuana make take up to two years to complete.


text:
Pillai Shaadi > Matrimony
Pillai Shaadi
I belong to a Upper Middle Class, Nuclear Family with Moderate Values.
Location : Kerala, India
My daughter secured a job in LIC (Central Government) as Assistant in Coimbatore Division.Currently working in Tirupur Branch Office and has completed MBA in HRM.We came from a upper middle class,nuclear family background with traditional values. People describe her as modest, honest and having positive-attitude.
Subcaste : Pandiya Vellalar
My name is N.pavithra. I come from a Middle Class, Joint Family. I have completed my B.Sc. and currently work makeup artist
My Daughter Anusha Devi currently working in a Private sector. She has completed B.Tech. Grown up in a Middle Class, Nuclear family.
Education : MD / MS (Medical)
We belong to a middle class, nuclear family with traditional values. My Sister has completed M. sc.,M. phil in Mathematics and now pursuing Ph.D in mathematics at VIT Chennai as a Teaching cum Research Assistant.
My daughter's name is Kala Nandini Selvam and she is working as a Engineer - Non IT in the Private sector. She completed my BE and grew up in a Upper Middle Class, Nuclear family.
My name is SivaPriya. I have completed my B.Tech.. I grew up in a Rich / Affluent, Joint family.
Occupation : Media Professional
My daughter has a bachelor's degree and she is employed in private sector as a media professional currently based in Salem. We come from a middle class, joint family background with orthodox values.
My name is Manikandan. I come from a Middle Class, Nuclear Family. I have completed my BE (mechanical engineering)and currently work in the Private Sector as an embedded developer
My name is Sibiraaj and I am working as a Software Professional in the Private sector in Bangalore. I have completed my B.Tech. I grew up in a Middle Class, Nuclear family.
Location : Munich, Munich, Germany
My son is working as a Executive in the Private sector and completed BE in mechanical. He grew up in a Upper Middle Class class, Nuclear family with Traditional values and a Pet lover.


This unique whipped cream siphon has an aluminum body and a solid high impact composite head.
· Included are three (3) decorating tips and a charger holder.
Whip-eez brand whippers reflect over 60 years of manufacturing expertise. These Cream Whippers are the perfect kitchen tools to whip up creams, flavored toppings and mousses. The whipped cream siphon will withstand intense in home and restaurant use. A decorator tip is connected to the whipping canister head with a metal adapter, allowing the decorator tips to be conveniently removed for cleaning while the whipper is under pressure.
This Aluminum Cream Whipper is equipped with a specially designed strong and durable steel lever system allowing perfect dispensing and decorating.
Love it! I took my new whipeez to a family party and everyone took turns using it on desserts like pie, ice cream, and jello. Now they all want one. Fun – fun – fun.
This is my first purchase from this company. Transaction was fast and friendly. I called my order in because I wanted to pay on 2 separate credit cards. Received my order quick! Very happy to say everything works great. Read the directions. I forgot to put in powdered sugar the first time. Second time was a charm. Thick, I mean really thick whipped cream. Awesome. I can't wait to start experimenting with different flavors and colors.


text:
Slumping Atlanta United have to make their own luck, says de Boer
April 1, 201910:38AM EDT
Andrew KingContributor
Follow@ AndrewKingCbus
COLUMBUS, Ohio – After four games, defending MLS Cup champions Atlanta United sit at the bottom of the Eastern Conference thanks to a 2-0 loss to Columbus Crew SC Saturday, the team's fourth straight match without a win.
In a sloppy match played in a torrential downpour, Atlanta went down early after a Columbus goal in the 2nd minute and couldn't fight back when the lead was stretched to two goals in the 39th minute.
After the match, head coach Frank de Boer said despite starting "very badly," he thought his team played "quite well" and deserved more than the shutout loss.
"We created our chances – I think we had four chances, three very good chances – and they had two chances and scored two times," he said. "That's football."
De Boer was clearly miffed by the waterlogged field conditions, which were impacted by a day of nonstop rain in Columbus.
"It was dangerous for our players and also the other team," he said. "They couldn't call it football anymore."
After starting the season with de Boer's preferred 3-4-3 formation, Atlanta played in a 4-3-3 that was more reminiscent of their 2018 look.
Well, looks like the formation wasn't @ATLUTD's issue. #CLBvATL
— Matthew Doyle (@MattDoyle76) March 30, 2019
In their new formation, de Boer said he was happy with what his team was able to create, but unhappy with their killer instinct. He said he thinks "we can build from here," but admitted Atlanta "want to change the results as quickly as possible."
"We showed – in the half-hour after the goal – that we played quite well," he said. "We have to improve even more, but still I put a lot of confidence in that. We're going to work hard and try to change this feeling that we have right now and [turn] it into a positive feeling."
De Boer said his team has "sometimes" deserved more than the results they've earned this season, and said Saturday's match felt similar.
"Today, when you concede an early goal, that's your own fault," he said. "But afterwards, we weren't the worst team on the pitch. Maybe sometimes we were equal; maybe sometimes we were better. But sometimes it's also not luck. You have to get the luck to go your way, and you can only do it with very hard work together."
Atlanta now have a two-week break to regroup before a trip to face the New England Revolution on April 13.
By then, de Boer said he hopes to have star attacker Pity Martinez – who missed Saturday's match with a hamstring injury – back in the fold. But he's not committing to the Argentine's return just yet.
"We think he will [be back]," he said. "He's already running on the field, so I think he'll be able to play. But we'll have to wait."


text:
The Latin Grammys surrender to Rubén Blades, the "poet of salsa"
Rubén Blades, poet, teacher and renovator of salsa, received last night a heartfelt tribute from the Latin Recording Academy, which named the Panamanian Person of the Year for his extensive professional career and his "continuous defense of human rights ".
"Success tastes like pain, sweat, hope and tears. Many times it tastes like shit and even if it creates fame, poor man who decides to live in it," said the musician, actor and activist when thanking the tribute.
The gala, organized in Las Vegas (USA) one day before the Latin Grammys are awarded, featured performances by artists as varied as Carlos Vives, Marc Anthony, Andrés Calamaro, Rozalén, Diego Torres and Christina Aguilera.
All of them brought to their field the most outstanding songs from the extensive discography of Blades, one of the most admired and prolific composers in Latin America.
Among the musical appearances, Aguilera opened the gala with a version of "Camaleón" in which she wore her jet of voice; Farruko showed that "Amor y Control" fit the urban rhythms and Rozalén, María Toledo and Beatriz Luengo surprised with a flamenco version of "El Padre Antonio y El Monaguillo Andrés".
There was also a place for Caribbean and tropical rhythms by the hand of Oscar D'Leon with "Looking Guayaba", Carlos Vives with "Decisiones" and Marc Anthony with "Patria".
"Thank you all very much, I thought it was excellent, this has been very emotional and I am very grateful," said the Panamanian and then dedicate the tribute to his country.
Before, the invited artists did not hesitate to interrupt the script of the ceremony to dedicate words of admiration to Blades.
Among the most emotional speeches was that of Joaquín Sabina, who came to the stage to read a letter that he introduced, making it clear that it was not easy "to find words at the height of his talent and admiration."
"We are facing one of those guys who are born once every century and what a blessing," he said before the attentive gaze of Blades, who did not expect the appearance of the Spanish in his tribute.
Sabina stressed that Blades, in addition to being the owner of "exemplary conduct", was able to renew neighborhood music "that served to dance" and elevate it "to the top of the fine arts."
"Gabo (Gabriel García Márquez) once told me that he would change having written his '100 years of Soledad' for having written 'Pedro Navaja', he recalled.
Sabina's praise came after the speech starred by René Perez, from Residente: "You are my mentor, my teacher and friend. Like a father to me," promised the musician.
Farruko, for his part, remembered through tears his family bond with the music of the honoree: "This song marked my life in 2002, I went with my grandfather to shop, he took his own life and this song is the one that he always played ", said after interpreting" Love and Control ".
Others, such as Carlos Vives, applauded Blades' contribution to the Latin "identity", something that Beatriz Luengo underlined when emphasizing that she "as a Spaniard" could "imagine Latin America thanks to her music."
Andrés Calamaro highlighted that the album "Siembra" (considered the best salsa album) "opened the doors" to the world of salsa and Jorge Drexler described Blades as a "blessing for Latin music."
Born on July 16, 1948 in Panama, Blades, in addition to being an emblematic figure in the salsa revolution of the 70s in New York, has collaborated with rock, jazz, pop, hip-hop and reggaeton artists, among other genres. musicals.
During his career he has been the winner of eight Latin Grammy Awards, as well as nine Grammys.
As an actor, he was Emmy nominated and has starred in more than 50 movies and television series in English and Spanish, including his acclaimed role as Daniel Salazar on AMC's award-winning series "Fear The Walking Dead."
As a result of his interest in politics, in 1994 he participated in the presidential elections in Panama.
However, after the applause, Blades rejected the popularity – "fame is a place that you visit, not a home and whoever does not understand it will lose their life" – and took the opportunity to thank all those who have contributed to its success, from his family, his school teachers and musicians who have accompanied him in his career.
"They asked me at the entrance what I had left to do, and I said everything," he settled. "I'm not afraid of time, just indifference."
Before Blades were Person of the Year: Juanes (2019), Maná (2018), Alejandro Sanz (2017), Marc Anthony (2016), Roberto Carlos (2015), Joan Manuel Serrat (2014) and Miguel Bosé (2013).
Caetano Veloso (2012), Shakira (2011), Plácido Domingo (2010), Juan Gabriel (2009), Gloria Estefan (2008), Juan Luis Guerra (2007), Ricky Martin (2006), José José (2005) also received this tribute. ), Carlos Santana (2004), Gilberto Gil (2003), Vicente Fernández (2002), Julio Iglesias (2001) and Emilio Estefan (2000).
Latin stars honor Rubén Blades as Person of the Year
Rubén Blades: "Do not be overcome by indifference"
Latin Grammy 2021 FREE ONLINE: relive the Latin music awards here
Goalkeeper of the Iranian team is accused of being a man and pronounces: "I am a woman!"
Milagros Llamosas attacks Movistar, which does not accept to pay a million: "Before cameras they cried you"


Fashion Q&A: Can I revive my faded jeans?
Q: My favourite jeans are really faded – is it possible to restore their colour?
A: I suggest you use a machine dye to bring the colour of your jeans back to life.
Dylon have a wide selection of colour available. They offer a denim colour but you might want to try out their new winter colours.
They are simple and easy to use, just pop them in your washing machine and after one wash cycle you'll have a new looking pair of jeans.
Dyes cost £6.06 and are available from John Lewis and Robert Dyas.
HAVE YOUR SAY! Have you got more advice to offer on this question? If so, make sure you add a comment in the box below. if you've go a question for one of our experts, you can also post that below as well.


text:
Has Compound Bow Technology Peaked?
Tony J. Peterson Jan 7, 2021
In 2007, PSE released their first version of the X-Force bow. It was built and marketed mostly around unprecedented chronograph readings. With advertised arrow speeds of up to 350 fps, its launch changed bowhunters' collective focus on what a hunting bow was capable of—and what we should focus on as consumers.
For several years to follow, whether you were at the range or in a pro shop, the conversation about bows always seemed to center on how fast they were. It was a weird time to be a bowhunter, particularly a whitetail bowhunter. With our average shots coming in at about 20 yards, we didn't really need the flat-trajectory advantage of blistering arrow speeds.
We also didn't need the short brace heights, the aggressive draw cycles, and the tuning issues that often came with prioritizing big numbers on the chronograph—or the potential rotator cuff problems that speed bows are notorious for creating. What the speed movement did do was show us what was possible, but the trade-offs were high at first.
Eventually, better bow designs bridged the gap between arrow speed and shootability. PSE had set a speed benchmark that most bow companies needed to hit to be relevant. Before long, though, they had to do it in a way that allowed consumers the chance to actually enjoy the shooting experience. In this manner, beyond parallel limbs, cam designs and configurations, and even cable guard advancements have all forced the industry to level up or be left in the dust. Aside from contributing to generally higher bow prices, these were all good things.
When it comes to the latest flagship rigs, you'll see that advertised arrow speeds are still in the conversation. They are not the focal point of bow performance, however. That's probably because it's a metric that has stopped rising. This is evidenced through offerings across the industry, which tend to average about 325 to 340 fps as advertised. These numbers, which you won't get in the real world unless you're shooting a lightweight arrow at a 30-inch draw length, have been rangebound for a long time.
That's just fine with me. After more than a decade of testing bows (and a lifetime of hunting with them), I can safely say that our shift away from speed obsession to overall performance is most welcome. We've probably peaked on speed, but there may be other shootability advances to come in the next decade.
Efficiency is What Matters
While bow technology will inevitably evolve alongside the availability of better materials and creation of more innovative designs, the limiting factor is often us as the shooters (which is one of the main reasons we seem to have peaked with arrow speeds). We can only put so much energy in, and the bow can only transfer so much of that energy to the arrow. Room for improvement on this front can be found in that lost energy, which is where Mathews's Design Engineering Manager Mark Hayes devotes a lot of his attention.
"The efficiency of the compound bow has drastically increased over the last 10 years," Hayes told MeatEater. "There is no metric more important in determining if a bow will make it past the prototype phase for Matt [McPherson, owner of Mathew's] than efficiency. This is the foundation of a desirable shooting experience and will fundamentally define the product."
The implied, undesirable aspects of shooting that Hayes is referring to are things like hand shock and vibration. Both, as well as shot noise, are physical manifestations of a bow's stored energy not converting to the kinetic energy propelling the arrow. While not as sexy or as easy to understand as arrow speed, increased bow efficiency translates to a better shooting experience. This means a better feel and less noise, as well as downrange performance and arrow penetration.
Whether at 75 or 90% let-off, bow efficiency isn't entirely a static function of a specific model. This is only what the bow is capable of achieving, just like advertised arrow speeds. Efficiency is also affected by arrow weight, with heavier ammo soaking up more power than lighter weight options when all else is equal.
Still, a more efficient bow is always preferable to a less efficient bow. Efficiency is a major driver behind most modern bow designs. It's also one area where future innovation will likely result in better overall performance. So when it comes to efficiency, bow technology has definitely not peaked.
Tunability
One of the great intangibles of compound bow quality is tunability. While arrow choice, shooting form, tip weight, and a host of other factors can influence arrow flight, bleeding-edge technologies are built into new bows every year solely for the purpose of making them easier to tune.
One company leading the charge on this front is Bowtech. Brand Manager Todd Snader says that this was an intentional effort to give bowhunters what they need to have a better bow-owning experience.
"Across the industry, manufacturers have focused on making bows smoother or faster, but with no other benefits outside of that," Snader said. "Our DeadLock technology, for example, allows users to fine-tune the energy directly behind the arrow and lock it down for repeatable performance."
In layman's terms, Bowtech's latest technology allows shooters the ability to adjust cam positioning left or right to achieve a perfect tune and then lock it into place ensuring it'll stay that way all season. This, aside from resulting in better arrow flight, also contributes to a more efficient system.
This feature also provides more forgiving shooting. In the backyard during a July practice session, this isn't a big deal. In September, when you're on a mountainside staring down a bull elk or in a tree saddle as a buck feeds past, it's everything. Starting with a perfectly tuned bow is a big deal at the moment of truth.
Emphasis on the ease of tuning and increased bow efficiency are two areas where archery engineers will continue to focus over the next decade. Barring some extreme leap in materials, bowhunters will likely witness an annual, incremental march in a better direction on both fronts. Will 2020 models vary all that much from 2021? Probably not. But will bows in 2025 and 2030 be noticeably more efficient, smoother, and quieter? Absolutely.
This won't result in arrow speeds of 400 fps anytime soon, but should produce higher-performance rigs that are easier to dial in and more enjoyable to shoot.
Those advancements alone are most welcome. They are also further affirmation that it could be a long time before we witness the high-water mark of bow design and technology.
Gear ,
How to Buy a Used Bow
Tony J. Peterson
Consistent bow accuracy is a puzzle that requires fitting a lot of odd-shaped pieces together. Bow...
Archery 101: How to Choose a Bow
After you've found your archery shop, it is time to get set up with a bow. Knowing which bow to buy...
Archery 101: How to Choose a Bow Sight
You've found the perfect bow and slung some arrows. Now, it's time to jump into the world of...


text:
Browse Acts Title - Ab
Abolition of Compulsory Age Retirement (Statutory Officeholders) Act 2001
Aboriginal Affairs (Arrangements with the States) Act 1973
Aboriginal and Torres Strait Islander Amendment (Indigenous Land Corporation) Act 2018
Aboriginal and Torres Strait Islander Commission Act 1989
Aboriginal and Torres Strait Islander Commission Amendment Act 1993
Aboriginal and Torres Strait Islander Commission Amendment Act (No. 2) 1993
Aboriginal and Torres Strait Islander Commission Amendment (TSRA) Act 1997
Aboriginal and Torres Strait Islander Heritage (Interim Protection) Act 1984
Aboriginal and Torres Strait Islander Heritage (Interim Protection) Amendment Act 1986
Aboriginal and Torres Strait Islander Heritage Protection Amendment Act 1987
Aboriginal and Torres Strait Islander Land and Sea Future Fund Act 2018
Aboriginal and Torres Strait Islander Land and Sea Future Fund (Consequential Amendments) Act 2018
Aboriginal and Torres Strait Islander Peoples Recognition Act 2013
Aboriginal and Torres Strait Islander Peoples Recognition (Sunset Extension) Act 2015
Aboriginal and Torres Strait Islanders (Queensland Discriminatory Laws) Act 1975
Aboriginal and Torres Strait Islanders (Queensland Reserves and Communities Self-management) Act 1978
Aboriginal Councils and Associations Act 1976
Aboriginal Councils and Associations Amendment Act 1978
Aboriginal Development Commission Act 1980
Aboriginal Development Commission Amendment Act 1989
Aboriginal Education (Supplementary Assistance) Act 1989
Aboriginal Education (Supplementary Assistance) Amendment Act 1991
Aboriginal Enterprises (Assistance) Act 1968
Aboriginal Land Fund Act 1974
Aboriginal Land Grant and Management (Jervis Bay Territory) Legislation Amendment Act 1995
Aboriginal Land Grant (Jervis Bay Territory) Act 1986
Aboriginal Land Grant (Jervis Bay Territory) Amendment Act 2003
Aboriginal Land (Lake Condah and Framlingham Forest) Act 1987
Aboriginal Land (Lake Condah and Framlingham Forest) Amendment Act 1994
Aboriginal Land Rights (Northern Territory) Amendment Act (No. 2) 2000
Aboriginal Land Rights (Northern Territory) Amendment (Land Scheduling) Act 2019
Aboriginal Land Rights and Other Legislation Amendment Act 2013
Aboriginal Land Rights Legislation Amendment Act 1982
Aboriginal Land Rights (Northern Territory) Act 1976
Aboriginal Land Rights (Northern Territory) Amendment Act 1978


text:
var searchData=
[
  ['hasnext',['HasNext',['../classinfact_1_1_stream_tokenizer.html#ac8de4792d7dadb993d3e96c54df2cbe6',1,'infact::StreamTokenizer']]],
  ['hasprev',['HasPrev',['../classinfact_1_1_stream_tokenizer.html#a2d8c5ba3138d99c7a13fa49091885d0e',1,'infact::StreamTokenizer']]],
  ['humanpetowner',['HumanPetOwner',['../classinfact_1_1_human_pet_owner.html#a9d1585c751db120234f4bce60d8b81ae',1,'infact::HumanPetOwner']]],
  ['humanpetowner',['HumanPetOwner',['../classinfact_1_1_human_pet_owner.html',1,'infact']]],
  ['humanpetownerconstructor',['HumanPetOwnerConstructor',['../classinfact_1_1_human_pet_owner_constructor.html',1,'infact']]]
];

redpajama_set_name: RedPajamaGithub


The Omega Man rulez! I repeat it : He rulez! He had everything todays crackers are missing: STYLE, STYLE and STYLE! Not only able to code like a running maniac, but also able to crack like that. And his cracks most of the time contained all the benefits you were expecting from a good version. Including the DOCS. He stays one of the first crackers who set standards, just like Mr. Zeropage.


text:
info@johnnymanson.com
VOTED BEST CLUB DJ
Daily World Readers
MASTER OF MARKETING
Biggest Niche Events
#MeToo and the Consequences of Mass Emasculation
jmanson2019-01-31T17:58:27+00:00
Allie Stuckey, founder of the Conservative Millennial blog and a regular on CR-TV, discusses the #MeToo movement and the flaws of its demands. Her remarks were recorded at CBLPI's Florida Women's Summit in Orlando in April 2018.
Common Sense, Interesting, Politics
Eight Indicators of Narcissism
Narcissists can draw the worst out of you especially if you don't understand what you're up against. Psychotherapist Dr. Les Carter will identify eight ingredients driving the narcissist so you can be armed with wisdom as you deal with the narcissists in your life. Dr. Les Carter is a best selling author and practices counseling in Southlake, Tx. He has conducted over 60,000 sessions with his patients.
Interesting, Life, Stupid People
How to Spot a Sociopath in 3 Steps
I so know a person or two that are full-blown sociopaths... Whether you're trying to spot a potential school shooter, a dangerous romantic partner, a total liar at work, a scammer on the internet or someone pushing a bogus business deal on you, it helps to know some of the warning signs for sociopaths. As I explained in Part 1 of this two-part series, sociopaths can have some of the most hidden and dangerous personalityf eatures. The DSM-5 lists 10 criteria for diagnosing antisocial personality disorder1(ASPD), but [...]
Mr. T Has The Solutions
We all hear about the "problems nowadays". I think Mr. T identifies some of the reasons why things are the way they are. We have failed as parents. Listen to what he says during his WWE Hall Of Fame Celebrity Wing speech.
Common Sense, Interesting, Life, Video
D'Souza Educates About Fascism
At this event produced by Young America's Foundation, Dinesh D'Souza visits the campus of SUNY Stony Brook to tear down the false narrative that Democrats are the "anti-fascist" party. In both form and substance, American leftists resemble WWII-era fascists and Nazis. Watch now as D'Souza tears down the Left's "big lie." — In theaters nationwide August 3! Through stunning historical recreations and a searching examination of fascism and white supremacy, "Death of a Nation" cuts through progressive big lies [...]
83 Weeks With Eric Bischoff
Being a pro wrestling fan from the 80's & 90's, it's good to see a resurgence interest from that era. After all, it was when wrestling was "real". It gave us immortal heroes and villains, it gave us unique characters like Bruiser Brody, Abdullah The Butcher, the Von Erichs and of coarse, the immortal Hulk Hogan. It also gave us the "Monday Night Wars" and a fight between WWF (now WWE) and the WCW (formerly the NWA). Dad used to [...]
The Band Called Sik9
In my short tenure with Jed, we played up and down the coast and one of the major stops was always Eugene Oregon. The guys had a pretty close relationship with some of the groups from there. The mighty Moth stands out and while there were many I forgot the names of, since I was heavily under the influence at the time, Sik9 was one that was easy to remember. I happened to find these songs they did and [...]
12 Odd Behaviors & Traits of the Psychopath
Some odd characteristics or behaviors that can help you identify psychopathic personalities.
Interesting, Life
Commentary – Ode To The Wait Staff
I grew up in restaurants and lounges. Jacks Restaurant, Petosa's, Riverside Timber all in Everett. Eventually washing dishes, waiting, prepping and head cook in various establishments. This commentary is for those who have to deal with the general public in a hospitality environment.
Commentary, Hospitality, Rants
Talking to Millenials
I have done a commentary or two talking about Millennials, so you may want to check out my soundcloud. Millennial attitudes, arguments and foundation is pretty much a result of bad parenting, or mis-guided parenting. And this doesn't mean ALL but a majority. But don't take my word for it.
Common Sense, Stupid People
YouTube Facing Backlash While Defending Accusations of Political Bias
Sears Home Warranty – Thinking About Buying In?
Jordan Peterson Speech
Are The Police Racist?
Ever Notice How Everyone Is A "Pro"?
Kathleen Kennedy Has Destroyed The Lucas Vision & Star Wars
Johnny Shows
Morning Madhouse
Strange Harbor
Commentary on KBKW
Facebook Twitter Pinterest Youtube Instagram Linkedin Tumblr


Maureen Spencer, RN, M.Ed. has been an Infection Preventionist for over 40 years and board certified in infection control (CIC). As one of the early pioneers in infection control, she was awarded the APIC National Carole DeMille Award in 1990 and was selected as one of the APIC Heroes of Infection Prevention in 2007 for her work in establishing a MRSA and Staph aureus Elimination Program at New England Baptist, an Orthopedic Center of Excellence in 2006.
In 2012 she was selected as one of the "Who's Who of Infection Prevention" and in 2017 she was recognized as a Fellow of the Association for Professionals in Infection Control and Epidemiology (FAPIC) for her advanced practice in infection prevention and leader within the field.
Maureen has presented numerous research abstracts and lectures at national conferences and published many peer reviewed articles on healthcare associated infections. She is a well sought after speaker for both international and national conferences on prevention of healthcare associated infections and has presented around the US and internationally in Austria, Singapore, Thailand, Indonesia, Taiwan, Malaysia, Vietnam, Philippines, France, Turkey, Argentina, Puerto Rico, Hawaii, Toronto, Vancouver and South Korea.


This uniquely shaped pasta combines the sophistication and herbal garden-freshness of chopped chives with the punch of zesty garlic. We add just enough freshly cracked black pepper to give it some pizazz. Take these flavors and incorporate them into our soon-to-be-famous, lovely, thin & silky 'pappardelle' noodles, and you have an impressive culinary dinner offering.
Easy pairings include a heart-healthy drizzle of our Asian Dipping Oil or our Sundried Tomato and Harissa Oil. Try our White Truffle Oil for a bit of sophistication. Tossing in some steamed vegetables, grilled Italian sausage, or pork medallions will provide for a memorable meal.
Note: We have a mix & match package where you can choose any three pastas for $21 - a $3 savings! Click here!
Our pasta packages are all 12 ounces, and will serve three to four.
Nan's pastas are all hand-crafted and made with 100% durum semolina. At the time the pasta is being made all-natural flavor elements are added to the dough – from pureed vegetables to herbs and spices. The result is delicious pasta which needs nothing more than a drizzle of olive oil or some butter to be intensely satisfying.
To create this distinct exotic oil we start with California grown olives, garlic and white wine vinegar. We build complexity of flavor and Far East character with ginger, lemon, cilantro, sesame and even some wasabi. This is truly an original.
Truffles are one of the world's most complex and mysterious foods, this oil captures the essence of the best truffles without the expense. This olive oil is infused with the exotic flavor of white truffles sometimes known as the "fruit of the woods".


text:
package divconq.ctp.f;

import java.util.Scanner;
import java.util.concurrent.CountDownLatch;

import divconq.ctp.CtpAdapter;
import divconq.ctp.CtpClient;
import divconq.ctp.CtpCommand;
import divconq.ctp.CtpConstants;
import divconq.ctp.cmd.RequestCommand;
import divconq.ctp.cmd.SimpleCommand;
import divconq.ctp.cmd.ProgressCommand;
import divconq.ctp.stream.CtpStreamDest;
import divconq.ctp.stream.CtpStreamSource;
import divconq.ctp.stream.FileSourceStream;
import divconq.ctp.stream.FolderDumpStream;
import divconq.ctp.stream.IStream;
import divconq.ctp.stream.IStreamDest;
import divconq.ctp.stream.NullStream;
import divconq.ctp.stream.StreamUtil;
import divconq.filestore.local.FileSystemDriver;
import divconq.filestore.select.FileSelection;
import divconq.filestore.select.FileSelectionMode;
import divconq.hub.Hub;
import divconq.lang.op.FuncCallback;
import divconq.lang.op.IOperationObserver;
import divconq.lang.op.OperationCallback;
import divconq.lang.op.OperationContext;
import divconq.lang.op.OperationObserver;
import divconq.struct.FieldStruct;
import divconq.struct.RecordStruct;
import divconq.util.StringUtil;
import divconq.work.IWork;
import divconq.work.Task;
import divconq.work.TaskRun;

/*
Title: Download Flow
Participant Client Code
Participant File Store A
Participant Pipe A
Participant Handler A
Participant Adapter A
Participant Server
Client Code->Adapter A: select
Adapter A->Server: SELECT
Server->Adapter A: SUCCESS
Adapter A->Handler A: SUCCESS
Handler A->Client Code: success
Client Code->Handler A: set pipe
Client Code->Adapter A: read
Adapter A->Server: READ
Server->Adapter A: BLOCK
Adapter A->Handler A: BLOCK
Handler A->Pipe A: BLOCK
Pipe A->File Store A: BLOCK
File Store A->Pipe A: request
Pipe A->Handler A: request
Handler A->Adapter A: read
Adapter A->Server: READ
Server->Adapter A: BLOCK*\netc...
Server->Adapter A: FINAL
Adapter A->Handler A: FINAL
Handler A->Client Code: final
Client Code->Handler A: close pipe
Client Code->Adapter A: success
Adapter A->Server: SUCCESS
 *
 */

public class CtpFClient extends CtpClient {
	protected TaskRun currTask = null;
	protected CtpStreamSource readStream = null;

	// when using this be sure to issue "read()" in callback
	public void selectFiles(FileSelection sel, FuncCallback<RecordStruct> cb) {
		RequestCommand cmd = new RequestCommand();

		RecordStruct params = new RecordStruct(
				new FieldStruct("Op", CtpConstants.CTP_F_OP_SELECT),
				new FieldStruct("Select", sel.toInstructions())
		);

		cmd.setBody(params);

		try {
			this.adapter.sendCommand(cmd, cb);
		}
		catch (Exception x) {
			System.out.println("ctp client send error: " + x);
		}
	}

	public void handle(CtpCommand cmd, CtpAdapter adapter) throws Exception {
		OperationContext ctx = adapter.getContext();

		ctx.touch();

		//System.out.println("Client got command: " + cmd.getCmdCode());

		if (cmd instanceof ProgressCommand) {
			if (ctx != null) {
				// put the call back into the work pool, don't tie up the IO thread
				Task t = new Task()
					.withContext(ctx.subContext())
					.withWork(new IWork() {
						@Override
						public void run(TaskRun trun) {
							trun.getContext().setAmountCompleted(((ProgressCommand)cmd).getAmount());

							adapter.read();

							trun.complete();
						}
					});

				Hub.instance.getWorkPool().submit(t);
			}

			return;
		}

		if (cmd.getCmdCode() == CtpConstants.CTP_F_CMD_STREAM_FINAL) {
			//System.out.println("Client got Final!");
			TaskRun brun = this.currTask;
			CtpStreamSource src = this.readStream;

			if (brun == null) {
				System.out.println("Client READ error, missing task!!!!! " + ((BlockCommand) cmd).getPath());
			}
			else if (src == null) {
				System.out.println("Client READ error, missing src!!!!! " + ((BlockCommand) cmd).getPath());
			}
			else {
				src.setFinal();

				brun.resume();
			}

			return;
		}

		if (cmd instanceof BlockCommand) {
			//System.out.println("Client got block: " + ((BlockCommand) cmd).getPath());
			//System.out.println("Client got block - is folder: " + ((BlockCommand) cmd).isFolder());
			//System.out.println("Client got block - size: " + ((BlockCommand) cmd).getSize());

			TaskRun brun = this.currTask;
			CtpStreamSource src = this.readStream;

			if (brun == null) {
				System.out.println("Client READ error, missing task!!!!! " + ((BlockCommand) cmd).getPath());
			}
			else if (src == null) {
				System.out.println("Client READ error, missing src!!!!! " + ((BlockCommand) cmd).getPath());
			}
			else {
				src.addNext((BlockCommand)cmd);

				brun.resume();

				/*
			Task t = new Task()
				.withRootContext()		// TODO use session context
				.withWork(new IWork() {
					@Override
					public void run(TaskRun trun) {
						if (((BlockCommand) cmd).getData() == null)
							System.out.println("Client processed empty block");
						else
							System.out.println("Client processed block: " + ((BlockCommand) cmd).getData().readableBytes());

						adapter.read();

						cmd.release();

						trun.complete();
					}
				});
				*/
			}

			return;
		}

		// get more, unless a stream command - then let it handle automatically
		/*
		if (!(cmd instanceof IStreamCommand)) {
			adapter.read();

			cmd.release();
		}
		*/
	}

	public void writeFrom(OperationCallback cb, IStream... strm) {
		OperationContext ctx = this.adapter.getContext();

		ctx.setAmountCompleted(0);

		Task t = new Task()
			.withSubContext()
			.withTitle("Stream Write");

		@SuppressWarnings("resource")
		IStreamDest writeStream = new CtpStreamDest(this.adapter, t.getContext());

		t.withObserver(new OperationObserver() {
			@Override
			public void completed(OperationContext or) {
				//System.out.println("READ server is complete!!");
				//System.out.println("Context 3: " + OperationContext.get().getOpId());

				/*
				try {
					CtpFClient.this.adapter.sendCommand(new ResponseCommand());
				}
				catch (Exception x) {
					System.out.println("Unable to send SUCCESS for READ: " + x);
				}
				*/

				cb.callback();
			}
		});

		IStream[] tstrm = new IStream[strm.length + 1];

		for (int i = 0; i < strm.length; i++)
			tstrm[i] = strm[i];

		tstrm[strm.length] = writeStream;

		//System.out.println("strm 0: " + tstrm[0]);
		//System.out.println("strm 1: " + tstrm[1]);

		TaskRun trun = StreamUtil.composeStream(t, tstrm);

		this.currTask = trun;

		trun.resume();

		// we can read while writing
		this.adapter.read();
	}

	public void readTo(OperationCallback cb, IStream... strm) {
		//System.out.println("Context 2: " + OperationContext.get().getOpId());

		OperationContext ctx = this.adapter.getContext();

		ctx.setAmountCompleted(0);

		this.readStream = new CtpStreamSource(this.adapter);

		Task t = new Task()
			.withSubContext()
			.withTitle("Stream Read");

		t.withObserver(new OperationObserver() {
			@Override
			public void completed(OperationContext or) {
				//System.out.println("WRITE client is complete!!");
				//System.out.println("Context 3: " + OperationContext.get().getOpId());

				/*
				try {
					CtpFClient.this.adapter.sendCommand(new ResponseCommand());
				}
				catch (Exception x) {
					System.out.println("Unable to send SUCCESS for READ: " + x);
				}
				*/

				cb.callback();

				adapter.read();
			}
		});

		IStream[] tstrm = new IStream[strm.length + 1];

		tstrm[0] = this.readStream;

		for (int i = 1; i < tstrm.length; i++)
			tstrm[i] = strm[i - 1];

		//System.out.println("strm 0: " + tstrm[0]);
		//System.out.println("strm 1: " + tstrm[1]);

		TaskRun trun = StreamUtil.composeStream(t, tstrm);

		this.currTask = trun;

		trun.resume();
	}

	@Override
	public void connect(String host, int port, OperationCallback connCallback) {
		//System.out.println("Context 1: " + OperationContext.get().getOpId());

		super.connect(host, port, new OperationCallback() {
			@Override
			public void callback() {
				adapter.setMapper(CtpfCommandMapper.instance);

				/* TODO ???
			    CtpFClient.this.sendCommand(new InitCommand(), new FuncCallback<RecordStruct>() {
					@Override
					public void callback() {

					    System.out.println("Ctp F Client - Init complete");

					    adapter.read();

					    connCallback.complete();
					}
				});

				*/

			    System.out.println("Ctp F Client - Init complete");

			    adapter.read();

			    connCallback.complete();
			}
		});
	}

	public void folderListing(String path) {
        FileSelection sel = new FileSelection()
	    	.withMode(FileSelectionMode.Listing)
	    	.withFileSet(path)
	    	.withAttrs(CtpConstants.CTP_F_ATTR_PREFERED);

	    try {
	    	this.selectFiles(sel, new FuncCallback<RecordStruct>() {
				@Override
				public void callback() {
					//System.out.println("Context 4: " + OperationContext.get().getOpId());
					if (this.hasErrors()) {
						System.out.println("Failed Selection: " + this.getMessage());

						adapter.read();		// TODO or close?
						return;
					}

					try {
						//ctpf.sendCommand(new ReadCommand());
		            	CtpFClient.this.readTo(new OperationCallback() {
							@Override
							public void callback() {
								//System.out.println("Context 5: " + OperationContext.get().getOpId());

								System.out.println("Directory listing completed!");
							}
						},
						new FolderDumpStream());
					}
					catch (Exception x) {
						System.out.println("Ctp-F Client cb error: " + x);
					}

					adapter.read();		// get that folder listing
				}
			});
		}
		catch (Exception x) {
			System.out.println("Ctp-F Client error: " + x);
		}
	}

	@Override
	public void close() {
		System.out.println("Client Connection closed");
	}

	static public void utilityMenu(Scanner scan) {
		OperationContext ctx = OperationContext.get();

		IOperationObserver oo = new OperationObserver() {
			@Override
			public void amount(OperationContext ctx, int v) {
				System.out.println("Progress: " + v);
			}
		};

		ctx.addObserver(oo);

		CtpFClient ctpf = new CtpFClient();

		CountDownLatch cdl = new CountDownLatch(1);

		ctpf.connect("localhost", 8181, new OperationCallback() {
			@Override
			public void callback() {
				cdl.countDown();
			}
		});

		try {
			cdl.await();
		}
		catch (InterruptedException x) {
			System.out.println("Error connecting: " + x);
			return;
		}

		boolean running = true;

		while(running) {
			try {
				System.out.println();
				System.out.println("-----------------------------------------------");
				System.out.println("   Hub " + Hub.instance.getResources().getHubId() + " Utility Menu");
				System.out.println("-----------------------------------------------");
				System.out.println("0)  Exit");
				System.out.println("1)  ls on karabiner");
				System.out.println("2)  Folder Listing");
				System.out.println("3)  Test Download");
				System.out.println("4)  Test Upload");

				String opt = scan.nextLine();

				Long mopt = StringUtil.parseInt(opt);

				if (mopt == null)
					continue;

				switch (mopt.intValue()) {
				case 0:
					ctpf.sendCommand(SimpleCommand.EXIT_SIGN_OUT);
					running = false;
					break;
				case 1: {
					ctpf.folderListing("/User/karabiner");
					break;
				}
				case 2: {
					System.out.println("Folder to list: ");
					ctpf.folderListing(scan.nextLine());
					break;
				}
				case 3: {
		            FileSelection sel = new FileSelection()
		            	.withMode(FileSelectionMode.Expanded)
		            	.withFileSet("/User/Salt/long score 3.txt.out")
		            	.withAttrs(CtpConstants.CTP_F_ATTR_PREFERED, CtpConstants.CTP_F_ATTR_DATA);

		            try {
		            	ctpf.selectFiles(sel,
		            			new FuncCallback<RecordStruct>() {
				    				@Override
				    				public void callback() {
				    					if (this.hasErrors()) {
				    						System.out.println("Failed Selection: " + this.getMessage());

				    						ctpf.read();		// TODO or close?
				    						return;
				    					}

				    					//System.out.println("Context 9: " + OperationContext.get().getOpId());

				    					try {
				    		            	ctpf.readTo(new OperationCallback() {
				    							@Override
				    							public void callback() {
				    								//System.out.println("Context 10: " + OperationContext.get().getOpId());

				    								System.out.println("Download completed!");
				    							}
				    						},
				    						new NullStream());
				    					}
				    					catch (Exception x) {
				    						System.out.println("Ctp-F Client cb error: " + x);
				    					}

				    					ctpf.read();		// get that folder listing
				    				}
				    			});
					}
					catch (Exception x) {
						System.out.println("Ctp-F Client error: " + x);
					}

					break;
				}
				case 4: {
					@SuppressWarnings("resource")
					FileSystemDriver fsd = new FileSystemDriver();
					fsd.setRootFolder("/Work/Temp/Dest/x");

					FileSelection sel = new FileSelection()
						.withFileSet("/cc-logo-sm.png");

					ctpf.writeFrom(new OperationCallback() {
							@Override
							public void callback() {
								//System.out.println("Context 10: " + OperationContext.get().getOpId());

								System.out.println("Upload completed!");
							}
						},
						new FileSourceStream(fsd.select(sel)));

					break;
				}
				}
			}
			catch(Exception x) {
				System.out.println("CLI error: " + x);
			}
		}

		ctx.removeObserver(oo);
	}

}