text:
from __future__ import print_function, absolute_import, division

import datetime
import base64
import binascii
import re
import sys
import types
import warnings

from ruamel_yaml.error import (MarkedYAMLError, MarkedYAMLFutureWarning,
                               MantissaNoDotYAML1_1Warning)
from ruamel_yaml.nodes import *                               # NOQA
from ruamel_yaml.nodes import (SequenceNode, MappingNode, ScalarNode)
from ruamel_yaml.compat import (utf8, builtins_module, to_str, PY2, PY3,  # NOQA
                                ordereddict, text_type, nprint, version_tnf, Hashable)
from ruamel_yaml.comments import *                               # NOQA
from ruamel_yaml.comments import (CommentedMap, CommentedOrderedMap, CommentedSet,
                                  CommentedKeySeq, CommentedSeq, TaggedScalar)
from ruamel_yaml.scalarstring import *                           # NOQA
from ruamel_yaml.scalarstring import (PreservedScalarString, SingleQuotedScalarString,
                                      DoubleQuotedScalarString, ScalarString)
from ruamel_yaml.scalarint import ScalarInt, BinaryInt, OctalInt, HexInt, HexCapsInt
from ruamel_yaml.scalarfloat import ScalarFloat
from ruamel_yaml.timestamp import TimeStamp
from ruamel_yaml.util import RegExp

if False:  # MYPY
    from typing import Any, Dict, List, Set, Generator  # NOQA

__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
           'ConstructorError', 'RoundTripConstructor']

class ConstructorError(MarkedYAMLError):
    pass

class DuplicateKeyFutureWarning(MarkedYAMLFutureWarning):
    pass

class DuplicateKeyError(MarkedYAMLFutureWarning):
    pass

class BaseConstructor(object):

    yaml_constructors = {}   # type: Dict[Any, Any]
    yaml_multi_constructors = {}   # type: Dict[Any, Any]

    def __init__(self, preserve_quotes=None, loader=None):
        # type: (bool, Any) -> None
        self.loader = loader
        if self.loader is not None and getattr(self.loader, '_constructor', None) is None:
            self.loader._constructor = self
        self.loader = loader
        self.constructed_objects = {}  # type: Dict[Any, Any]
        self.recursive_objects = {}  # type: Dict[Any, Any]
        self.state_generators = []  # type: List[Any]
        self.deep_construct = False
        self._preserve_quotes = preserve_quotes
        self.allow_duplicate_keys = version_tnf((0, 15, 1), (0, 16))

    @property
    def composer(self):
        # type: () -> Any
        if hasattr(self.loader, 'typ'):
            return self.loader.composer  # type: ignore
        try:
            return self.loader._composer  # type: ignore
        except AttributeError:
            print('slt', type(self))
            print('slc', self.loader._composer)  # type: ignore
            print(dir(self))
            raise

    @property
    def resolver(self):
        # type: () -> Any
        if hasattr(self.loader, 'typ'):
            return self.loader.resolver  # type: ignore
        return self.loader._resolver  # type: ignore

    def check_data(self):
        # type: () -> Any
        # If there are more documents available?
        return self.composer.check_node()

    def get_data(self):
        # type: () -> Any
        # Construct and return the next document.
        if self.composer.check_node():
            return self.construct_document(self.composer.get_node())

    def get_single_data(self):
        # type: () -> Any
        # Ensure that the stream contains a single document and construct it.
        node = self.composer.get_single_node()
        if node is not None:
            return self.construct_document(node)
        return None

    def construct_document(self, node):
        # type: (Any) -> Any
        data = self.construct_object(node)
        while bool(self.state_generators):
            state_generators = self.state_generators
            self.state_generators = []
            for generator in state_generators:
                for dummy in generator:
                    pass
        self.constructed_objects = {}
        self.recursive_objects = {}
        self.deep_construct = False
        return data

    def construct_object(self, node, deep=False):
        # type: (Any, bool) -> Any
        """deep is True when creating an object/mapping recursively,
        in that case want the underlying elements available during construction
        """
        if node in self.constructed_objects:
            return self.constructed_objects[node]
        if deep:
            old_deep = self.deep_construct
            self.deep_construct = True
        if node in self.recursive_objects:
            raise ConstructorError(
                None, None,
                "found unconstructable recursive node", node.start_mark)
        self.recursive_objects[node] = None
        constructor = None  # type: Any
        tag_suffix = None
        if node.tag in self.yaml_constructors:
            constructor = self.yaml_constructors[node.tag]
        else:
            for tag_prefix in self.yaml_multi_constructors:
                if node.tag.startswith(tag_prefix):
                    tag_suffix = node.tag[len(tag_prefix):]
                    constructor = self.yaml_multi_constructors[tag_prefix]
                    break
            else:
                if None in self.yaml_multi_constructors:
                    tag_suffix = node.tag
                    constructor = self.yaml_multi_constructors[None]
                elif None in self.yaml_constructors:
                    constructor = self.yaml_constructors[None]
                elif isinstance(node, ScalarNode):
                    constructor = self.__class__.construct_scalar  # type: ignore
                elif isinstance(node, SequenceNode):
                    constructor = self.__class__.construct_sequence  # type: ignore
                elif isinstance(node, MappingNode):
                    constructor = self.__class__.construct_mapping   # type: ignore
        if tag_suffix is None:
            data = constructor(self, node)
        else:
            data = constructor(self, tag_suffix, node)
        if isinstance(data, types.GeneratorType):
            generator = data
            data = next(generator)  # type: ignore
            if self.deep_construct:
                for dummy in generator:  # type: ignore
                    pass
            else:
                self.state_generators.append(generator)
        self.constructed_objects[node] = data
        del self.recursive_objects[node]
        if deep:
            self.deep_construct = old_deep
        return data

    def construct_scalar(self, node):
        # type: (Any) -> Any
        if not isinstance(node, ScalarNode):
            raise ConstructorError(
                None, None,
                "expected a scalar node, but found %s" % node.id,
                node.start_mark)
        return node.value

    def construct_sequence(self, node, deep=False):
        # type: (Any, bool) -> Any
        """deep is True when creating an object/mapping recursively,
        in that case want the underlying elements available during construction
        """
        if not isinstance(node, SequenceNode):
            raise ConstructorError(
                None, None,
                "expected a sequence node, but found %s" % node.id,
                node.start_mark)
        return [self.construct_object(child, deep=deep)
                for child in node.value]

    def construct_mapping(self, node, deep=False):
        # type: (Any, bool) -> Any
        """deep is True when creating an object/mapping recursively,
        in that case want the underlying elements available during construction
        """
        if not isinstance(node, MappingNode):
            raise ConstructorError(
                None, None,
                "expected a mapping node, but found %s" % node.id,
                node.start_mark)
        total_mapping = {}
        if getattr(node, 'merge', None) is not None:
            todo = [(node.merge, False), (node.value, False)]
        else:
            todo = [(node.value, True)]
        for values, check in todo:
            mapping = {}  # type: Dict[Any, Any]
            for key_node, value_node in values:
                # keys can be list -> deep
                key = self.construct_object(key_node, deep=True)
                # lists are not hashable, but tuples are
                if not isinstance(key, Hashable):
                    if isinstance(key, list):
                        key = tuple(key)
                if PY2:
                    try:
                        hash(key)
                    except TypeError as exc:
                        raise ConstructorError(
                            "while constructing a mapping", node.start_mark,
                            "found unacceptable key (%s)" %
                            exc, key_node.start_mark)
                else:
                    if not isinstance(key, Hashable):
                        raise ConstructorError(
                            "while constructing a mapping", node.start_mark,
                            "found unhashable key", key_node.start_mark)

                value = self.construct_object(value_node, deep=deep)
                if check:
                    self.check_mapping_key(node, key_node, mapping, key, value)
                mapping[key] = value
            total_mapping.update(mapping)
        return total_mapping

    def check_mapping_key(self, node, key_node, mapping, key, value):
        # type: (Any, Any, Any, Any, Any) -> None
        if key in mapping:
            if not self.allow_duplicate_keys:
                args = [
                    "while constructing a mapping", node.start_mark,
                    'found duplicate key "{}" with value "{}" '
                    '(original value: "{}")'.format(
                        key, value, mapping.get(key)), key_node.start_mark,
                    """
                    To suppress this check see:
                        http://yaml.readthedocs.io/en/latest/api.html#duplicate-keys
                    """,
                    """\
                    Duplicate keys will become an error in future releases, and are errors
                    by default when using the new API.
                    """,
                ]
                if self.allow_duplicate_keys is None:
                    warnings.warn(DuplicateKeyFutureWarning(*args))
                else:
                    raise DuplicateKeyError(*args)

    def construct_pairs(self, node, deep=False):
        # type: (Any, bool) -> Any
        if not isinstance(node, MappingNode):
            raise ConstructorError(
                None, None,
                "expected a mapping node, but found %s" % node.id,
                node.start_mark)
        pairs = []
        for key_node, value_node in node.value:
            key = self.construct_object(key_node, deep=deep)
            value = self.construct_object(value_node, deep=deep)
            pairs.append((key, value))
        return pairs

    @classmethod
    def add_constructor(cls, tag, constructor):
        # type: (Any, Any) -> None
        if 'yaml_constructors' not in cls.__dict__:
            cls.yaml_constructors = cls.yaml_constructors.copy()
        cls.yaml_constructors[tag] = constructor

    @classmethod
    def add_multi_constructor(cls, tag_prefix, multi_constructor):
        # type: (Any, Any) -> None
        if 'yaml_multi_constructors' not in cls.__dict__:
            cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
        cls.yaml_multi_constructors[tag_prefix] = multi_constructor

class SafeConstructor(BaseConstructor):
    def construct_scalar(self, node):
        # type: (Any) -> Any
        if isinstance(node, MappingNode):
            for key_node, value_node in node.value:
                if key_node.tag == u'tag:yaml.org,2002:value':
                    return self.construct_scalar(value_node)
        return BaseConstructor.construct_scalar(self, node)

    def flatten_mapping(self, node):
        # type: (Any) -> Any
        """
        This implements the merge key feature http://yaml.org/type/merge.html
        by inserting keys from the merge dict/list of dicts if not yet
        available in this node
        """
        merge = []  # type: List[Any]
        index = 0
        while index < len(node.value):
            key_node, value_node = node.value[index]
            if key_node.tag == u'tag:yaml.org,2002:merge':
                del node.value[index]
                if isinstance(value_node, MappingNode):
                    self.flatten_mapping(value_node)
                    merge.extend(value_node.value)
                elif isinstance(value_node, SequenceNode):
                    submerge = []
                    for subnode in value_node.value:
                        if not isinstance(subnode, MappingNode):
                            raise ConstructorError(
                                "while constructing a mapping",
                                node.start_mark,
                                "expected a mapping for merging, but found %s"
                                % subnode.id, subnode.start_mark)
                        self.flatten_mapping(subnode)
                        submerge.append(subnode.value)
                    submerge.reverse()
                    for value in submerge:
                        merge.extend(value)
                else:
                    raise ConstructorError(
                        "while constructing a mapping", node.start_mark,
                        "expected a mapping or list of mappings for merging, "
                        "but found %s"
                        % value_node.id, value_node.start_mark)
            elif key_node.tag == u'tag:yaml.org,2002:value':
                key_node.tag = u'tag:yaml.org,2002:str'
                index += 1
            else:
                index += 1
        if bool(merge):
            node.merge = merge  # separate merge keys to be able to update without duplicate
            node.value = merge + node.value

    def construct_mapping(self, node, deep=False):
        # type: (Any, bool) -> Any
        """deep is True when creating an object/mapping recursively,
        in that case want the underlying elements available during construction
        """
        if isinstance(node, MappingNode):
            self.flatten_mapping(node)
        return BaseConstructor.construct_mapping(self, node, deep=deep)

    def construct_yaml_null(self, node):
        # type: (Any) -> Any
        self.construct_scalar(node)
        return None

    # YAML 1.2 spec doesn't mention yes/no etc any more, 1.1 does
    bool_values = {
        u'yes': True,
        u'no': False,
        u'true': True,
        u'false': False,
        u'on': True,
        u'off': False,
    }

    def construct_yaml_bool(self, node):
        # type: (Any) -> bool
        value = self.construct_scalar(node)
        return self.bool_values[value.lower()]

    def construct_yaml_int(self, node):
        # type: (Any) -> int
        value_s = to_str(self.construct_scalar(node))
        value_s = value_s.replace('_', '')
        sign = +1
        if value_s[0] == '-':
            sign = -1
        if value_s[0] in '+-':
            value_s = value_s[1:]
        if value_s == '0':
            return 0
        elif value_s.startswith('0b'):
            return sign * int(value_s[2:], 2)
        elif value_s.startswith('0x'):
            return sign * int(value_s[2:], 16)
        elif value_s.startswith('0o'):
            return sign * int(value_s[2:], 8)
        elif self.resolver.processing_version != (1, 2) and value_s[0] == '0':
            return sign * int(value_s, 8)
        elif self.resolver.processing_version != (1, 2) and ':' in value_s:
            digits = [int(part) for part in value_s.split(':')]
            digits.reverse()
            base = 1
            value = 0
            for digit in digits:
                value += digit * base
                base *= 60
            return sign * value
        else:
            return sign * int(value_s)

    inf_value = 1e300
    while inf_value != inf_value * inf_value:
        inf_value *= inf_value
    nan_value = -inf_value / inf_value   # Trying to make a quiet NaN (like C99).

    def construct_yaml_float(self, node):
        # type: (Any) -> float
        value_so = to_str(self.construct_scalar(node))
        value_s = value_so.replace('_', '').lower()
        sign = +1
        if value_s[0] == '-':
            sign = -1
        if value_s[0] in '+-':
            value_s = value_s[1:]
        if value_s == '.inf':
            return sign * self.inf_value
        elif value_s == '.nan':
            return self.nan_value
        elif self.resolver.processing_version != (1, 2) and ':' in value_s:
            digits = [float(part) for part in value_s.split(':')]
            digits.reverse()
            base = 1
            value = 0.0
            for digit in digits:
                value += digit * base
                base *= 60
            return sign * value
        else:
            if self.resolver.processing_version != (1, 2) and 'e' in value_s:
                # value_s is lower case independent of input
                mantissa, exponent = value_s.split('e')
                if '.' not in mantissa:
                    warnings.warn(MantissaNoDotYAML1_1Warning(node, value_so))
            return sign * float(value_s)

    if PY3:
        def construct_yaml_binary(self, node):
            # type: (Any) -> Any
            try:
                value = self.construct_scalar(node).encode('ascii')
            except UnicodeEncodeError as exc:
                raise ConstructorError(
                    None, None,
                    "failed to convert base64 data into ascii: %s" % exc,
                    node.start_mark)
            try:
                if hasattr(base64, 'decodebytes'):
                    return base64.decodebytes(value)
                else:
                    return base64.decodestring(value)
            except binascii.Error as exc:
                raise ConstructorError(
                    None, None,
                    "failed to decode base64 data: %s" % exc, node.start_mark)
    else:
        def construct_yaml_binary(self, node):
            # type: (Any) -> Any
            value = self.construct_scalar(node)
            try:
                return to_str(value).decode('base64')
            except (binascii.Error, UnicodeEncodeError) as exc:
                raise ConstructorError(
                    None, None,
                    "failed to decode base64 data: %s" % exc, node.start_mark)

    timestamp_regexp = RegExp(
        u'''^(?P<year>[0-9][0-9][0-9][0-9])
          -(?P<month>[0-9][0-9]?)
          -(?P<day>[0-9][0-9]?)
          (?:((?P<t>[Tt])|[ \\t]+)   # explictly not retaining extra spaces
          (?P<hour>[0-9][0-9]?)
          :(?P<minute>[0-9][0-9])
          :(?P<second>[0-9][0-9])
          (?:\\.(?P<fraction>[0-9]*))?
          (?:[ \\t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
          (?::(?P<tz_minute>[0-9][0-9]))?))?)?$''', re.X)

    def construct_yaml_timestamp(self, node, values=None):
        # type: (Any, Any) -> Any
        if values is None:
            try:
                match = self.timestamp_regexp.match(node.value)
            except TypeError:
                match = None
            if match is None:
                raise ConstructorError(
                    None, None,
                    'failed to construct timestamp from "{}"'.format(node.value),
                    node.start_mark)
            values = match.groupdict()
        year = int(values['year'])
        month = int(values['month'])
        day = int(values['day'])
        if not values['hour']:
            return datetime.date(year, month, day)
        hour = int(values['hour'])
        minute = int(values['minute'])
        second = int(values['second'])
        fraction = 0
        if values['fraction']:
            fraction_s = values['fraction'][:6]
            while len(fraction_s) < 6:
                fraction_s += '0'
            fraction = int(fraction_s)
            if len(values['fraction']) > 6 and int(values['fraction'][6]) > 4:
                fraction += 1
        delta = None
        if values['tz_sign']:
            tz_hour = int(values['tz_hour'])
            minutes = values['tz_minute']
            tz_minute = int(minutes) if minutes else 0
            delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
            if values['tz_sign'] == '-':
                delta = -delta
        data = datetime.datetime(year, month, day, hour, minute, second,
                                 fraction)
        if delta:
            data -= delta
        return data

    def construct_yaml_omap(self, node):
        # type: (Any) -> Any
        # Note: we do now check for duplicate keys
        omap = ordereddict()
        yield omap
        if not isinstance(node, SequenceNode):
            raise ConstructorError(
                "while constructing an ordered map", node.start_mark,
                "expected a sequence, but found %s" % node.id, node.start_mark)
        for subnode in node.value:
            if not isinstance(subnode, MappingNode):
                raise ConstructorError(
                    "while constructing an ordered map", node.start_mark,
                    "expected a mapping of length 1, but found %s" %
                    subnode.id,
                    subnode.start_mark)
            if len(subnode.value) != 1:
                raise ConstructorError(
                    "while constructing an ordered map", node.start_mark,
                    "expected a single mapping item, but found %d items" %
                    len(subnode.value),
                    subnode.start_mark)
            key_node, value_node = subnode.value[0]
            key = self.construct_object(key_node)
            assert key not in omap
            value = self.construct_object(value_node)
            omap[key] = value

    def construct_yaml_pairs(self, node):
        # type: (Any) -> Any
        # Note: the same code as `construct_yaml_omap`.
        pairs = []  # type: List[Any]
        yield pairs
        if not isinstance(node, SequenceNode):
            raise ConstructorError(
                "while constructing pairs", node.start_mark,
                "expected a sequence, but found %s" % node.id, node.start_mark)
        for subnode in node.value:
            if not isinstance(subnode, MappingNode):
                raise ConstructorError(
                    "while constructing pairs", node.start_mark,
                    "expected a mapping of length 1, but found %s" %
                    subnode.id,
                    subnode.start_mark)
            if len(subnode.value) != 1:
                raise ConstructorError(
                    "while constructing pairs", node.start_mark,
                    "expected a single mapping item, but found %d items" %
                    len(subnode.value),
                    subnode.start_mark)
            key_node, value_node = subnode.value[0]
            key = self.construct_object(key_node)
            value = self.construct_object(value_node)
            pairs.append((key, value))

    def construct_yaml_set(self, node):
        # type: (Any) -> Any
        data = set()    # type: Set[Any]
        yield data
        value = self.construct_mapping(node)
        data.update(value)

    def construct_yaml_str(self, node):
        # type: (Any) -> Any
        value = self.construct_scalar(node)
        if PY3:
            return value
        try:
            return value.encode('ascii')
        except UnicodeEncodeError:
            return value

    def construct_yaml_seq(self, node):
        # type: (Any) -> Any
        data = []  # type: List[Any]
        yield data
        data.extend(self.construct_sequence(node))

    def construct_yaml_map(self, node):
        # type: (Any) -> Any
        data = {}  # type: Dict[Any, Any]
        yield data
        value = self.construct_mapping(node)
        data.update(value)

    def construct_yaml_object(self, node, cls):
        # type: (Any, Any) -> Any
        data = cls.__new__(cls)
        yield data
        if hasattr(data, '__setstate__'):
            state = self.construct_mapping(node, deep=True)
            data.__setstate__(state)
        else:
            state = self.construct_mapping(node)
            data.__dict__.update(state)

    def construct_undefined(self, node):
        # type: (Any) -> None
        raise ConstructorError(
            None, None,
            "could not determine a constructor for the tag %r" %
            utf8(node.tag),
            node.start_mark)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:null',
    SafeConstructor.construct_yaml_null)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:bool',
    SafeConstructor.construct_yaml_bool)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:int',
    SafeConstructor.construct_yaml_int)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:float',
    SafeConstructor.construct_yaml_float)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:binary',
    SafeConstructor.construct_yaml_binary)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:timestamp',
    SafeConstructor.construct_yaml_timestamp)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:omap',
    SafeConstructor.construct_yaml_omap)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:pairs',
    SafeConstructor.construct_yaml_pairs)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:set',
    SafeConstructor.construct_yaml_set)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:str',
    SafeConstructor.construct_yaml_str)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:seq',
    SafeConstructor.construct_yaml_seq)

SafeConstructor.add_constructor(
    u'tag:yaml.org,2002:map',
    SafeConstructor.construct_yaml_map)

SafeConstructor.add_constructor(
    None, SafeConstructor.construct_undefined)

if PY2:
    class classobj:
        pass

class Constructor(SafeConstructor):

    def construct_python_str(self, node):
        # type: (Any) -> Any
        return utf8(self.construct_scalar(node))

    def construct_python_unicode(self, node):
        # type: (Any) -> Any
        return self.construct_scalar(node)

    if PY3:
        def construct_python_bytes(self, node):
            # type: (Any) -> Any
            try:
                value = self.construct_scalar(node).encode('ascii')
            except UnicodeEncodeError as exc:
                raise ConstructorError(
                    None, None,
                    "failed to convert base64 data into ascii: %s" % exc,
                    node.start_mark)
            try:
                if hasattr(base64, 'decodebytes'):
                    return base64.decodebytes(value)
                else:
                    return base64.decodestring(value)
            except binascii.Error as exc:
                raise ConstructorError(
                    None, None,
                    "failed to decode base64 data: %s" % exc, node.start_mark)

    def construct_python_long(self, node):
        # type: (Any) -> int
        val = self.construct_yaml_int(node)
        if PY3:
            return val
        return int(val)

    def construct_python_complex(self, node):
        # type: (Any) -> Any
        return complex(self.construct_scalar(node))

    def construct_python_tuple(self, node):
        # type: (Any) -> Any
        return tuple(self.construct_sequence(node))

    def find_python_module(self, name, mark):
        # type: (Any, Any) -> Any
        if not name:
            raise ConstructorError(
                "while constructing a Python module", mark,
                "expected non-empty name appended to the tag", mark)
        try:
            __import__(name)
        except ImportError as exc:
            raise ConstructorError(
                "while constructing a Python module", mark,
                "cannot find module %r (%s)" % (utf8(name), exc), mark)
        return sys.modules[name]

    def find_python_name(self, name, mark):
        # type: (Any, Any) -> Any
        if not name:
            raise ConstructorError(
                "while constructing a Python object", mark,
                "expected non-empty name appended to the tag", mark)
        if u'.' in name:
            module_name, object_name = name.rsplit('.', 1)
        else:
            module_name = builtins_module
            object_name = name
        try:
            __import__(module_name)
        except ImportError as exc:
            raise ConstructorError(
                "while constructing a Python object", mark,
                "cannot find module %r (%s)" % (utf8(module_name), exc), mark)
        module = sys.modules[module_name]
        if not hasattr(module, object_name):
            raise ConstructorError(
                "while constructing a Python object", mark,
                "cannot find %r in the module %r" % (utf8(object_name),
                                                     module.__name__), mark)
        return getattr(module, object_name)

    def construct_python_name(self, suffix, node):
        # type: (Any, Any) -> Any
        value = self.construct_scalar(node)
        if value:
            raise ConstructorError(
                "while constructing a Python name", node.start_mark,
                "expected the empty value, but found %r" % utf8(value),
                node.start_mark)
        return self.find_python_name(suffix, node.start_mark)

    def construct_python_module(self, suffix, node):
        # type: (Any, Any) -> Any
        value = self.construct_scalar(node)
        if value:
            raise ConstructorError(
                "while constructing a Python module", node.start_mark,
                "expected the empty value, but found %r" % utf8(value),
                node.start_mark)
        return self.find_python_module(suffix, node.start_mark)

    def make_python_instance(self, suffix, node,
                             args=None, kwds=None, newobj=False):
        # type: (Any, Any, Any, Any, bool) -> Any
        if not args:
            args = []
        if not kwds:
            kwds = {}
        cls = self.find_python_name(suffix, node.start_mark)
        if PY3:
            if newobj and isinstance(cls, type):
                return cls.__new__(cls, *args, **kwds)
            else:
                return cls(*args, **kwds)
        else:
            if newobj and isinstance(cls, type(classobj))  \
                    and not args and not kwds:
                instance = classobj()
                instance.__class__ = cls
                return instance
            elif newobj and isinstance(cls, type):
                return cls.__new__(cls, *args, **kwds)
            else:
                return cls(*args, **kwds)

    def set_python_instance_state(self, instance, state):
        # type: (Any, Any) -> None
        if hasattr(instance, '__setstate__'):
            instance.__setstate__(state)
        else:
            slotstate = {}  # type: Dict[Any, Any]
            if isinstance(state, tuple) and len(state) == 2:
                state, slotstate = state
            if hasattr(instance, '__dict__'):
                instance.__dict__.update(state)
            elif state:
                slotstate.update(state)
            for key, value in slotstate.items():
                setattr(object, key, value)

    def construct_python_object(self, suffix, node):
        # type: (Any, Any) -> Any
        # Format:
        #   !!python/object:module.name { ... state ... }
        instance = self.make_python_instance(suffix, node, newobj=True)
        yield instance
        deep = hasattr(instance, '__setstate__')
        state = self.construct_mapping(node, deep=deep)
        self.set_python_instance_state(instance, state)

    def construct_python_object_apply(self, suffix, node, newobj=False):
        # type: (Any, Any, bool) -> Any
        # Format:
        #   !!python/object/apply       # (or !!python/object/new)
        #   args: [ ... arguments ... ]
        #   kwds: { ... keywords ... }
        #   state: ... state ...
        #   listitems: [ ... listitems ... ]
        #   dictitems: { ... dictitems ... }
        # or short format:
        #   !!python/object/apply [ ... arguments ... ]
        # The difference between !!python/object/apply and !!python/object/new
        # is how an object is created, check make_python_instance for details.
        if isinstance(node, SequenceNode):
            args = self.construct_sequence(node, deep=True)
            kwds = {}  # type: Dict[Any, Any]
            state = {}  # type: Dict[Any, Any]
            listitems = []  # type: List[Any]
            dictitems = {}  # type: Dict[Any, Any]
        else:
            value = self.construct_mapping(node, deep=True)
            args = value.get('args', [])
            kwds = value.get('kwds', {})
            state = value.get('state', {})
            listitems = value.get('listitems', [])
            dictitems = value.get('dictitems', {})
        instance = self.make_python_instance(suffix, node, args, kwds, newobj)
        if bool(state):
            self.set_python_instance_state(instance, state)
        if bool(listitems):
            instance.extend(listitems)
        if bool(dictitems):
            for key in dictitems:
                instance[key] = dictitems[key]
        return instance

    def construct_python_object_new(self, suffix, node):
        # type: (Any, Any) -> Any
        return self.construct_python_object_apply(suffix, node, newobj=True)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/none',
    Constructor.construct_yaml_null)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/bool',
    Constructor.construct_yaml_bool)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/str',
    Constructor.construct_python_str)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/unicode',
    Constructor.construct_python_unicode)

if PY3:
    Constructor.add_constructor(
        u'tag:yaml.org,2002:python/bytes',
        Constructor.construct_python_bytes)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/int',
    Constructor.construct_yaml_int)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/long',
    Constructor.construct_python_long)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/float',
    Constructor.construct_yaml_float)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/complex',
    Constructor.construct_python_complex)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/list',
    Constructor.construct_yaml_seq)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/tuple',
    Constructor.construct_python_tuple)

Constructor.add_constructor(
    u'tag:yaml.org,2002:python/dict',
    Constructor.construct_yaml_map)

Constructor.add_multi_constructor(
    u'tag:yaml.org,2002:python/name:',
    Constructor.construct_python_name)

Constructor.add_multi_constructor(
    u'tag:yaml.org,2002:python/module:',
    Constructor.construct_python_module)

Constructor.add_multi_constructor(
    u'tag:yaml.org,2002:python/object:',
    Constructor.construct_python_object)

Constructor.add_multi_constructor(
    u'tag:yaml.org,2002:python/object/apply:',
    Constructor.construct_python_object_apply)

Constructor.add_multi_constructor(
    u'tag:yaml.org,2002:python/object/new:',
    Constructor.construct_python_object_new)

class RoundTripConstructor(SafeConstructor):
    """need to store the comments on the node itself,
    as well as on the items
    """

    def construct_scalar(self, node):
        # type: (Any) -> Any
        if not isinstance(node, ScalarNode):
            raise ConstructorError(
                None, None,
                "expected a scalar node, but found %s" % node.id,
                node.start_mark)

        if node.style == '|' and isinstance(node.value, text_type):
            return PreservedScalarString(node.value)
        elif bool(self._preserve_quotes) and isinstance(node.value, text_type):
            if node.style == "'":
                return SingleQuotedScalarString(node.value)
            if node.style == '"':
                return DoubleQuotedScalarString(node.value)
        return node.value

    def construct_yaml_int(self, node):
        # type: (Any) -> Any
        width = None  # type: Any
        value_su = to_str(self.construct_scalar(node))
        try:
            sx = value_su.rstrip('_')
            underscore = [len(sx) - sx.rindex('_') - 1, False, False]  # type: Any
        except ValueError:
            underscore = None
        except IndexError:
            underscore = None
        value_s = value_su.replace('_', '')
        sign = +1
        if value_s[0] == '-':
            sign = -1
        if value_s[0] in '+-':
            value_s = value_s[1:]
        if value_s == '0':
            return 0
        elif value_s.startswith('0b'):
            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
                width = len(value_s[2:])
            if underscore is not None:
                underscore[1] = value_su[2] == '_'
                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
            return BinaryInt(sign * int(value_s[2:], 2), width=width,   # type: ignore
                             underscore=underscore)
        elif value_s.startswith('0x'):
            # default to lower-case if no a-fA-F in string
            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
                width = len(value_s[2:])
            hex_fun = HexInt  # type: Any
            for ch in value_s[2:]:
                if ch in 'ABCDEF':  # first non-digit is capital
                    hex_fun = HexCapsInt
                    break
                if ch in 'abcdef':
                    break
            if underscore is not None:
                underscore[1] = value_su[2] == '_'
                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
            return hex_fun(sign * int(value_s[2:], 16), width=width, underscore=underscore)
        elif value_s.startswith('0o'):
            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
                width = len(value_s[2:])
            if underscore is not None:
                underscore[1] = value_su[2] == '_'
                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
            return OctalInt(sign * int(value_s[2:], 8), width=width,  # type: ignore
                            underscore=underscore)
        elif self.resolver.processing_version != (1, 2) and value_s[0] == '0':
            return sign * int(value_s, 8)
        elif self.resolver.processing_version != (1, 2) and ':' in value_s:
            digits = [int(part) for part in value_s.split(':')]
            digits.reverse()
            base = 1
            value = 0
            for digit in digits:
                value += digit * base
                base *= 60
            return sign * value
        elif self.resolver.processing_version > (1, 1) and value_s[0] == '0':
            # not an octal, an integer with leading zero(s)
            if underscore is not None:
                # cannot have a leading underscore
                underscore[2] = len(value_su) > 1 and value_su[-1] == '_'
            return ScalarInt(sign * int(value_s), width=len(value_s),  # type: ignore
                             underscore=underscore)
        elif underscore:
            # cannot have a leading underscore
            underscore[2] = len(value_su) > 1 and value_su[-1] == '_'
            return ScalarInt(sign * int(value_s), width=None,  # type: ignore
                             underscore=underscore)
        else:
            return sign * int(value_s)

    def construct_yaml_float(self, node):
        # type: (Any) -> Any
        def leading_zeros(v):
            # type: (Any) -> int
            lead0 = 0
            idx = 0
            while idx < len(v) and v[idx] in '0.':
                if v[idx] == '0':
                    lead0 += 1
                idx += 1
            return lead0
        # underscore = None
        m_sign = False  # type: Any
        value_so = to_str(self.construct_scalar(node))
        value_s = value_so.replace('_', '').lower()
        sign = +1
        if value_s[0] == '-':
            sign = -1
        if value_s[0] in '+-':
            m_sign = value_s[0]
            value_s = value_s[1:]
        if value_s == '.inf':
            return sign * self.inf_value
        if value_s == '.nan':
            return self.nan_value
        if self.resolver.processing_version != (1, 2) and ':' in value_s:
            digits = [float(part) for part in value_s.split(':')]
            digits.reverse()
            base = 1
            value = 0.0
            for digit in digits:
                value += digit * base
                base *= 60
            return sign * value
        if 'e' in value_s:
            try:
                mantissa, exponent = value_so.split('e')
                exp = 'e'
            except ValueError:
                mantissa, exponent = value_so.split('E')
                exp = 'E'
            if self.resolver.processing_version != (1, 2):
                # value_s is lower case independent of input
                if '.' not in mantissa:
                    warnings.warn(MantissaNoDotYAML1_1Warning(node, value_so))
            lead0 = leading_zeros(mantissa)
            width = len(mantissa)
            prec = mantissa.find('.')
            if m_sign:
                width -= 1
            e_width = len(exponent)
            e_sign = exponent[0] in '+-'
            # print('sf', width, prec, m_sign, exp, e_width, e_sign)
            return ScalarFloat(sign * float(value_s),  # type: ignore
                               width=width, prec=prec, m_sign=m_sign,
                               m_lead0=lead0, exp=exp, e_width=e_width, e_sign=e_sign)
        width = len(value_so)
        prec = value_so.index('.')  # you can use index, this would not be float without dot
        lead0 = leading_zeros(value_so)
        return ScalarFloat(sign * float(value_s),  # type: ignore
                           width=width, prec=prec, m_sign=m_sign, m_lead0=lead0)

    def construct_yaml_str(self, node):
        # type: (Any) -> Any
        value = self.construct_scalar(node)
        if isinstance(value, ScalarString):
            return value
        if PY3:
            return value
        try:
            return value.encode('ascii')
        except AttributeError:
            # in case you replace the node dynamically e.g. with a dict
            return value
        except UnicodeEncodeError:
            return value

    def construct_rt_sequence(self, node, seqtyp, deep=False):
        # type: (Any, Any, bool) -> Any
        if not isinstance(node, SequenceNode):
            raise ConstructorError(
                None, None,
                "expected a sequence node, but found %s" % node.id,
                node.start_mark)
        ret_val = []
        if node.comment:
            seqtyp._yaml_add_comment(node.comment[:2])
            if len(node.comment) > 2:
                seqtyp.yaml_end_comment_extend(node.comment[2], clear=True)
        if node.anchor:
            from ruamel_yaml.serializer import templated_id
            if not templated_id(node.anchor):
                seqtyp.yaml_set_anchor(node.anchor)
        for idx, child in enumerate(node.value):
            ret_val.append(self.construct_object(child, deep=deep))
            if child.comment:
                seqtyp._yaml_add_comment(child.comment, key=idx)
            seqtyp._yaml_set_idx_line_col(
                idx, [child.start_mark.line, child.start_mark.column])
        return ret_val

    def flatten_mapping(self, node):
        # type: (Any) -> Any
        """
        This implements the merge key feature http://yaml.org/type/merge.html
        by inserting keys from the merge dict/list of dicts if not yet
        available in this node
        """

        def constructed(value_node):
            # type: (Any) -> Any
            # If the contents of a merge are defined within the
            # merge marker, then they won't have been constructed
            # yet. But if they were already constructed, we need to use
            # the existing object.
            if value_node in self.constructed_objects:
                value = self.constructed_objects[value_node]
            else:
                value = self.construct_object(value_node, deep=False)
            return value

        # merge = []
        merge_map_list = []
        index = 0
        while index < len(node.value):
            key_node, value_node = node.value[index]
            if key_node.tag == u'tag:yaml.org,2002:merge':
                del node.value[index]
                if isinstance(value_node, MappingNode):
                    merge_map_list.append(
                        (index, constructed(value_node)))
                    # self.flatten_mapping(value_node)
                    # merge.extend(value_node.value)
                elif isinstance(value_node, SequenceNode):
                    # submerge = []
                    for subnode in value_node.value:
                        if not isinstance(subnode, MappingNode):
                            raise ConstructorError(
                                "while constructing a mapping",
                                node.start_mark,
                                "expected a mapping for merging, but found %s"
                                % subnode.id, subnode.start_mark)
                        merge_map_list.append(
                            (index, constructed(subnode)))
                    #     self.flatten_mapping(subnode)
                    #     submerge.append(subnode.value)
                    # submerge.reverse()
                    # for value in submerge:
                    #     merge.extend(value)
                else:
                    raise ConstructorError(
                        "while constructing a mapping", node.start_mark,
                        "expected a mapping or list of mappings for merging, "
                        "but found %s"
                        % value_node.id, value_node.start_mark)
            elif key_node.tag == u'tag:yaml.org,2002:value':
                key_node.tag = u'tag:yaml.org,2002:str'
                index += 1
            else:
                index += 1
        return merge_map_list
        # if merge:
        #     node.value = merge + node.value

    def _sentinel(self):
        # type: () -> None
        pass

    def construct_mapping(self, node, maptyp=None, deep=False):  # type: ignore
        # type: (Any, Any, bool) -> Any
        if not isinstance(node, MappingNode):
            raise ConstructorError(
                None, None,
                "expected a mapping node, but found %s" % node.id,
                node.start_mark)
        merge_map = self.flatten_mapping(node)
        # mapping = {}
        if node.comment:
            maptyp._yaml_add_comment(node.comment[:2])  # type: ignore
            if len(node.comment) > 2:
                maptyp.yaml_end_comment_extend(node.comment[2], clear=True)  # type: ignore
        if node.anchor:
            from ruamel_yaml.serializer import templated_id
            if not templated_id(node.anchor):
                maptyp.yaml_set_anchor(node.anchor)
        last_key, last_value = None, self._sentinel
        for key_node, value_node in node.value:
            # keys can be list -> deep
            key = self.construct_object(key_node, deep=True)
            # lists are not hashable, but tuples are
            if not isinstance(key, Hashable):
                if isinstance(key, list):
                    key_a = CommentedKeySeq(key)
                    if key_node.flow_style is True:
                        key_a.fa.set_flow_style()
                    elif key_node.flow_style is False:
                        key_a.fa.set_block_style()
                    key = key_a
                    # key = tuple(key)
            if PY2:
                try:
                    hash(key)
                except TypeError as exc:
                    raise ConstructorError(
                        "while constructing a mapping", node.start_mark,
                        "found unacceptable key (%s)" %
                        exc, key_node.start_mark)
            else:
                if not isinstance(key, Hashable):
                    raise ConstructorError(
                        "while constructing a mapping", node.start_mark,
                        "found unhashable key", key_node.start_mark)
            value = self.construct_object(value_node, deep=deep)
            self.check_mapping_key(node, key_node, maptyp, key, value)

            if key_node.comment and len(key_node.comment) > 4 and \
               key_node.comment[4]:
                if last_value is None:
                    key_node.comment[0] = key_node.comment.pop(4)
                    maptyp._yaml_add_comment(key_node.comment, value=last_key)
                else:
                    key_node.comment[2] = key_node.comment.pop(4)
                    maptyp._yaml_add_comment(key_node.comment, key=key)  # type: ignore
                key_node.comment = None
            if key_node.comment:
                maptyp._yaml_add_comment(key_node.comment, key=key)  # type: ignore
            if value_node.comment:
                maptyp._yaml_add_comment(value_node.comment, value=key)  # type: ignore
            maptyp._yaml_set_kv_line_col(  # type: ignore
                key, [key_node.start_mark.line, key_node.start_mark.column,
                      value_node.start_mark.line, value_node.start_mark.column])
            maptyp[key] = value  # type: ignore
            last_key, last_value = key, value  # could use indexing
        # do this last, or <<: before a key will prevent insertion in instances
        # of collections.OrderedDict (as they have no __contains__
        if merge_map:
            maptyp.add_yaml_merge(merge_map)  # type: ignore

    def construct_setting(self, node, typ, deep=False):
        # type: (Any, Any, bool) -> Any
        if not isinstance(node, MappingNode):
            raise ConstructorError(
                None, None,
                "expected a mapping node, but found %s" % node.id,
                node.start_mark)
        if node.comment:
            typ._yaml_add_comment(node.comment[:2])
            if len(node.comment) > 2:
                typ.yaml_end_comment_extend(node.comment[2], clear=True)
        if node.anchor:
            from ruamel_yaml.serializer import templated_id
            if not templated_id(node.anchor):
                typ.yaml_set_anchor(node.anchor)
        for key_node, value_node in node.value:
            # keys can be list -> deep
            key = self.construct_object(key_node, deep=True)
            # lists are not hashable, but tuples are
            if not isinstance(key, Hashable):
                if isinstance(key, list):
                    key = tuple(key)
            if PY2:
                try:
                    hash(key)
                except TypeError as exc:
                    raise ConstructorError(
                        "while constructing a mapping", node.start_mark,
                        "found unacceptable key (%s)" %
                        exc, key_node.start_mark)
            else:
                if not isinstance(key, Hashable):
                    raise ConstructorError(
                        "while constructing a mapping", node.start_mark,
                        "found unhashable key", key_node.start_mark)
            # construct but should be null
            value = self.construct_object(value_node, deep=deep)  # NOQA
            self.check_mapping_key(node, key_node, typ, key, value)
            if key_node.comment:
                typ._yaml_add_comment(key_node.comment, key=key)
            if value_node.comment:
                typ._yaml_add_comment(value_node.comment, value=key)
            typ.add(key)

    def construct_yaml_seq(self, node):
        # type: (Any) -> Any
        data = CommentedSeq()
        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
        if node.flow_style is True:
            data.fa.set_flow_style()
        elif node.flow_style is False:
            data.fa.set_block_style()
        if node.comment:
            data._yaml_add_comment(node.comment)
        yield data
        data.extend(self.construct_rt_sequence(node, data))

    def construct_yaml_map(self, node):
        # type: (Any) -> Any
        data = CommentedMap()
        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
        if node.flow_style is True:
            data.fa.set_flow_style()
        elif node.flow_style is False:
            data.fa.set_block_style()
        yield data
        self.construct_mapping(node, data)

    def construct_yaml_object(self, node, cls):
        # type: (Any, Any) -> Any
        data = cls.__new__(cls)
        yield data
        if hasattr(data, '__setstate__'):
            state = SafeConstructor.construct_mapping(self, node, deep=True)
            data.__setstate__(state)
        else:
            state = SafeConstructor.construct_mapping(self, node)
            data.__dict__.update(state)

    def construct_yaml_omap(self, node):
        # type: (Any) -> Any
        # Note: we do now check for duplicate keys
        omap = CommentedOrderedMap()
        omap._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
        if node.flow_style is True:
            omap.fa.set_flow_style()
        elif node.flow_style is False:
            omap.fa.set_block_style()
        yield omap
        if node.comment:
            omap._yaml_add_comment(node.comment[:2])
            if len(node.comment) > 2:
                omap.yaml_end_comment_extend(node.comment[2], clear=True)
        if not isinstance(node, SequenceNode):
            raise ConstructorError(
                "while constructing an ordered map", node.start_mark,
                "expected a sequence, but found %s" % node.id, node.start_mark)
        for subnode in node.value:
            if not isinstance(subnode, MappingNode):
                raise ConstructorError(
                    "while constructing an ordered map", node.start_mark,
                    "expected a mapping of length 1, but found %s" %
                    subnode.id,
                    subnode.start_mark)
            if len(subnode.value) != 1:
                raise ConstructorError(
                    "while constructing an ordered map", node.start_mark,
                    "expected a single mapping item, but found %d items" %
                    len(subnode.value),
                    subnode.start_mark)
            key_node, value_node = subnode.value[0]
            key = self.construct_object(key_node)
            assert key not in omap
            value = self.construct_object(value_node)
            if key_node.comment:
                omap._yaml_add_comment(key_node.comment, key=key)
            if subnode.comment:
                omap._yaml_add_comment(subnode.comment, key=key)
            if value_node.comment:
                omap._yaml_add_comment(value_node.comment, value=key)
            omap[key] = value

    def construct_yaml_set(self, node):
        # type: (Any) -> Any
        data = CommentedSet()
        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
        yield data
        self.construct_setting(node, data)

    def construct_undefined(self, node):
        # type: (Any) -> Any
        try:
            if isinstance(node, MappingNode):
                data = CommentedMap()
                data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
                if node.flow_style is True:
                    data.fa.set_flow_style()
                elif node.flow_style is False:
                    data.fa.set_block_style()
                data.yaml_set_tag(node.tag)
                yield data
                self.construct_mapping(node, data)
                return
            elif isinstance(node, ScalarNode):
                data = TaggedScalar()
                data.value = self.construct_scalar(node)
                data.style = node.style
                data.yaml_set_tag(node.tag)
                yield data
                return
        except:  # NOQA
            pass
        raise ConstructorError(
            None, None,
            "could not determine a constructor for the tag %r" %
            utf8(node.tag),
            node.start_mark)

    def construct_yaml_timestamp(self, node, values=None):
        # type: (Any, Any) -> Any
        try:
            match = self.timestamp_regexp.match(node.value)
        except TypeError:
            match = None
        if match is None:
            raise ConstructorError(
                None, None,
                'failed to construct timestamp from "{}"'.format(node.value),
                node.start_mark)
        values = match.groupdict()
        if not values['hour']:
            return SafeConstructor.construct_yaml_timestamp(self, node, values)
        for part in ['t', 'tz_sign', 'tz_hour', 'tz_minute']:
            if values[part]:
                break
        else:
            return SafeConstructor.construct_yaml_timestamp(self, node, values)
        year = int(values['year'])
        month = int(values['month'])
        day = int(values['day'])
        hour = int(values['hour'])
        minute = int(values['minute'])
        second = int(values['second'])
        fraction = 0
        if values['fraction']:
            fraction_s = values['fraction'][:6]
            while len(fraction_s) < 6:
                fraction_s += '0'
            fraction = int(fraction_s)
            if len(values['fraction']) > 6 and int(values['fraction'][6]) > 4:
                fraction += 1
        delta = None
        if values['tz_sign']:
            tz_hour = int(values['tz_hour'])
            minutes = values['tz_minute']
            tz_minute = int(minutes) if minutes else 0
            delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute)
            if values['tz_sign'] == '-':
                delta = -delta
        if delta:
            dt = datetime.datetime(year, month, day, hour, minute)
            dt -= delta
            data = TimeStamp(dt.year, dt.month, dt.day, dt.hour, dt.minute,
                             second, fraction)
            data._yaml['delta'] = delta
            tz = values['tz_sign'] + values['tz_hour']
            if values['tz_minute']:
                tz += ':' + values['tz_minute']
            data._yaml['tz'] = tz
        else:
            data = TimeStamp(year, month, day, hour, minute, second, fraction)
            if values['tz']:  # no delta
                data._yaml['tz'] = values['tz']

        if values['t']:
            data._yaml['t'] = True
        return data

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:null',
    RoundTripConstructor.construct_yaml_null)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:bool',
    RoundTripConstructor.construct_yaml_bool)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:int',
    RoundTripConstructor.construct_yaml_int)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:float',
    RoundTripConstructor.construct_yaml_float)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:binary',
    RoundTripConstructor.construct_yaml_binary)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:timestamp',
    RoundTripConstructor.construct_yaml_timestamp)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:omap',
    RoundTripConstructor.construct_yaml_omap)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:pairs',
    RoundTripConstructor.construct_yaml_pairs)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:set',
    RoundTripConstructor.construct_yaml_set)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:str',
    RoundTripConstructor.construct_yaml_str)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:seq',
    RoundTripConstructor.construct_yaml_seq)

RoundTripConstructor.add_constructor(
    u'tag:yaml.org,2002:map',
    RoundTripConstructor.construct_yaml_map)

RoundTripConstructor.add_constructor(
    None, RoundTripConstructor.construct_undefined)


text:
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright 2015 GDG Minsk
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~        http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<!--
    Can't be changed to TextView with compound drawable because ImageView is a part of transition animation
    and contact image is loading from Uri
-->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeightLarge"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    tools:ignore="UseCompoundDrawables">

    <ImageView
        android:id="@+id/contact_photo"
        android:layout_width="@dimen/icon_size"
        android:layout_height="@dimen/icon_size"
        android:layout_marginLeft="5dp"
        android:layout_marginStart="5dp"
        android:scaleType="centerCrop"
        android:contentDescription="@null"/>

    <TextView
        android:id="@+id/name"
        style="@style/AnimationGuide.Text.Large"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/text_margin"
        android:layout_marginBottom="@dimen/text_margin"
        android:layout_marginRight="5dp"
        android:layout_marginEnd="5dp"
        android:layout_marginLeft="@dimen/text_margin"
        android:layout_marginStart="@dimen/text_margin"
        tools:text="John Doe"/>
</LinearLayout>

redpajama_set_name: RedPajamaGithub


text:
Tandi Dorji (, Wylie : Rta mgrin rdo rje; born 2 September 1968) is a Bhutanese politician who has been Foreign Minister for Bhutan since November 2018. He has been a member of the National Assembly of Bhutan, since October 2018.

Education
He holds a Bachelor of Medicine and Bachelor of Surgery degree from Mymensingh Medical College under the University of Dhaka, Bangladesh. He completed his Master of International Public Health from University of Sydney, Australia and Master of Business Administration from University of Canberra, Australia.

Political career
Before entering politics, he was a pediatrician, public health researcher and a technical advisor.

Dorji is a founding member and former president of the Druk Nyamrup Tshogpa.
He participated in the 2008 and 2013 elections. He was elected to the National Assembly of Bhutan in the 2018 elections for the Lingmukha Toedwang constituency. He received 3,154 votes and defeated Sonam Wangyel Wang, a candidate of DPT.

On 3 November, Lotay Tshering formally announced his cabinet structure and Tandi was named as Foreign Minister for Bhutan. On 7 November 2018, he was sworn in as Foreign Minister for Bhutan in the cabinet of Prime Minister Lotay Tshering.

Honours
  :
  The Royal Orange Scarf (3 November 2018).
  The Royal Red Scarf (17 December 2022).

References

1968 births
Living people
Foreign ministers of Bhutan
Bhutanese MNAs 2018–2023
Bhutanese pediatricians
Lotay Tshering ministry
Druk Nyamrup Tshogpa politicians
University of Dhaka alumni
University of Sydney alumni
University of Canberra alumni
Druk Nyamrup Tshogpa MNAs

redpajama_set_name: RedPajamaWikipedia


text:
Engagement, bonding, and identity across multiple platforms: Avaaz on Facebook, YouTube, and MySpace
Kavada, A. 2012. Engagement, bonding, and identity across multiple platforms: Avaaz on Facebook, YouTube, and MySpace. MedieKultur: Journal of Media and Communication Research. 28 (52), pp. 28-48.
Kavada, A.
This article explores the role of social media platforms in transnational activism by examining the case of Avaaz.org, an international advocacy organization aiming to bring people-powered politics to global decision-making. Focusing on the Avaaz website, its channel on YouTube, its page on Facebook and its profile page on MySpace, the article investigates the affordances of these platforms for identity-building, bonding, and engagement. The empirical data is derived from features analysis of the selected web platforms, as well as textual analysis of the comments posted by users. The findings show that while social media platforms make individual voices more visible, their design helps Avaaz to maintain a coherent collective voice. In terms of bonding, platforms allow individual activists to communicate with the organization and to spread its message to their existing social networks, but opportunities for private interpersonal communication with other Avaaz supporters are limited.
MedieKultur: Journal of Media and Communication Research
Journal citation
28 (52), pp. 28-48
SMID (Association of media researchers in Denmark)
http://ojs.statsbiblioteket.dk/index.php/mediekultur/article/view/5486
From Counterpublics to Contentious Publicness: Tracing the Temporal, Spatial, and Material Articulations of Popular Protest Through Social Media
Kavada, Anastasia and Poell, Thomas 2020. From Counterpublics to Contentious Publicness: Tracing the Temporal, Spatial, and Material Articulations of Popular Protest Through Social Media. Communication Theory. Advanced online publication. https://doi.org/10.1093/ct/qtaa025
Live Democracy and Its Tensions: Making Sense of Livestreaming in the 15M and Occupy
Kavada, A. and Trere, Emiliano 2020. Live Democracy and Its Tensions: Making Sense of Livestreaming in the 15M and Occupy. Information, Communication & Society. 23 (12), pp. 1787-1804. https://doi.org/10.1080/1369118X.2019.1637448
Protest Spaces Online and Offline: The Indignant Movement in Syntagma Square
Kavada, A. and Dimitriou, U. 2017. Protest Spaces Online and Offline: The Indignant Movement in Syntagma Square . in: Brown, G., Feigenbaum, A., Frenzel , F. and McCurdy, P. (ed.) Protest Camps and Social Movements: Spaces, Infrastructures and Media of Resistance Bristol and Chicago Policy Press. pp. 71-90
Social Media Battles: their Impact during the 2014 Greek Municipal Elections
Lappas, G., Triantafillidou, A., Yannas, P., Kavada, A., Kleftodimos, A. and Vasileiadou, O. 2016. Social Media Battles: their Impact during the 2014 Greek Municipal Elections . Journal of Universal Computer Science. 22 (3), pp. 375-393. https://doi.org/10.3217/jucs-022-03-0375
Social Movements and Political Agency in the Digital Age: A Communication Approach
Kavada, A. 2016. Social Movements and Political Agency in the Digital Age: A Communication Approach. Media and Communication . 4 (4), pp. 8-12. https://doi.org/10.17645/mac.v4i4.691
Social Media as Conversation: A Manifesto
Kavada, A. 2015. Social Media as Conversation: A Manifesto. Social Media + Society. 1 (1). https://doi.org/10.1177/2056305115580793
Creating the collective: social media, the Occupy Movement and its constitution as a collective actor
Kavada, A. 2015. Creating the collective: social media, the Occupy Movement and its constitution as a collective actor. Information, Communication & Society. 18 (8), pp. 872-886. https://doi.org/10.1080/1369118X.2015.1043318
Transnational Civil Society and Social Movements
Kavada, A. 2014. Transnational Civil Society and Social Movements. in: Wilkins, K.G., Tufte, T. and Obregon, R. (ed.) Handbook of Development Communication & Social Change Chichester Wiley-Blackwell. pp. 351-369
Internet cultures and protest movements: the cultural links between strategy, organizing and online communication
Kavada, A. 2013. Internet cultures and protest movements: the cultural links between strategy, organizing and online communication. in: Cammaerts, B., Mattoni, A. and McCurdy, P. (ed.) Mediation and protest movements London Intellect. pp. 75-94
The Role of the Internet in Current Global Activism
Kavada, A. 2011. The Role of the Internet in Current Global Activism . in: Papathanassopoulos, S. (ed.) Communication and Society from the Twentieth to the Twenty-first Century (Fourth Edition) Athens Kastaniwtis. pp. 392-412
Email lists and participatory democracy in the European Social Forum
Kavada, A. 2010. Email lists and participatory democracy in the European Social Forum. Media, Culture & Society. 32 (3), pp. 355-372. https://doi.org/10.1177/0163443709361167
Between individuality and collectiveness: email lists and face-to-face contact in the global justice movement
Kavada, A. 2010. Between individuality and collectiveness: email lists and face-to-face contact in the global justice movement. International Journal of E-Politics. 1 (1), pp. 41-56. https://doi.org/10.4018/jep.2010102203
Activism transforms digital: the social movement perspective
Kavada, A. 2010. Activism transforms digital: the social movement perspective. in: Joyce, M. (ed.) Digital activism decoded: the new mechanism of change New York & Amsterdam International Debate Education Association. pp. 101-118
E-mail lists and the construction of an open and multifaceted identity: the case of the London 2004 European Social Forum
Kavada, A. 2009. E-mail lists and the construction of an open and multifaceted identity: the case of the London 2004 European Social Forum. Information, Communication & Society. 12 (6), pp. 817-839. https://doi.org/10.1080/13691180802304854
The Internet and decentralized architectures: email lists and the organizing process of the European Social Forum
Kavada, A. 2009. The Internet and decentralized architectures: email lists and the organizing process of the European Social Forum. in: Karatzogianni, A. (ed.) Cyber conflict and global politics London Routledge. pp. 188-204
Collective action and the social web: Comparing the architecture of Avaaz.org and Openesf.net
Kavada, A. 2009. Collective action and the social web: Comparing the architecture of Avaaz.org and Openesf.net. in: Carpentier, N., Pruulmann-Vengerfeldt, P., Kilborn, R., Olsson, T., Nieminen, H., Sundin, E. and Nordenstreng, K. (ed.) Communicative approaches to politics and ethics in Europe: The intellectual work of the 2009 European media and communication doctoral summer school Tartu University of Tartu Press. pp. 129-140
Decision-making online and offline: the case of the 'movement for alternative globalization'
Kavada, A. 2008. Decision-making online and offline: the case of the 'movement for alternative globalization'. in: Carpentier, N., Pruulmann-Vengerfeldt, P., Nordenstreng, K., Hartmann, M., Vihalemm, P., Cammaerts, B., Nieminen, H. and Olsson, T. (ed.) Democracy, Journalism and Technology: New Developments in an Enlarged Europe: The Intellectual Work of the 2008 ECREA Media and Communication Doctoral Summer School Tartu University of Tartu Press. pp. 217-228
The European Social Forum and the Internet: a case of communications networks and collective action
Kavada, A. 2007. The European Social Forum and the Internet: a case of communications networks and collective action. PhD thesis University of Westminster School of Media, Arts and Design
Exploring the Role of the Internet in the "Movement for Alternative Globalization": The case of the Paris 2003 European Social Forum
Kavada, A. 2005. Exploring the Role of the Internet in the "Movement for Alternative Globalization": The case of the Paris 2003 European Social Forum. Westminster Papers in Communication and Culture. 2 (1), pp. 72-95. https://doi.org/10.16997/wpcc.9
Civil society organisation and the internet: the case of Amnesty International, Oxfam and the World Development Movement
Kavada, A. 2005. Civil society organisation and the internet: the case of Amnesty International, Oxfam and the World Development Movement. in: de Jong, W., Shaw, M. and Stammers, N. (ed.) Global activitism, global media London, UK Pluto Press. pp. 208-222
Permalink - https://westminsterresearch.westminster.ac.uk/item/8z7z6/engagement-bonding-and-identity-across-multiple-platforms-avaaz-on-facebook-youtube-and-myspace

redpajama_set_name: RedPajamaCommonCrawl


Cherry to the cake, Heinricy is also an avid racing driver. He counts numerous SCCA Runoffs road-racing victories to his credit.
Around this time last year, Bugatti and Koenigsegg got a wake-up call after Hennessy showcased the Venom F5 hypercar at the 2017 SEMA auto show. The rather beautiful car was slated to have a staggering 1,600 horsepower that would lunge the car to a top speed of 484kph!
However, in the latest development of the project, Hennessy confirmed that it has hired veteran GM engineer John Heinricy to lead the development of the hypercar.
The 71-year-old veteran engineer concluded his duties at General Motors in 2008 after serving the company for nearly 40 years. Ahead of his retirement from GM, Heinricy headed the company's Performance Division where he was responsible for the company's some of the crucial models like the Chevrolet Corvette Z06 and Cadillac CTS-V.
Cherry to the cake, Heinricy is also an avid racing driver. He counts numerous SCCA Runoffs road-racing victories to his credit, many achieved in the tough T1 class. Apart from that, Heinricy holds the achievement of the first sub-8:00 Nürburgring lap time for a production sedan at 7:59.32, claimed with the aid of the second-generation Cadillac CTS-V.
In the past, Heinricy has helped Hennessy with testing of several cars and has already been a serving consulting role on the Venom F5 project and its Venom GT predecessor. Currently, Heinricy has been appointed as a full-time member of the Hennessy team, focussing on development, testing and production of the Venom F5.
The Venom F5 turned heads with is bespoke 7.6-litre twin-turbocharged V-8, capable of delivering a staggering 1,600-plus horsepower and 1762Nm of torque. Only 24 models will exit the production ramp and will carry a price tag of $1.6 million.
While the F5 dials every attribute up, the similarly potent Venom GT is built on a completely new chassis and carbon fibre body to achieve a 1338kg kerb weight. The current coefficient of drag of the car stands at 0.33 compared to the 0.40 that Hennessy had in mind.


Help us Cultivate a Healthy Nantucket!
Build gardens and increase access to local food for the public schools with our Farm to School program.
Become a partner in our work by making your tax-deductible gift to Sustainable Nantucket today!
Your gift of support is an investment ensuring wide-scale community benefits by helping to build a more locally-based, self-reliant food economy – one in which sustainable food production, processing, distribution, and consumption is integrated – thereby enhancing the economic, environmental and social health of our island, and improving our long-term, overall sustainability.
Additional information about our programs that provide support to and benefit of our local community can be found on this site and by signing up to receive our e-newsletters.
Donations to our Annual Fund can be made online here or by sending a check payable to 'Sustainable Nantucket' to Sustainable Nantucket, PO Box 1244, Nantucket, MA 02554.


A New York City woman has recovered her wedding and engagement rings from a New Jersey dump with some help from sanitation workers.
Shannon Lombardo says she accidentally threw out the rings, which were in a paper towel.
She called 311 and the city delayed pickups from her Upper West Side building to give her a chance to sift through the building's trash.
When her search proved unsuccessful, the 46-year-old Lombardo went to a facility in Fairview, New Jersey, with her husband.
The New York Daily News reported Friday that workers identified the truck that took their garbage and removed 800 bags.
Sanitation workers then helped the Lombardos dig through the trash for an hour before finding the correct bag. Inside, they found two rings nestled in some tissues.


melunier.win Page 39: sliding mirrored door wardrobes. hafele wardrobe fittings. bedroom built in wardrobe. double sided wardrobe tape. 3 door solid wood wardrobe. hanging clothes wardrobe.
Published at Wednesday 01st, August 2018, in Wardrobes. By Cree Le Meur.


Reliable and sleek-looking—these are the characteristics that make the Toyota Camry a hit. These may also be the reasons why it's among the vehicles that car thieves love to steal. In fact, there were around 15,000 reported thefts of the Toyota Camry last year.
More than 27,000 units of Chevrolet Pickup were reportedly stolen last year. With its impressive performance and roomy design, it's not surprising that this vehicle is one of the car thieves' favorite models.
The Ford Pickup is considered as one of the best-selling vehicles in the USA. The high demand for this truck makes it easier for car thieves to sell it to unsuspecting buyers. There were around 29,000 reported thefts of this automobile unit.
The Civic is easily one of the most popular cars in the automotive market today, which is probably the reason why a lot of car thieves want to get their hands on it. In 2015, there were more than 49,000 reported thefts of this car.
The Honda Accord has been in production for more than four decades and it has continuously topped the lists of the most stolen vehicles over the past years. With a whopping 52,000 reported thefts, the Accord is undoubtedly a car thief's favorite.
And that's all! If your ride is one the mentioned vehicles, then you might want to practice extra precaution while you're on the road. Got more to add to this list? Drop a comment below!


Which one of our podcasts is the podcast of the week? It had to be the most recent podcast about the most discussed topic in the news this week.
As part of the Spindle project we are investigating the use of automatic keywords for OER discoverability. Please find below the automatic keywords generated from the automatic transcription of the podcast of the week. Click on the image to listen!


2008 Apple Inc. All rights reserved. Apple, the Apple logo, Mac, Mac OS, Macintosh, Leopard, iPhone, Multi-Touch, MoblieMe, iPod and iTunes are trademarks of Apple. Other company and product names may be trademarks of their respective owners.


Nintendo has sold over 4 million Switch consoles to date, the company reports in its latest financials.
Japanese games-maker Nintendo today announced its first quarter earnings, kicking off its fiscal year with strong earnings momentum on the heels of the Switch's mighty launch.
The company also adjusted the Switch handheld-console's lifetime-to-date sales across the globe to 4.7 million units, showing that the console-maker is almost halfway to its 10 million sales goal for the fiscal year. Nintendo Switch software sales sit at 13.6 million units, meaning most Switch owners have 2-3 games.
Despite the growth to 4.7 million units, the Switch has been mired by supply situations stemming from shortages of components like flash memory. Smartphone titans like Apple and Samsung have reserved the lion's share of key components to use in their phones--the very same chips that make power Nintendo's new machine.
As a result of the shortages, Nintendo has sold markedly less Switch consoles in its first-quarter period: the company reported 1.97 million units sold in the three-month period from April to June, down a substantial 30% from the Switch's 2.74 million unit sales figure generated in a single month.
It will be interesting to see how Nintendo prepares to weather the component storm now that Apple is gearing up for its new 10th anniversary iPhone, however IHS Markit analyst Piers Harding-Rolls predicts supply will remained constrained for the rest of the year.
Despite shortages, IHS Markit forecasts 9.5 million Switch sales by the end of 2017.


Author: Congress of the U.S., Washington, DC. House Committee on Science and Technology.; Congress of the U.S., Washington, DC. House Committee on Agriculture.
Title: H.R. 2436, National Nutrition Monitoring and Related Research Act of 1985. Joint Hearing before the Subcommittee on Science, Research and Technology of the Committee on Science and Technology and the Subcommittee on Department Operations, Research, and Foreign Agriculture and the Subcommittee on Domestic Marketing, Consumer Relations, and Nutrition of the Committee on Agriculture. House of Representatives, Ninety-Ninth Congress, First Session (June 25, 1985).
Physical: 5 microfiche: negative, ill.


text:
sstusek 30/09/2019 16/06/2020 Aviation, Uncategorized No Comments
A sad day for Slovenian aviation, Adria airways went bankrupt today after 58 years. What a big loss for Slovenia and European regional aviation.
The spirit of this airline inspired me and made me follow into this aviation hobby. The support of Adria employees was very helpful and without it, I guess much of this would not be possible.
The story of Adria Aviopromet (Adria Airways) begun on 14 March of 1961 when the Executive Council of then People´s Republic of Slovenia decided on founding the company Adria Aviopromet. The establishment was dictated by the growth and evelopment of Slovenian and Yugoslav tourism and the increasing interest of foreign tourists. At that time JAT as the only airline during this period, could not meet all the needs so the new airline could provide additional services. Few months later 1.9 million USD contract was signed with KLM for four used DC-6B aircraft from Caribean KLM fleet. Financial guarantees where provided by the Slovenian government and Splošna plovba shipping company took care of the loan. On August 9, 1961 the first aircraft landed at Zagreb Airport followed by second on August 12 (YU-AFC, YU-AFD). The other two aircraft (YU-AFE, YU-AFD) followed later in April 18, and 28, 1962. At first all operations were performed from Zagreb´s Pleso Airport and were later moved to Ljubljana, when the airport was built in 1964. The captain of the first aircraft to land on Ljubljana´s Brnik Airport was Karel Rankel.
The 84 seat propeller aircraft provided both regional and intercontinental flights. Some of the first flights served the conference of non-aligned states movement in Belgrade. Adria's first flight was international flight for the conference from Pula to Rome on August 23, 1961. The first commercial flight followed on October 21, from Zagreb to Paris. Adria offered flights for tourist markets of Germany, UK, Netherlands and Scandinavian countries to Adriatic coast. They also tailored specific charter flights for Western European and North American travel agencies, connecting them to destinations in Africa (Dakar, Adis Abeba, Khartoum, Entebbe, Nairobi,..) and the Far East (Jemen, Teheran, Mumbay, Bangkok, Sri Lanka, Hong Kong, Manilla, Jakarta, Tokyo, Toronto,…). Adria also operated flights for the United Nations and the Red Cross, flying mainly from Scandinavia and Brazil to the Sinai (El Arisha to Rio de Janeiro).
Captain Karel Rankel led the first flight across the Atlantic in June 1963. The flight from Shannon (Ireland) to Toronto (Canada) took 13 hours and 22 minutes and was performed by a double crew. The captain of the second crew was Branivoj Majcen. They set a Yugoslav record for the length of the flight and the flight was also considered to be the longest nonstop flight in that time. A major achievement was also gaining the landing permit for the US airports, which only a few charter companies got at the time. 63 cross Atlantic return flights were completed to New York, Washington, Boston, Cleveland,…
In those days Adria's planes flew to all continents except Australia. In 1968 the first scheduled flight was introduced between Ljubljana and Belgrade. Unfortunately aging slow propeler aircraft like Adria "sixes" gradually became uncompetitive compared to the increasing number of faster jet aircraft. The economic situation of Adria started to deteriorate in 1967. Management was well aware of urgent fleet upgrade with jet aircraft but could not find an investor that would help them financially. Flight hours slowly decreased and Adria started facing first crisis which led to bankruptcy in 26.1.1968.
The jet age
Adria got new management and in February 1969 they announced that company successfully reorganized and kept a positive balance. However a fleet renewal was still necessary and the management
was still trying hard to find a business partner to fund the final reconstruction of the company. After many unsuccessful attempts, Adria finally found a business partner in Belgrade-based company Inexexport. The company merge gave Adria a new name Inex-Adria Aviopromet (Inex-Adria Airways) and a fresh capital for fleet renewal. First 115-seat McDonnell Douglas DC-9-32 jet aircraft landed at Ljubljana Airport on April 25, 1969 (YU-AHJ). New jet aircraft livery came with updated window stripes, same as Alitalia had at that time.
In the following years to 1972, the old DC-6B´s where replaced with new DC-9-32 jet aircraft, purchased and leased (YU-AHR, YU-AHW, YU-AJB, YU-AJN). The last commercial flight with propeller DC-6B (YU-AAF) was performed by cpt. Kamenšek J. on 3.4.1972 from Lusaka to Ljubljana. This aircraft can still be seen today on Ljubljana Airport. Sud Aviation Caravelle SE 210 (YU-AJE) was leased (31.31972 to 27.11.1972) from Aerospatiale for the time between aircraft deliveries and unfortunate loss of DC-9 (YU-AHR) over Aden Yemen on March 19, 1972 (EgyptAir Flight 763).
In 1972 Adria atempted to renew its transatlantic flights to the US and Canada using leased 184 seat aircraft Douglas DC-8-55. Due to high cost and strong competition over the Atlantic the flights were not profitable and wher soon withdrawn.
Adria continued to operate charter flights between European cities and the holiday destinations on Adriatic coast (Dubrovnik, Split, Pula and Tivat). Within a few years, Adria has regained its reputation for its accuracy, reliability and quality of service. It was renowned as one of the most reliable charter airlines in Europe. As demand on charter flights dictated further fleet expansion, a larger 135 seat aircraft DC-9-51 aircraft (YU-AJT) was purchased on May 12, 1976 and followed by another in May 24, 1977 (YU-AJU). On domestic market scheduled flight to Belgrade was successful and to satisfy increasing demand, Adria connected Ljubljana with all the major cities in Yugoslavia.
No everything was so brite, late 70's were tough years for Adria regarding safety and aircraft losses. In just a few years another three aircraft where lost in accidents. DC-9-32 (YU-AJN) on November 23, 1974 over Belgrade Airport ex Surčin, DC-9-32 (YU-AJO) on October 30, 1975 near Prague Ruzyne Airport and DC-9-32 (YU-AJR) on September 10, 1976 near Vrobec Croatia. Adria found itself in difficult times.
Adria followed the development in aviation industry and at the beginning of 1980´s ordered five new versions of extended DC-9 Super 80 series aircraft, called MD-80, to help further expand on the foreign market. Adria received the first of four 165-seat MD-80 on June 10, 1981 (YU-AJZ). Unfortunately, the eighties also began with accident which is still deeply embedded in the consciousness of the Slovenes. One of the new MD-81 aircraft (YU-ANA) flew into the side of a mountain near Ajaccio Corsica on December 1, 1981. That was fifth loss of the aircraft in a relatively short time which placed Adria to the bottom of the safety rankings. Many thought that accidents where linked to ex military pilots flying for Adria and their flying attitude. In any case Adria had to fundamentally reorganize its flight operations and pilot training to improve flight safety and restore its reputation. They worked hard to improve flight safety with new flight operation standards modeled after Swissair. Pilot training and assessment was doubled and Adria gave more attention to its flight school. All the effort was evident as Adria had no accident since. In 1983 the first international scheduled flights were established on the Ljubljana-Belgrade-Larnaca (Cyprus) route and in the following years Adria also expanded its network of scheduled flights to Munich, London and Paris. The number of passengers was constantly growing and reached one million, peaking in 1987 with 1,740,000 passengers. In 1982 Adria had a fleet of nine aircraft, 4x DC-9-32, 2x DC-9-51 and 3x DC-9-81 with a total capacity of 1124 passenger seats.
As Yugoslavia was preparing to stage the XIV. Olympics Winter games at Sarajevo, Adria expandet its fleet with two 48-seat de Havilland Dash 7 turboprop aircraft, intended for the Olympics flight service. Dash 7 aircraft would later boost regional airports flights. Adria received both aircraft on January 30, 1984 (YU-AIE, YU-AIF) and moved them to Sarajevo on February 5, just in time for the start of Olympic games. In 1985, Adria wet-leased aditional aircraft BAC 1-11-525FT from Romanian Tarom. First 119-seat aircraft arrivedon 26.4.1985 (YU-AKN) and supported all planned flights. In the following year 1986 two BAC 1-11 were wet-leased (YU-ANM , YU-ANN) and in 1987 three but this time ROM-BAC 1-11 (YU-ANR , YU-ANS , YU-ANT). Last BAC 1-11 left fleet on 26.10.1987.
Inex-Adria Aviopromet (Inex-Adria Airways) also started commercial, organizational and restructuring programe from 1983 – 1986 after which Adria became its own company again and parted with Inexexport. Name was changed to Adria Airways.
Adria continually strived to stay ahead of competition with the latest advances aviation industry could offer and in 1984 already started planning fleet renewal with new generation aircraft. First talks were made with european aircraft manufacturer Airbus for buying wide-body A-310 aircraft. Adria management and technical department was visionary and eventually decidet for five of the emerging A320 aircraft. On July 12, 1984 contract for first three aircraft was signed.
Leap into the future
For airline every new aircraft marks a turning point and arrival of new Airbus A320 was sure one of important milestone for Adria. The first Airbus A320-231 aircraft registration YU-AOA landed at Ljubljana Airport on May 18, 1989. This was undoubtedly most modern passenger airplane by date in the category of 150 seat aircraft. With new aircraft Adria also unveiled its new updated logo and livery designed by Knut Marsen (Chief Graphic Designer at Airbus) and Samo Ivančič. Adria sign got more modern rounded shape and a larger print on the side of a white plane. Tail got a characteristic Adria "heart" or the shape of a linden leaf composed from letter A and its shadow.
Adria was the first airline to fly A320 powered with new V2500 engines, manufactured by International Aero Engines (IAE). IAE engines had a better fuel economy, A320 burned a quarter less fuel per passenger compared to DC-9 and MD-81/82 aircraft in the fleet.
Adria's new flagship with 168 seats made its first commercial flight on May 22, 1989 on Ljubljana-Belgrade-Larnaca (Cyprus) line. In December same year Adria tested A320 on long route flight. The flight from Seychelles to Athens, took 7 hours and 40 minutes and ran past the distance of 5750 km. With this flight a new record was set for the longest flight with A320 at that time.
Adria introduced many new destinations from Ljubljana to primarily European cities and continued with seasonal charter flights, most often to Mediterranean tourist destinations.
While waiting for the second and third A320 delivery, Adria leased Cyprus Airlines A320 form April to October 1990 (YU-AOB). On September 11, 1990 another two A320 aircraft joined the fleet, YU-AOD and YU-AOE. The three A320 buses became Adria's workhorses.
As Yugoslavia began to break up and the market became uncertaint, two additional A320´s expected to arrive in June 1991 were never delivered. The Republic of Slovenia declared independence on June 25, 1991. Soon eafter Yugoslavia's Civil Aviation Administration, which was still responsible for Slovenian airspace, banned Adria from flying for three months. Douring ten day independence war Yugoslav Air Force fighters jets attacked Adria facilities at Ljubljana Brnik Airport. In the attack damage was caused to hangar building including four aircraft inside and outside the hangar. Airbus A320 and de Havilland Dash 7 were severely damaged. Adria management quickly decided, despite the ban, to fly all the remaining aircraft still at Brnik Airport to the Klagenfurt airport in neighboring Austria. In 1991 Adria had a fleet of thirteen aircraft, 3x Airbus A320, 4x MD-82, 1x MD-81, 3x DC-9-30 and 2x Dash-7.
Flag carrier
After 52 days of forced grounding Adria Airways resumed its activities from Klagenfurt Airport on January 16, 1992 with MD80 flight to Moscow. On January 30, the first aircraft returned to the home base Ljubljana Airport. However, the market was now significantly reduced. The majority of charter destinations to the Adriatic coast became inaccessible as a territory of other countries. The entire operating structure had to change dramatically. Some of the aircraft were leased to other airlines and the rest started flying on scheduled flights which now represented 70 percent of flights.
With Slovenia's independence the entire operating structure of the company had to transform dramatically. Adria became Slovenia's national airline and changed from primarily charter airline to mainly scheduled operator. Another restructuring program was needed with rationalization and modernization of the operations and fleet. Adria started cooperation with other European airlines and made a codeshare agreement with Lufthansa in 1995. Fleet modernization and first aircrat orders started in 1997. Adria choose the Canadair Regional Jet aircraft as the best option, following the example of Lufthansa Cityline. CRJ was economical and environmentally friendly modern regional jet aircraft that offered range comparable to the Airbus A320 and made flexibility possible on the entire flight network operated from Ljubljana. First two 48-seat CRJ-200LR aircraft arrived in January 1998 (S5-AAD, S5-AAE) and third at the end of 1998 (S5-AAF). In the same period two Dash-7 and two DC-9-30 where sold.
Adria successfully enhanced the fleet with operational lease of two new 86-seat CRJ-900 aircraft in May 2007 (S5-AAK and S5-AAL), increacsing and optimising capacities on EU routes. Two more CRJ-900 followed in December 2008 (S5-AAN) and the fourth in January 2009 (S5-AAO).
Adria replaced the A320 with two new A319 aircraft by long term leased at AerCap. The first 135-seat A319 (S5-AAP) was deliver on April 29, 2010 and second (S5-AAR) on April 30, 2010.
Due to expansion strategy in the season 2011 two more A-320 (S5-AAS and S5-AAT) 180 and 162-seat aircraft.
Adria Airways 20th anniversary booket, Krila_1_1984, Krila_2_1984, Krila_6_1984, Krila_2_1989, Krila_6_1990, Krila_2_1991, Krila_5_1991, Letalo,polet, letališče Anton Polenec,
← In Memoriam of Holt McMinn


text:
Lawrence, Jags rally from 27 down, shock Chargers 31-30
JACKSONVILLE, Fla. (AP)Trevor Lawrence followed four interceptions with four touchdown passes – one of the most improbable turnarounds in NFL postseason history – and rallied the Jacksonville Jaguars to a 31-30 victory over the Los Angeles Chargers on Saturday night.
Lawrence engineered the winning drive, highlighted by Travis Etienne's 25-yard run on a fourth-and-1 play, and put the Jaguars in position for Riley Patterson's 36-yard field goal on the final play. It capped a 27-point comeback, the third largest in playoff history.
Patterson's kick barely stayed inside the right upright and set off a raucous celebration for a franchise that had won just four games the previous two years.
This one was mostly a credit to Lawrence. He completed 28 of 47 passes for 288 yards, a shocker considering he the way he started.
Lawrence was downright dreadful to begin Jacksonville's first playoff game since losing in the 2017 AFC title game. He became the third quarterback in the Super Bowl era to throw four interceptions in the first half of a playoff game, joining Detroit's Gary Danielson and Denver's Craig Morton.
The Jaguars (10-8) became the first team in the Super Bowl era to win a playoff game with a turnover differential of minus-5 or worse.
Lawrence threw TD passes to Evan Engram, Marvin Jones, Zay Jones and Christian Kirk, and he added one of the biggest plays when he jumped for a 2-point conversion with 5:25 to play that made it 30-28.
Justin Herbert threw for 273 yards and a touchdown without an interception, but the Chargers' offense was largely ineffective after a 62-yard TD drive that made it 24-0 midway through the second quarter. Los Angeles (10-8) finished with 320 yards of offense and 18 first downs, and it produced only three points on four second-half possessions.
49ERS 41, SEAHAWKS 23
SANTA CLARA, Calif. (AP) – Brock Purdy threw three touchdown passes and ran for a fourth score in his playoff debut, leading San Francisco past Seattle.
Purdy picked up where he left off in the regular season for the 49ers (14-4) and showed few signs of playoff jitters by winning his sixth straight start since replacing an injured Jimmy Garoppolo early in a Week 13 win over Miami.
The Niners advanced to the divisional round where they will host either Minnesota, Tampa Bay or Dallas next weekend.
Purdy connected on a 3-yard pass to Christian McCaffrey in the first quarter, converted a 1-yard sneak in the third quarter and a 7-yard TD pass to Elijah Mitchell early in the fourth to make it 31-17.
The Niners broke it open when Deebo Samuel took a short pass from Purdy and raced in for a 74-yard score.
Purdy threw for 332 yards – the second most ever for a rookie in the playoffs to Russell Wilson's 385 in a loss to Atlanta 10 years ago – and he became the first rookie QB ever to account for four TDs in a playoff game.
The Seahawks (9-9) kept it close for most of three quarters before a strip sack by Charles Omenihu late in the third quarter spoiled a red zone drive.
Geno kept it close for a while thanks to a 50-yard TD pass to DK Metcalf in the first half. He finished 25 for 35 for 253 yards, two TDs and one interception.