text:
"""
@package ion.services.mi.instrument_driver Instrument driver structures
@file ion/services/mi/instrument_driver.py
@author Edward Hunter
@brief Instrument driver classes that provide structure towards interaction
with individual instruments in the system.
"""
import json

import consulate
import random
import time

from threading import Thread
from requests import ConnectionError

from mi.core.common import BaseEnum
from mi.core.exceptions import TestModeException
from mi.core.exceptions import NotImplementedException
from mi.core.exceptions import InstrumentException
from mi.core.exceptions import InstrumentParameterException
from mi.core.exceptions import InstrumentConnectionException
from mi.core.instrument.instrument_fsm import ThreadSafeFSM
from mi.core.instrument.port_agent_client import PortAgentClient, PortAgentPacket
from mi.core.log import get_logger, get_logging_metaclass

__author__ = 'Steve Foley'
__license__ = 'Apache 2.0'

log = get_logger()

META_LOGGER = get_logging_metaclass('trace')

STARTING_RECONNECT_INTERVAL = .5
MAXIMUM_RECONNECT_INTERVAL = 256
MAXIMUM_CONSUL_QUERIES = 5
MAXIMUM_BACKOFF = 5  # seconds

class AutoDiscoverFailure(Exception):
    pass

class ConfigMetadataKey(BaseEnum):
    """
    Keys used in the metadata structure that describes the driver, commands,
    and parameters used in the driver and protocol.
    """
    DRIVER = 'driver'
    COMMANDS = 'commands'
    PARAMETERS = 'parameters'

class DriverConfigKey(BaseEnum):
    """
    Dictionary keys for driver config objects
    """
    PARAMETERS = 'parameters'
    SCHEDULER = 'scheduler'

# This is a copy since we can't import from pyon.
class ResourceAgentState(BaseEnum):
    """
    Resource agent common states.
    """
    POWERED_DOWN = 'RESOURCE_AGENT_STATE_POWERED_DOWN'
    UNINITIALIZED = 'RESOURCE_AGENT_STATE_UNINITIALIZED'
    INACTIVE = 'RESOURCE_AGENT_STATE_INACTIVE'
    IDLE = 'RESOURCE_AGENT_STATE_IDLE'
    STOPPED = 'RESOURCE_AGENT_STATE_STOPPED'
    COMMAND = 'RESOURCE_AGENT_STATE_COMMAND'
    STREAMING = 'RESOURCE_AGENT_STATE_STREAMING'
    TEST = 'RESOURCE_AGENT_STATE_TEST'
    CALIBRATE = 'RESOURCE_AGENT_STATE_CALIBRATE'
    DIRECT_ACCESS = 'RESOURCE_AGENT_STATE_DIRECT_ACCESS'
    BUSY = 'RESOURCE_AGENT_STATE_BUSY'
    LOST_CONNECTION = 'RESOURCE_AGENT_STATE_LOST_CONNECTION'
    ACTIVE_UNKNOWN = 'RESOURCE_AGENT_STATE_ACTIVE_UNKNOWN'

class ResourceAgentEvent(BaseEnum):
    """
    Resource agent common events.
    """
    ENTER = 'RESOURCE_AGENT_EVENT_ENTER'
    EXIT = 'RESOURCE_AGENT_EVENT_EXIT'
    POWER_UP = 'RESOURCE_AGENT_EVENT_POWER_UP'
    POWER_DOWN = 'RESOURCE_AGENT_EVENT_POWER_DOWN'
    INITIALIZE = 'RESOURCE_AGENT_EVENT_INITIALIZE'
    RESET = 'RESOURCE_AGENT_EVENT_RESET'
    GO_ACTIVE = 'RESOURCE_AGENT_EVENT_GO_ACTIVE'
    GO_INACTIVE = 'RESOURCE_AGENT_EVENT_GO_INACTIVE'
    RUN = 'RESOURCE_AGENT_EVENT_RUN'
    CLEAR = 'RESOURCE_AGENT_EVENT_CLEAR'
    PAUSE = 'RESOURCE_AGENT_EVENT_PAUSE'
    RESUME = 'RESOURCE_AGENT_EVENT_RESUME'
    GO_COMMAND = 'RESOURCE_AGENT_EVENT_GO_COMMAND'
    GO_DIRECT_ACCESS = 'RESOURCE_AGENT_EVENT_GO_DIRECT_ACCESS'
    GET_RESOURCE = 'RESOURCE_AGENT_EVENT_GET_RESOURCE'
    SET_RESOURCE = 'RESOURCE_AGENT_EVENT_SET_RESOURCE'
    EXECUTE_RESOURCE = 'RESOURCE_AGENT_EVENT_EXECUTE_RESOURCE'
    GET_RESOURCE_STATE = 'RESOURCE_AGENT_EVENT_GET_RESOURCE_STATE'
    GET_RESOURCE_CAPABILITIES = 'RESOURCE_AGENT_EVENT_GET_RESOURCE_CAPABILITIES'
    DONE = 'RESOURCE_AGENT_EVENT_DONE'
    PING_RESOURCE = 'RESOURCE_AGENT_PING_RESOURCE'
    LOST_CONNECTION = 'RESOURCE_AGENT_EVENT_LOST_CONNECTION'
    AUTORECONNECT = 'RESOURCE_AGENT_EVENT_AUTORECONNECT'
    GET_RESOURCE_SCHEMA = 'RESOURCE_AGENT_EVENT_GET_RESOURCE_SCHEMA'
    CHANGE_STATE_ASYNC = 'RESOURCE_AGENT_EVENT_CHANGE_STATE_ASYNC'

class DriverState(BaseEnum):
    """Common driver state enum"""

    UNCONFIGURED = 'DRIVER_STATE_UNCONFIGURED'
    DISCONNECTED = 'DRIVER_STATE_DISCONNECTED'
    CONNECTING = 'DRIVER_STATE_CONNECTING'
    DISCONNECTING = 'DRIVER_STATE_DISCONNECTING'
    CONNECTED = 'DRIVER_STATE_CONNECTED'
    ACQUIRE_SAMPLE = 'DRIVER_STATE_ACQUIRE_SAMPLE'
    UPDATE_PARAMS = 'DRIVER_STATE_UPDATE_PARAMS'
    SET = 'DRIVER_STATE_SET'
    SLEEP = 'DRIVER_STATE_SLEEP'

class DriverProtocolState(BaseEnum):
    """
    Base states for driver protocols. Subclassed for specific driver
    protocols.
    """
    AUTOSAMPLE = 'DRIVER_STATE_AUTOSAMPLE'
    TEST = 'DRIVER_STATE_TEST'
    CALIBRATE = 'DRIVER_STATE_CALIBRATE'
    COMMAND = 'DRIVER_STATE_COMMAND'
    DIRECT_ACCESS = 'DRIVER_STATE_DIRECT_ACCESS'
    UNKNOWN = 'DRIVER_STATE_UNKNOWN'
    POLL = 'DRIVER_STATE_POLL'

class DriverConnectionState(BaseEnum):
    """
    Base states for driver connections.
    """
    UNCONFIGURED = 'DRIVER_STATE_UNCONFIGURED'
    DISCONNECTED = 'DRIVER_STATE_DISCONNECTED'
    CONNECTED = 'DRIVER_STATE_CONNECTED'
    INST_DISCONNECTED = 'DRIVER_STATE_INSTRUMENT_DISCONNECTED'

class DriverEvent(BaseEnum):
    """
    Base events for driver state machines. Commands and other events
    are transformed into state machine events for handling.
    """
    ENTER = 'DRIVER_EVENT_ENTER'
    EXIT = 'DRIVER_EVENT_EXIT'
    INITIALIZE = 'DRIVER_EVENT_INITIALIZE'
    CONFIGURE = 'DRIVER_EVENT_CONFIGURE'
    CONNECT = 'DRIVER_EVENT_CONNECT'
    CONNECTION_LOST = 'DRIVER_CONNECTION_LOST'
    PA_CONNECTION_LOST = 'DRIVER_PA_CONNECTION_LOST'
    DISCONNECT = 'DRIVER_EVENT_DISCONNECT'
    SET = 'DRIVER_EVENT_SET'
    GET = 'DRIVER_EVENT_GET'
    DISCOVER = 'DRIVER_EVENT_DISCOVER'
    EXECUTE = 'DRIVER_EVENT_EXECUTE'
    ACQUIRE_SAMPLE = 'DRIVER_EVENT_ACQUIRE_SAMPLE'
    START_AUTOSAMPLE = 'DRIVER_EVENT_START_AUTOSAMPLE'
    STOP_AUTOSAMPLE = 'DRIVER_EVENT_STOP_AUTOSAMPLE'
    TEST = 'DRIVER_EVENT_TEST'
    RUN_TEST = 'DRIVER_EVENT_RUN_TEST'
    STOP_TEST = 'DRIVER_EVENT_STOP_TEST'
    CALIBRATE = 'DRIVER_EVENT_CALIBRATE'
    RESET = 'DRIVER_EVENT_RESET'
    UPDATE_PARAMS = 'DRIVER_EVENT_UPDATE_PARAMS'
    BREAK = 'DRIVER_EVENT_BREAK'
    EXECUTE_DIRECT = 'EXECUTE_DIRECT'
    START_DIRECT = 'DRIVER_EVENT_START_DIRECT'
    STOP_DIRECT = 'DRIVER_EVENT_STOP_DIRECT'
    PING_DRIVER = 'DRIVER_EVENT_PING_DRIVER'
    FORCE_STATE = 'DRIVER_FORCE_STATE'
    CLOCK_SYNC = 'DRIVER_EVENT_CLOCK_SYNC'
    SCHEDULED_CLOCK_SYNC = 'DRIVER_EVENT_SCHEDULED_CLOCK_SYNC'
    ACQUIRE_STATUS = 'DRIVER_EVENT_ACQUIRE_STATUS'
    INIT_PARAMS = 'DRIVER_EVENT_INIT_PARAMS'
    GAP_RECOVERY = 'DRIVER_EVENT_GAP_RECOVERY'
    GAP_RECOVERY_COMPLETE = 'DRIVER_EVENT_GAP_RECOVERY_COMPLETE'

class DriverAsyncEvent(BaseEnum):
    """
    Asynchronous driver event types.
    """
    STATE_CHANGE = 'DRIVER_ASYNC_EVENT_STATE_CHANGE'
    CONFIG_CHANGE = 'DRIVER_ASYNC_EVENT_CONFIG_CHANGE'
    SAMPLE = 'DRIVER_ASYNC_EVENT_SAMPLE'
    ERROR = 'DRIVER_ASYNC_EVENT_ERROR'
    RESULT = 'DRIVER_ASYNC_RESULT'
    DIRECT_ACCESS = 'DRIVER_ASYNC_EVENT_DIRECT_ACCESS'
    AGENT_EVENT = 'DRIVER_ASYNC_EVENT_AGENT_EVENT'
    DRIVER_CONFIG = 'DRIVER_ASYNC_EVENT_DRIVER_CONFIG'

class DriverParameter(BaseEnum):
    """
    Base driver parameters. Subclassed by specific drivers with device
    specific parameters.
    """
    ALL = 'DRIVER_PARAMETER_ALL'

class InstrumentDriver(object):
    """
    Base class for instrument drivers.
    """

    def __init__(self, event_callback):
        """
        Constructor.
        @param event_callback The driver process callback used to send
        asynchronous driver events to the agent.
        """
        self._send_event = event_callback
        self._test_mode = False

    #############################################################
    # Device connection interface.
    #############################################################

    def set_test_mode(self, mode):
        """
        Enable test mode for the driver.  If this mode is invoked
        then the user has access to test_ commands.
        @param mode: test mode state
        """
        self._test_mode = True if mode else False

    def initialize(self, *args, **kwargs):
        """
        Initialize driver connection, bringing communications parameters
        into unconfigured state (no connection object).
        @raises InstrumentStateException if command not allowed in current state
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('initialize() not implemented.')

    def configure(self, *args, **kwargs):
        """
        Configure the driver for communications with the device via
        port agent / logger (valid but unconnected connection object).
        @param arg[0] comms config dict.
        @raises InstrumentStateException if command not allowed in current state
        @throws InstrumentParameterException if missing comms or invalid config dict.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('configure() not implemented.')

    def connect(self, *args, **kwargs):
        """
        Establish communications with the device via port agent / logger
        (connected connection object).
        @raises InstrumentStateException if command not allowed in current state
        @throws InstrumentConnectionException if the connection failed.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('connect() not implemented.')

    def disconnect(self, *args, **kwargs):
        """
        Disconnect from device via port agent / logger.
        @raises InstrumentStateException if command not allowed in current state
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('disconnect() not implemented.')

    #############################################################
    # Command and control interface.
    #############################################################

    def discover_state(self, *args, **kwargs):
        """
        Determine initial state upon establishing communications.
        @param timeout=timeout Optional command timeout.
        @retval Current device state.
        @raises InstrumentTimeoutException if could not wake device.
        @raises InstrumentStateException if command not allowed in current state or if
        device state not recognized.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('discover_state() is not implemented.')

    def get_resource_capabilities(self, *args, **kwargs):
        """
        Return driver commands and parameters.
        @param current_state True to retrieve commands available in current
        state, otherwise return all commands.
        @retval list of AgentCapability objects representing the drivers
        capabilities.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('get_resource_capabilities() is not implemented.')

    def get_resource_state(self, *args, **kwargs):
        """
        Return the current state of the driver.
        @retval str current driver state.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('get_resource_state() is not implemented.')

    def get_resource(self, *args, **kwargs):
        """
        Retrieve device parameters.
        @param args[0] DriverParameter.ALL or a list of parameters to retrieve
        @retval parameter : value dict.
        @raises InstrumentParameterException if missing or invalid get parameters.
        @raises InstrumentStateException if command not allowed in current state
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('get_resource() is not implemented.')

    def set_resource(self, *args, **kwargs):
        """
        Set device parameters.
        @param args[0] parameter : value dict of parameters to set.
        @param timeout=timeout Optional command timeout.
        @raises InstrumentParameterException if missing or invalid set parameters.
        @raises InstrumentTimeoutException if could not wake device or no response.
        @raises InstrumentProtocolException if set command not recognized.
        @raises InstrumentStateException if command not allowed in current state.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('set_resource() not implemented.')

    def execute_resource(self, *args, **kwargs):
        """
        Execute a driver command.
        @param timeout=timeout Optional command timeout.
        @ retval Command specific.
        @raises InstrumentTimeoutException if could not wake device or no response.
        @raises InstrumentProtocolException if command not recognized.
        @raises InstrumentStateException if command not allowed in current state.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('execute_resource() not implemented.')

    def start_direct(self, *args, **kwargs):
        """
        Start direct access mode
        @param timeout=timeout Optional command timeout.
        @ retval Command specific.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('execute_resource() not implemented.')

    def stop_direct(self, *args, **kwargs):
        """
        Stop direct access mode
        @param timeout=timeout Optional command timeout.
        @ retval Command specific.
        @raises NotImplementedException if not implemented by subclass.
        """
        raise NotImplementedException('execute_resource() not implemented.')

    ########################################################################
    # Event interface.
    ########################################################################

    def _driver_event(self, event_type, val=None):
        """
        Construct and send an asynchronous driver event.
        @param event_type a DriverAsyncEvent type specifier.
        @param val event value for sample and test result events.
        """
        event = {
            'type': event_type,
            'value': None,
            'time': time.time()
        }
        if event_type == DriverAsyncEvent.STATE_CHANGE:
            state = self.get_resource_state()
            event['value'] = state
            log.info('STATE CHANGE: %r', event)
            self._send_event(event)

        elif event_type == DriverAsyncEvent.CONFIG_CHANGE:
            config = self.get_resource(DriverParameter.ALL)
            event['value'] = config
            self._send_event(event)

        elif event_type == DriverAsyncEvent.SAMPLE:
            event['value'] = val
            self._send_event(event)

        elif event_type == DriverAsyncEvent.ERROR:
            event['value'] = val
            self._send_event(event)

        elif event_type == DriverAsyncEvent.RESULT:
            event['value'] = val
            self._send_event(event)

        elif event_type == DriverAsyncEvent.DIRECT_ACCESS:
            event['value'] = val
            self._send_event(event)

        elif event_type == DriverAsyncEvent.AGENT_EVENT:
            event['value'] = val
            self._send_event(event)

        elif event_type == DriverAsyncEvent.DRIVER_CONFIG:
            event['value'] = val
            self._send_event(event)

    ########################################################################
    # Test interface.
    ########################################################################

    def driver_ping(self, msg):
        """
        Echo a message.
        @param msg the message to prepend and echo back to the caller.
        """
        reply = 'driver_ping: %r %s' % (self, msg)
        return reply

    def test_exceptions(self, msg):
        """
        Test exception handling in the driver process.
        @param msg message string to put in a raised exception to be caught in
        a test.
        @raises InstrumentException always.
        """
        raise InstrumentException(msg)

# noinspection PyMethodMayBeStatic,PyProtectedMember,PyUnusedLocal
class SingleConnectionInstrumentDriver(InstrumentDriver):
    """
    Base class for instrument drivers with a single device connection.
    Provides connection state logic for single connection drivers. This is
    the base class for the majority of driver implementation classes.
    """
    __metaclass__ = META_LOGGER

    def __init__(self, event_callback, refdes=None):
        """
        Constructor for singly connected instrument drivers.
        @param event_callback Callback to the driver process to send asynchronous
        driver events back to the agent.
        """
        InstrumentDriver.__init__(self, event_callback)

        # The one and only instrument connection.
        # Exists in the connected state.
        self._connection = None

        # The one and only instrument protocol.
        self._protocol = None

        # Consul
        self.consul = consulate.Consul()

        # Reference Designator to the port agent service
        self.refdes = refdes

        # Build connection state machine.
        self._connection_fsm = ThreadSafeFSM(DriverConnectionState,
                                             DriverEvent,
                                             DriverEvent.ENTER,
                                             DriverEvent.EXIT)

        # Add handlers for all events.
        handlers = {
            DriverState.UNCONFIGURED: [
                (DriverEvent.ENTER, self._handler_unconfigured_enter),
                (DriverEvent.EXIT, self._handler_unconfigured_exit),
                (DriverEvent.INITIALIZE, self._handler_unconfigured_initialize),
                (DriverEvent.CONFIGURE, self._handler_unconfigured_configure),
            ],
            DriverConnectionState.DISCONNECTED: [
                (DriverEvent.ENTER, self._handler_disconnected_enter),
                (DriverEvent.EXIT, self._handler_disconnected_exit),
                (DriverEvent.INITIALIZE, self._handler_disconnected_initialize),
                (DriverEvent.CONFIGURE, self._handler_disconnected_configure),
                (DriverEvent.CONNECT, self._handler_disconnected_connect),
            ],
            DriverConnectionState.INST_DISCONNECTED: [
                (DriverEvent.ENTER, self._handler_inst_disconnected_enter),
                (DriverEvent.EXIT, self._handler_inst_disconnected_exit),
                (DriverEvent.CONNECT, self._handler_inst_disconnected_connect),
                (DriverEvent.CONNECTION_LOST, self._handler_connected_connection_lost),
                (DriverEvent.PA_CONNECTION_LOST, self._handler_inst_disconnected_pa_connection_lost),
            ],
            DriverConnectionState.CONNECTED: [
                (DriverEvent.ENTER, self._handler_connected_enter),
                (DriverEvent.EXIT, self._handler_connected_exit),
                (DriverEvent.DISCONNECT, self._handler_connected_disconnect),
                (DriverEvent.CONNECTION_LOST, self._handler_connected_connection_lost),
                (DriverEvent.PA_CONNECTION_LOST, self._handler_connected_pa_connection_lost),
                (DriverEvent.DISCOVER, self._handler_connected_protocol_event),
                (DriverEvent.GET, self._handler_connected_protocol_event),
                (DriverEvent.SET, self._handler_connected_protocol_event),
                (DriverEvent.EXECUTE, self._handler_connected_protocol_event),
                (DriverEvent.FORCE_STATE, self._handler_connected_protocol_event),
                (DriverEvent.START_DIRECT, self._handler_connected_start_direct_event),
                (DriverEvent.STOP_DIRECT, self._handler_connected_stop_direct_event),
            ],
        }

        for state in handlers:
            for event, handler in handlers[state]:
                self._connection_fsm.add_handler(state, event, handler)

        self._pre_da_config = {}
        self._port_agent_config = {}
        self._startup_config = {}

        # Idempotency flag for lost connections.
        # This set to false when a connection is established to
        # allow for lost callback to become activated.
        self._connection_lost = True

        # Autoconnect flag
        # Set this to false to disable autoconnect
        self._autoconnect = True
        self._reconnect_interval = STARTING_RECONNECT_INTERVAL
        self._max_reconnect_interval = MAXIMUM_RECONNECT_INTERVAL

        # Start state machine.
        self._connection_fsm.start(DriverConnectionState.UNCONFIGURED)

    #############################################################
    # Device connection interface.
    #############################################################

    def initialize(self, *args, **kwargs):
        """
        Initialize driver connection, bringing communications parameters
        into unconfigured state (no connection object).
        @raises InstrumentStateException if command not allowed in current state
        """
        # Forward event and argument to the connection FSM.
        return self._connection_fsm.on_event(DriverEvent.INITIALIZE, *args, **kwargs)

    def configure(self, *args, **kwargs):
        """
        Configure the driver for communications with the device via
        port agent / logger (valid but unconnected connection object).
        @param arg[0] comms config dict.
        @raises InstrumentStateException if command not allowed in current state
        @throws InstrumentParameterException if missing comms or invalid config dict.
        """
        # Forward event and argument to the connection FSM.
        return self._connection_fsm.on_event(DriverEvent.CONFIGURE, *args, **kwargs)

    def connect(self, *args, **kwargs):
        """
        Establish communications with the device via port agent / logger
        (connected connection object).
        @raises InstrumentStateException if command not allowed in current state
        @throws InstrumentConnectionException if the connection failed.
        """
        # Forward event and argument to the connection FSM.
        result = self._connection_fsm.on_event(DriverEvent.CONNECT, *args, **kwargs)

    def disconnect(self, *args, **kwargs):
        """
        Disconnect from device via port agent / logger.
        @raises InstrumentStateException if command not allowed in current state
        """
        # Disable autoconnect if manually disconnected
        self._autoconnect = False
        # Forward event and argument to the connection FSM.
        return self._connection_fsm.on_event(DriverEvent.DISCONNECT, *args, **kwargs)

    #############################################################
    # Configuration logic
    #############################################################
    def get_init_params(self):
        """
        get the driver initialization parameters
        @return driver configuration dictionary
        """
        return self._startup_config

    def set_init_params(self, config):
        """
        Set the initialization parameters down in the protocol and store the
        driver configuration in the driver.

        If the protocol hasn't been setup yet cache the config.  Next time
        this method is called, if you call it with an empty config it will
        read from the cache.

        @param config This default configuration assumes a structure driver
        configuration dict with keys named in DriverConfigKey.
        Stranger parameters can be adjusted by over riding this method.
        @raise InstrumentParameterException If the config cannot be applied
        """
        if not isinstance(config, dict):
            raise InstrumentParameterException("Incompatible initialization parameters")

        if self._protocol:
            param_config = None
            if config:
                param_config = config
            elif self._startup_config:
                param_config = self._startup_config

            if param_config:
                self._protocol.set_init_params(param_config)
                self._protocol.initialize_scheduler()

        if config:
            self._startup_config = config

    def apply_startup_params(self):
        """
        Apply the startup values previously stored in the protocol to
        the running config of the live instrument. The startup values are the
        values that are (1) marked as startup parameters and are (2) the "best"
        value to use at startup. Preference is given to the previously-set init
        value, then the default value, then the currently used value.

        This default implementation simply pushes the logic down into the protocol
        for processing should the action be better accomplished down there.

        The driver writer can decide to overload this method in the derived
        driver class and apply startup parameters in the driver (likely calling
        some get and set methods for the resource). If the driver does not
        implement an apply_startup_params() method in the driver, this method
        will call into the protocol. Deriving protocol classes are expected to
        implement an apply_startup_params() method lest they get the exception
        from the base InstrumentProtocol implementation.
        """
        log.debug("Base driver applying startup params...")
        self._protocol.apply_startup_params()

    def get_cached_config(self):
        """
        Return the configuration object that shows the instrument's
        configuration as cached in the protocol parameter dictionary.
        @retval The running configuration in the instruments config format. By
        default, it is a dictionary of parameter names and values.
        """
        if self._protocol:
            return self._protocol.get_cached_config()

    def get_config_metadata(self):
        """
        Return the configuration metadata object in JSON format
        @retval The description of the parameters, commands, and driver info
        in a JSON string
        @see https://confluence.oceanobservatories.org/display/syseng/
        CIAD+MI+SV+Instrument+Driver-Agent+parameter+and+command+metadata+exchange
        """
        log.debug("Getting metadata from driver...")
        protocol = self._protocol

        if protocol:
            log.debug("Getting metadata from protocol...")
            return self._protocol.get_config_metadata_dict()

    def get_direct_config(self):
        """
        Note - must override if instrument driver has more than one instrument configuration.
        :return: list of dictionaries containing direct access configuration and commands
        """
        config = {}
        if self._protocol:
            config = self._protocol.get_direct_config()
            config['ip'] = self._port_agent_config.get('host', 'uft20')
            config['data'] = self._port_agent_config.get('ports', {}).get('da')
            config['sniffer'] = self._port_agent_config.get('ports', {}).get('sniff')
        return [config]

    def restore_direct_access_params(self, config):
        """
        Restore the correct values out of the full config that is given when
        returning from direct access. By default, this takes a simple dict of
        param name and value. Override this class as needed as it makes some
        simple assumptions about how your instrument sets things.

        @param config The configuration that was previously saved (presumably
        to disk somewhere by the driver that is working with this protocol)
        """
        vals = {}
        # for each parameter that is read only, restore
        da_params = self._protocol.get_direct_access_params()
        for param in da_params:
            vals[param] = config[param]

        log.debug("Restore DA Parameters: %r", vals)
        self.set_resource(vals, True)

    #############################################################
    # Command and control interface.
    #############################################################

    def discover_state(self, *args, **kwargs):
        """
        Determine initial state upon establishing communications.
        @param timeout=timeout Optional command timeout.
        @retval Current device state.
        @raises InstrumentTimeoutException if could not wake device.
        @raises InstrumentStateException if command not allowed in current state or if
        device state not recognized.
        @raises NotImplementedException if not implemented by subclass.
        """
        # Forward event and argument to the protocol FSM.
        return self._connection_fsm.on_event(
            DriverEvent.DISCOVER, DriverEvent.DISCOVER, *args, **kwargs)

    def get_resource_capabilities(self, current_state=True, *args, **kwargs):
        """
        Return driver commands and parameters.
        @param current_state True to retrieve commands available in current
        state, otherwise return all commands.
        @retval list of AgentCapability objects representing the drivers
        capabilities.
        @raises NotImplementedException if not implemented by subclass.
        """

        if self._protocol:
            return self._protocol.get_resource_capabilities(current_state)

        else:
            return [[], []]

    def get_resource_state(self, *args, **kwargs):
        """
        Return the current state of the driver.
        @retval str current driver state.
        @raises NotImplementedException if not implemented by subclass.
        """
        connection_state = self._connection_fsm.get_current_state()
        if self._protocol:
            return self._protocol.get_current_state()
        else:
            return connection_state

    def get_resource(self, *args, **kwargs):
        """
        Retrieve device parameters.
        @param args[0] DriverParameter.ALL or a list of parameters to retrieve.
        @retval parameter : value dict.
        @raises InstrumentParameterException if missing or invalid get parameters.
        @raises InstrumentStateException if command not allowed in current state
        @raises NotImplementedException if not implemented by subclass.
        """
        # Forward event and argument to the protocol FSM.
        return self._connection_fsm.on_event(DriverEvent.GET, DriverEvent.GET, *args, **kwargs)

    def set_resource(self, *args, **kwargs):
        """
        Set device parameters.
        @param args[0] parameter : value dict of parameters to set.
        @param timeout=timeout Optional command timeout.
        @raises InstrumentParameterException if missing or invalid set parameters.
        @raises InstrumentTimeoutException if could not wake device or no response.
        @raises InstrumentProtocolException if set command not recognized.
        @raises InstrumentStateException if command not allowed in current state.
        @raises NotImplementedException if not implemented by subclass.
        """
        # Forward event and argument to the protocol FSM.
        return self._connection_fsm.on_event(DriverEvent.SET, DriverEvent.SET, *args, **kwargs)

    def execute_resource(self, resource_cmd, *args, **kwargs):
        """
        Poll for a sample.
        @param timeout=timeout Optional command timeout.
        @ retval Device sample dict.
        @raises InstrumentTimeoutException if could not wake device or no response.
        @raises InstrumentProtocolException if acquire command not recognized.
        @raises InstrumentStateException if command not allowed in current state.
        @raises NotImplementedException if not implemented by subclass.
        """
        # Forward event and argument to the protocol FSM.
        return self._connection_fsm.on_event(DriverEvent.EXECUTE, resource_cmd, *args, **kwargs)

    def start_direct(self, *args, **kwargs):
        """
        start direct access mode
        @param timeout=timeout Optional command timeout.
        @ retval Device sample dict.
        @raises InstrumentTimeoutException if could not wake device or no response.
        @raises InstrumentProtocolException if acquire command not recognized.
        @raises InstrumentStateException if command not allowed in current state.
        @raises NotImplementedException if not implemented by subclass.
        """
        # Need to pass the event as a parameter because the event handler to capture the current
        # pre-da config requires it.
        return self._connection_fsm.on_event(DriverEvent.START_DIRECT, DriverEvent.START_DIRECT)

    def execute_direct(self, *args, **kwargs):
        """
        execute direct access command
        @param timeout=timeout Optional command timeout.
        @ retval Device sample dict.
        @raises InstrumentTimeoutException if could not wake device or no response.
        @raises InstrumentProtocolException if acquire command not recognized.
        @raises InstrumentStateException if command not allowed in current state.
        @raises NotImplementedException if not implemented by subclass.
        """
        return self.execute_resource(DriverEvent.EXECUTE_DIRECT, *args, **kwargs)

    def stop_direct(self, *args, **kwargs):
        """
        stop direct access mode
        @param timeout=timeout Optional command timeout.
        @ retval Device sample dict.
        @raises InstrumentTimeoutException if could not wake device or no response.
        @raises InstrumentProtocolException if acquire command not recognized.
        @raises InstrumentStateException if command not allowed in current state.
        @raises NotImplementedException if not implemented by subclass.
        """
        return self._connection_fsm.on_event(DriverEvent.STOP_DIRECT, DriverEvent.STOP_DIRECT)

    def test_force_state(self, *args, **kwargs):
        """
        Force driver into a given state for the purposes of unit testing
        @param state=desired_state Required desired state to change to.
        @raises InstrumentParameterException if no state parameter.
        @raises TestModeException if not in test mode
        """

        if not self._test_mode:
            raise TestModeException()

        # Get the required param
        state = kwargs.get('state', None)  # via kwargs
        if state is None:
            raise InstrumentParameterException('Missing state parameter.')

        # We are mucking with internal FSM parameters which may be bad.
        # The alternative was to raise an event to change the state. Don't
        # know which is better.
        self._protocol._protocol_fsm.current_state = state

    ########################################################################
    # Unconfigured handlers.
    ########################################################################

    def _handler_unconfigured_enter(self, *args, **kwargs):
        """
        Enter unconfigured state.
        """
        # Send state change event to agent.
        self._driver_event(DriverAsyncEvent.STATE_CHANGE)
        # attempt to auto-configure from consul
        self._auto_config_with_backoff()

    def _handler_unconfigured_exit(self, *args, **kwargs):
        """
        Exit unconfigured state.
        """
        pass

    def _handler_unconfigured_initialize(self, *args, **kwargs):
        """
        Initialize handler. We are already in unconfigured state, do nothing.
        @retval (next_state, result) tuple, (None, None).
        """
        return None, None

    def _handler_unconfigured_configure(self, *args, **kwargs):
        """
        Configure driver for device comms.
        @param args[0] Communications config dictionary.
        @retval (next_state, result) tuple, (DriverConnectionState.DISCONNECTED,
        None) if successful, (None, None) otherwise.
        @raises InstrumentParameterException if missing or invalid param dict.
        """
        # Verify configuration dict, and update connection if possible.
        try:
            self._connection = self._build_connection(*args, **kwargs)
        except AutoDiscoverFailure:
            self._auto_config_with_backoff()
            return None, None
        except InstrumentException:
            self._auto_config_with_backoff()
            raise

        return DriverConnectionState.DISCONNECTED, None

    ########################################################################
    # Disconnected handlers.
    ########################################################################

    def _handler_disconnected_enter(self, *args, **kwargs):
        """
        Enter disconnected state.
        """
        # Send state change event to agent.
        self._driver_event(DriverAsyncEvent.STATE_CHANGE)

        if self._autoconnect:
            self._async_raise_event(DriverEvent.CONNECT, *args, **kwargs)

    def _handler_disconnected_exit(self, *args, **kwargs):
        """
        Exit disconnected state.
        """
        pass

    def _handler_disconnected_initialize(self, *args, **kwargs):
        """
        Initialize device communications. Causes the connection parameters to
        be reset.
        @retval (next_state, result) tuple, (DriverConnectionState.UNCONFIGURED,
        None).
        """
        self._connection = None
        return DriverConnectionState.UNCONFIGURED, None

    def _handler_disconnected_configure(self, *args, **kwargs):
        """
        Configure driver for device comms.
        @param args[0] Communications config dictionary.
        @retval (next_state, result) tuple, (None, None).
        @raises InstrumentParameterException if missing or invalid param dict.
        """
        # Verify configuration dict, and update connection if possible.
        try:
            self._connection = self._build_connection(*args, **kwargs)
        except AutoDiscoverFailure:
            return DriverConnectionState.UNCONFIGURED, None
        return None, None

    def _handler_disconnected_connect(self, *args, **kwargs):
        """
        Establish communications with the device via port agent / logger and
        construct and initialize a protocol FSM for device interaction.
        @retval (next_state, result) tuple, (DriverConnectionState.CONNECTED,
        None) if successful.
        """
        result = None

        try:
            self._connection.init_comms()
            next_state = DriverConnectionState.INST_DISCONNECTED
        except InstrumentConnectionException as e:
            log.error("Connection Exception: %s", e)
            log.error("Instrument Driver returning to unconfigured state.")
            next_state = DriverConnectionState.UNCONFIGURED

        init_config = {}
        if len(args) > 0 and isinstance(args[0], dict):
            init_config = args[0]
        self.set_init_params(init_config)

        return next_state, result

    ########################################################################
    # PA Connected handlers.
    ########################################################################

    def _handler_inst_disconnected_enter(self, *args, **kwargs):
        """
        Enter connected state.
        """
        self._connection_lost = False
        # reset the reconnection interval to 1
        self._reconnect_interval = STARTING_RECONNECT_INTERVAL

        # Send state change event to agent.
        self._driver_event(DriverAsyncEvent.STATE_CHANGE)

    def _handler_inst_disconnected_exit(self, *args, **kwargs):
        """
        Exit connected state.
        """
        pass

    def _handler_inst_disconnected_connect(self, *args, **kwargs):
        self._build_protocol()
        self.set_init_params({})
        self._protocol._connection = self._connection
        return DriverConnectionState.CONNECTED, None

    def _handler_inst_disconnected_pa_connection_lost(self, *args, **kwargs):
        return None, None

    ########################################################################
    # Connected handlers.
    ########################################################################

    def _handler_connected_enter(self, *args, **kwargs):
        """
        Enter connected state.
        """
        # Send state change event to agent.
        self._driver_event(DriverAsyncEvent.STATE_CHANGE)

    def _handler_connected_exit(self, *args, **kwargs):
        """
        Exit connected state.
        """
        pass

    def _handler_connected_disconnect(self, *args, **kwargs):
        """
        Disconnect to the device via port agent / logger and destroy the
        protocol FSM.
        @retval (next_state, result) tuple, (DriverConnectionState.DISCONNECTED,
        None) if successful.
        """
        log.info("_handler_connected_disconnect: invoking stop_comms().")
        self._connection.stop_comms()
        self._destroy_protocol()

        return DriverConnectionState.UNCONFIGURED, None

    def _handler_connected_connection_lost(self, *args, **kwargs):
        """
        The device connection was lost. Stop comms, destroy protocol FSM and
        revert to disconnected state.
        @retval (next_state, result) tuple, (DriverConnectionState.DISCONNECTED,
        None).
        """
        log.info("_handler_connected_connection_lost: invoking stop_comms().")
        self._connection.stop_comms()
        self._destroy_protocol()

        # Send async agent state change event.
        log.info("_handler_connected_connection_lost: sending LOST_CONNECTION "
                 "event, moving to UNCONFIGURED state.")
        self._driver_event(DriverAsyncEvent.AGENT_EVENT,
                           ResourceAgentEvent.LOST_CONNECTION)

        return DriverConnectionState.UNCONFIGURED, None

    def _handler_connected_pa_connection_lost(self, *args, **kwargs):
        self._destroy_protocol()

        return DriverConnectionState.INST_DISCONNECTED, None

    def _handler_connected_protocol_event(self, event, *args, **kwargs):
        """
        Forward a driver command event to the protocol FSM.
        @param args positional arguments to pass on.
        @param kwargs keyword arguments to pass on.
        @retval (next_state, result) tuple, (None, protocol result).
        """
        next_state = None
        if event == DriverEvent.START_DIRECT:
            return self._handler_connected_start_direct_event(event, *args, **kwargs)
        elif event == DriverEvent.STOP_DIRECT:
            return self._handler_connected_stop_direct_event(event, *args, **kwargs)

        result = self._protocol._protocol_fsm.on_event(event, *args, **kwargs)
        return next_state, result

    def _handler_connected_start_direct_event(self, event, *args, **kwargs):
        """
        Stash the current config first, then forward a driver command event
        to the protocol FSM.
        @param args positional arguments to pass on.
        @param kwargs keyword arguments to pass on.
        @retval (next_state, result) tuple, (None, protocol result).
        """
        next_state = None

        # Get the value for all direct access parameters and store them in the protocol
        self._pre_da_config = self.get_resource(self._protocol.get_direct_access_params())
        self._protocol.store_direct_access_config(self._pre_da_config)
        self._protocol.enable_da_initialization()
        log.debug("starting DA.  Storing DA parameters for restore: %s", self._pre_da_config)

        result = self._protocol._protocol_fsm.on_event(event, *args, **kwargs)
        return next_state, result

    def _handler_connected_stop_direct_event(self, event, *args, **kwargs):
        """
        Restore previous config first, then forward a driver command event
        to the protocol FSM.
        @param args positional arguments to pass on.
        @param kwargs keyword arguments to pass on.
        @retval (next_state, result) tuple, (None, protocol result).
        """
        next_state = None
        result = self._protocol._protocol_fsm.on_event(event, *args, **kwargs)

        # Moving the responsibility for applying DA parameters to the
        # protocol.
        # self.restore_direct_access_params(self._pre_da_config)

        return next_state, result

    ########################################################################
    # Helpers.
    ########################################################################

    def _build_connection(self, *args, **kwargs):
        """
        Constructs and returns a Connection object according to the given
        configuration. The connection object is a LoggerClient instance in
        this base class. Subclasses can overwrite this operation as needed.
        The value returned by this operation is assigned to self._connection
        and also to self._protocol._connection upon entering in the
        DriverConnectionState.CONNECTED state.

        @param config configuration dict

        @retval a Connection instance, which will be assigned to
                  self._connection

        @throws InstrumentParameterException Invalid configuration.
        """
        # Get required config param dict.
        config = kwargs.get('config', None)  # via kwargs
        if config is None and len(args) > 0:
            config = args[0]  # via first argument

        if config is None:
            config = self._get_config_from_consul(self.refdes)

            if config is None:
                raise AutoDiscoverFailure()

        if 'mock_port_agent' in config:
            mock_port_agent = config['mock_port_agent']
            # check for validity here...
            if mock_port_agent is not None:
                return mock_port_agent

        try:
            addr = config['addr']
            port = config['port']
            cmd_port = config.get('cmd_port')

            if isinstance(addr, basestring) and isinstance(port, int) and len(addr) > 0:
                return PortAgentClient(addr, port, cmd_port, self._got_data, self._lost_connection_callback)
            else:
                raise InstrumentParameterException('Invalid comms config dict.')

        except (TypeError, KeyError):
            raise InstrumentParameterException('Invalid comms config dict.')

    def _get_config_from_consul(self, tag):
        """
        Query consul for the port agent service
        configuration parameters: data port, command port, and address
        This will retry a specified number of times with exponential backoff.
        """
        try:
            data_port = self.consul.health.service('port-agent', passing=True, tag=tag)
            cmd_port = self.consul.health.service('command-port-agent', passing=True, tag=tag)

            if data_port and cmd_port:
                port = data_port[0]['Service']['Port']
                addr = data_port[0]['Node']['Address']
                cmd_port = cmd_port[0]['Service']['Port']
                port_agent_config = {'port': port, 'cmd_port': cmd_port, 'addr': addr}
                return port_agent_config
        except ConnectionError:
            return None

    def _got_exception(self, exception):
        """
        Callback for the client for exception handling with async data.  Exceptions
        are wrapped in an event and sent up to the agent.
        """
        try:
            log.error("ASYNC Data Exception Detected: %s (%s)",
                      exception.__class__.__name__, str(exception))
        finally:
            self._driver_event(DriverAsyncEvent.ERROR, exception)

    def _got_data(self, port_agent_packet):
        if isinstance(port_agent_packet, Exception):
            return self._got_exception(port_agent_packet)

        if isinstance(port_agent_packet, PortAgentPacket):
            packet_type = port_agent_packet.get_header_type()
            data = port_agent_packet.get_data()

            if packet_type == PortAgentPacket.PORT_AGENT_CONFIG:
                try:
                    paconfig = json.loads(data)
                    self._port_agent_config = paconfig
                    self._driver_event(DriverAsyncEvent.DRIVER_CONFIG, paconfig)
                except ValueError as e:
                    log.exception('Unable to parse port agent config: %r %r', data, e)

            elif packet_type == PortAgentPacket.PORT_AGENT_STATUS:
                log.debug('Received PORT AGENT STATUS: %r', data)
                current_state = self._connection_fsm.get_current_state()
                if data == 'DISCONNECTED':
                    if current_state == DriverConnectionState.CONNECTED:
                        self._async_raise_event(DriverEvent.PA_CONNECTION_LOST)
                elif data == 'CONNECTED':
                    if current_state == DriverConnectionState.INST_DISCONNECTED:
                        self._async_raise_event(DriverEvent.CONNECT)

            else:
                if self._protocol:
                    self._protocol.got_data(port_agent_packet)

    def _lost_connection_callback(self):
        """
        A callback invoked by the port agent client when it loses
        connectivity to the port agent.
        """

        if not self._connection_lost:
            log.info("_lost_connection_callback: starting thread to send "
                     "CONNECTION_LOST event to instrument driver.")
            self._connection_lost = True
            self._async_raise_event(DriverEvent.CONNECTION_LOST)
        else:
            log.info("_lost_connection_callback: connection_lost flag true.")

    def _build_protocol(self):
        """
        Construct device specific single connection protocol FSM.
        Overridden in device specific subclasses.
        """
        pass

    def _auto_config_with_backoff(self):
        # randomness to prevent all instrument drivers from trying to reconnect at the same exact time.
        self._reconnect_interval = self._reconnect_interval * 2 + random.uniform(-.5, .5)
        self._reconnect_interval = min(self._reconnect_interval, self._max_reconnect_interval)
        self._async_raise_event(DriverEvent.CONFIGURE, event_delay=self._reconnect_interval)
        log.info('Created delayed CONFIGURE event with %.2f second delay', self._reconnect_interval)

    def _async_raise_event(self, event, *args, **kwargs):
        delay = kwargs.pop('event_delay', 0)

        def inner():
            try:
                time.sleep(delay)
                log.info('Async raise event: %r', event)
                self._connection_fsm.on_event(event)
            except Exception as exc:
                log.exception('Exception in asynchronous thread: %r', exc)
                self._driver_event(DriverAsyncEvent.ERROR, exc)
            log.info('_async_raise_fsm_event: event complete. bub bye thread. (%r)', args)

        thread = Thread(target=inner)
        thread.daemon = True
        thread.start()

    def _destroy_protocol(self):
        if self._protocol:
            scheduler = self._protocol._scheduler
            if scheduler:
                scheduler._scheduler.shutdown()
            scheduler = None
            self._protocol = None


Sometimes filling a need is just the right idea for making money!
There's not a person on the planet that has not found themselves running out of power on their cellphone. Providing a solution also represents a business opportunity. Cell Phone Charging stations provide people with secure and simple opportunity to recharge and make you money.
There are a variety of versions from a single module to multiple module walls. You can increase revenues by incorporating a digital advertising screen too.
Take a look at our gallery below and be inspired!
Whether you are new to vending and looking for an opportunity, or an experienced vending operator looking to increase your estate, the cell phone charging station is a great concept for you. Pick up the phone and talk to us.


text:
Randy's Donuts Opens on the Walk of Yum, er, Fame
A doughnut themed to Tinseltown is on the menu, oh yeah.
By Alysia Gray Painter
Published Dec 10, 2018 at 9:57 AM
Randy's Donuts
The newest star in Hollywood? Why it's that classic SoCal bastion o' doughnut wizardy, Randy's. Find it at Hollywood & Highland, right on the boulevard, beginning on Monday, Dec. 10.
6801 Hollywood Boulevard
Hollywood & Highland
Sun-Thu 8 a.m. to 10 p.m., Fri-Sat 8 a.m. to midnight
A few years ago, as in not so long ago, as in a different doughnut day, you had to make a trek, or pilgrimage, even, to get your favorite goodie at Randy's Donuts.
Of course, finding the pastry palace wasn't all that hard: The Randy's location known throughout the world, via legend, reputation, and "Iron Man 2," is the one with the ginormous doughnut on top.
And when we say it can be found pretty dang close to LAX, we're not whistling through a doughnut hole.
But new Randy's shops has been popping up elsewhere around the region, with precision and regularity, much like tempting balls of sugary dough dropping onto a buttered baking sheet.
Film-tastic: Academy Museum Reveals First Exhibits
Look to Century City for a still-new Randy's, and, earlier in 2018, El Segundo, too.
And now, starting on Monday, Dec. 10, Hollywood & Highland, where the latest Randy's Donuts is stirring up its starry batter.
And we're not tossing "starry" around there, for the newest location, which is right on Hollywood Boulevard, will boast a Hollywood Star doughnut.
Rosy Outlook: Free Pasadena Visitor Hotline Opens
Which, yes, you could purchase, and then take right outside the front door and eat while standing on an actual Walk of Fame star.
That front door, by the way, is framed by an "18-foot-wide, donut-shaped entrance," which creates an eye-catching first impression along a highly visual stretch that very much serves to catch a lot of eyes in a million different ways, or seemingly so.
There's more eye-catching-a-tude inside the new Randy's Donuts, which also includes a mural that's decidedly "pop culture" in theme.
But as far as what's in the display cases, and, later, in the bag you're walking out with, and, later, in your tum?
Prepare for 40-plus varieties of doughnut-based and doughnut-related deliciousness, and we're including fritters and cinnamon rolls in that, as we most definitely should.
Get the latest from NBC4 anywhere, anytime
Follow NBC4

redpajama_set_name: RedPajamaCommonCrawl


IPORT LAKES – 4 Shoveler, 229 Tufted Duck, 2 Pochard, 4 Cormorant, 6 LITTLE EGRET, 1 Grey Heron, c.35 Lapwing, 2 Common Sandpiper, 1 Green Sandpiper, 5 Greenshank, 1 WOOD SANDPIPER, 1j COMMON TERN, 1 Kestrel, 30+ Swallow SW, c.100 House Martin, 1 Chiffchaff, 10+ Yellow Wagtail, 20+ Pied Wagtail (Bob Usher, Chris Robinson, Dave MacWilliams). Added to Birdtrack.
LOCAL – Weather: mainly overcast interspersed with variable cloudy skies with some sunshine; some rain during the early hours. Visibility: very good/excellent throughout. Temperatures: +12.8°C to +11.2°C to 16.7°C to ??.?°C. Wind: very light/light throughout, variable in direction but wholly from within the SW quarter. Surface pressure: 1018hPa-1019hPa-101?hPa. Fronts etc.: none.


We miss and still really enjoy treats like cakes and biscuits, but to buy these from the supermarket can be costly!
Combine all the ingredients in a bowl until dough forms. Roll into a ball and wrap with glad wrap – leave in fridge for an hour. From there, roll into little balls and press down with your fingers or a fork – I have tried to cut into shapes but because it is such a wetter mix in comparison to normal shortbread, its harder to work with.
Bake for 30 mins on 150 – 160 (oven dependant) They will spread slightly and the shortbread will form a crust around the edges where it has spread/butter is coming out – but just leave them. Remove from the oven, and let them rest for 30 mins. Don't touch them until they are stone cold – as they will just crumble. Once they're cold, they'll be nice and hard and ready to eat!


Kevin completed his Bachelor's Degree at the University of Manitoba in 2000. Upon arrival to his first job on 7A south at the St. Boniface hospital, he was volunteered to become the unit's Ward Representative. Moving to Calgary in May of 2001, Kevin accepted a position at the Foothills Medical Centre (FMC) in general surgery on unit 102. Within a year of arriving to Calgary his activism within the union was in full swing, once again becoming a Ward Representative. He became a Professional Responsibility Concern Committee member which ignited his passion for social justice. His career transitioned to various areas developing his experience as a Registered Nurse and growing within the United Nurses of Alberta (UNA). Over the next 5 years, Kevin worked in various areas including research and rural medicine in Claresholm, before finding his niche in the Intensive Care Unit (ICU) at FMC. He has previously completed one term as a provincial counsellor for the College and Association of Registered Nurses of Alberta and has represented the South Central District of UNA on the provincial Joint Committee. As the running President of Local 115 for the last twelve years, Kevin has represented nurses tirelessly through grievances and patient and individual safety concerns, with a mandate of always being at your side.
Having spent time working in EMS and as an LPN, Wayne finished with a Baccalaureate degree in Nursing from Mount Royal College in 2004. He became active in the union shortly after graduation, beginning as a Unit/Ward Representative in Neurology while working as a Registered Nurse at the Foothills Medical Centre and continuing the role during transition into the Emergency Department in 2006. From 2014 - 2016 he served as the Executive Secretary of Local 115 and, in 2017, was elected into and currently serves as, the Local's Vice-President. To date, Wayne supports Local 115's Occupational Health and Safety and Professional Responsibility Concern Committees, is involved in the Calgary District Labour Council, and spends time lobbying government for Pharmacare and universal child care for all.
Sheldon graduated with a Bachelor of Science in Nursing degree from the College of the Rockies/University of Victoria transfer program in 2011 after finishing a final practicum in the Emergency Department at the Royal Jubilee Hospital. His career has been spent working as a Registered Nurse at Foothills Medical Centre in a variety of areas including surgical orthopedics, general neurology, stroke and acute medicine. He has also spent time assisting in research with the Calgary Stroke Program and served a year as a Unit Manager in Neurology. Sheldon's involvement with Local 115 of the United Nurses of Alberta began as a member of the Communication Committee in 2015 writing articles for the quarterly newsletter such as "The Benefit of Having Benefits - Maternity Leave", "Bullying", "A Crash Course in Workplace Accommodation", and "A Nurse's Guide to Privacy". Sheldon was elected into the role of Executive Secretary in 2017 and now serves as chair of the Communication Committee. His primary purpose is to serve the members of Local 115 by upholding a primary obligation in Collective Agreement administration while increasing membership engagement across the Local.
James graduated from nursing at Mount Royal College in 1995 and most recently completed a graduate degree in leadership studies at Royal Roads University in Victoria, BC. A nurse for over 24 years, James has experience in medical nursing, nephrology, emergency department, neonatal ICU, palliative care, nursing education, program development and clinical management. During the 1990's downturn, he worked in California, Texas and Washington, returning back home to Calgary 15 years later. James's healthcare interests lie in improving patient outcomes, enhancing patient safety, building stronger teams, creating healthier work environments and challenging systemic problems. Elected to a PRC position in December 2017, he was appointed Co-Chair of the Joint PRC Committee in March 2018. In November 2018, James was elected to the Treasurer role for Local 115.


text:
Opularity, a site for learning what you need to know.
## Providing Services like
 - How to create a basic website
 - The basics of Github
 - and more.

redpajama_set_name: RedPajamaGithub


text:
'She cannot smile the smile that wells up from the heart': beauty, health, and emotion in Six to Sixteen and The Secret Garden
Michelle Smith
Beauty ideals for girls were intimately connected with the concept of health in late nineteenth-century print culture. The healthy girl would necessarily have a cheerful character and a pleasing appearance. In contrast, in the Girl's Own Book of Health and Beauty, Gordon Stables, a former Royal Navy surgeon who wrote the medical advice column for the popular British girls' magazine, the Girl's Own Paper, explains that unhealthy girls could be neither beautiful nor happy: Brightness of eyes, clearness of complexion, and happiness of expression, belong only to the possessor of health. The guide book is typical of representations of girls in fiction and advice of the period in its correlation of health with beauty and happiness. The Girl's Own Book of Health and Beauty implicitly argues against any form of external cosmetics by glorifying the relationship between inner health and pleasing external features.
Affect, Emotion, and Children's Literature
Representation and Socialisation in Texts for Children and Young Adults
Kristine Moruzi, Michelle J. Smith, Elizabeth Bullen
New York NY USA
https://doi.org/10.4324/9781315266961-5
Children's Literature and Culture
10.4324/9781315266961-5
Smith, M. (2018). 'She cannot smile the smile that wells up from the heart': beauty, health, and emotion in Six to Sixteen and The Secret Garden. In K. Moruzi, M. J. Smith, & E. Bullen (Eds.), Affect, Emotion, and Children's Literature: Representation and Socialisation in Texts for Children and Young Adults (1st ed., pp. 66-78). (Children's Literature and Culture). Routledge. https://doi.org/10.4324/9781315266961-5
Smith, Michelle. / 'She cannot smile the smile that wells up from the heart' : beauty, health, and emotion in Six to Sixteen and The Secret Garden. Affect, Emotion, and Children's Literature: Representation and Socialisation in Texts for Children and Young Adults. editor / Kristine Moruzi ; Michelle J. Smith ; Elizabeth Bullen. 1st. ed. New York NY USA : Routledge, 2018. pp. 66-78 (Children's Literature and Culture).
@inbook{9056df89e143465597a6a1b39bc3e338,
title = "{\textquoteleft}She cannot smile the smile that wells up from the heart{\textquoteright}: beauty, health, and emotion in Six to Sixteen and The Secret Garden",
abstract = "Beauty ideals for girls were intimately connected with the concept of health in late nineteenth-century print culture. The healthy girl would necessarily have a cheerful character and a pleasing appearance. In contrast, in the Girl's Own Book of Health and Beauty, Gordon Stables, a former Royal Navy surgeon who wrote the medical advice column for the popular British girls' magazine, the Girl's Own Paper, explains that unhealthy girls could be neither beautiful nor happy: Brightness of eyes, clearness of complexion, and happiness of expression, belong only to the possessor of health. The guide book is typical of representations of girls in fiction and advice of the period in its correlation of health with beauty and happiness. The Girl's Own Book of Health and Beauty implicitly argues against any form of external cosmetics by glorifying the relationship between inner health and pleasing external features.",
keywords = "girlhood, emotion, children's literature, Beauty",
author = "Michelle Smith",
doi = "10.4324/9781315266961-5",
series = "Children{\textquoteright}s Literature and Culture",
editor = "Kristine Moruzi and Smith, {Michelle J.} and Elizabeth Bullen",
booktitle = "Affect, Emotion, and Children{\textquoteright}s Literature",
Smith, M 2018, 'She cannot smile the smile that wells up from the heart': beauty, health, and emotion in Six to Sixteen and The Secret Garden. in K Moruzi, MJ Smith & E Bullen (eds), Affect, Emotion, and Children's Literature: Representation and Socialisation in Texts for Children and Young Adults. 1st edn, Children's Literature and Culture, Routledge, New York NY USA, pp. 66-78. https://doi.org/10.4324/9781315266961-5
'She cannot smile the smile that wells up from the heart' : beauty, health, and emotion in Six to Sixteen and The Secret Garden. / Smith, Michelle.
Affect, Emotion, and Children's Literature: Representation and Socialisation in Texts for Children and Young Adults. ed. / Kristine Moruzi; Michelle J. Smith; Elizabeth Bullen. 1st. ed. New York NY USA : Routledge, 2018. p. 66-78 (Children's Literature and Culture).
T1 - 'She cannot smile the smile that wells up from the heart'
T2 - beauty, health, and emotion in Six to Sixteen and The Secret Garden
AU - Smith, Michelle
N2 - Beauty ideals for girls were intimately connected with the concept of health in late nineteenth-century print culture. The healthy girl would necessarily have a cheerful character and a pleasing appearance. In contrast, in the Girl's Own Book of Health and Beauty, Gordon Stables, a former Royal Navy surgeon who wrote the medical advice column for the popular British girls' magazine, the Girl's Own Paper, explains that unhealthy girls could be neither beautiful nor happy: Brightness of eyes, clearness of complexion, and happiness of expression, belong only to the possessor of health. The guide book is typical of representations of girls in fiction and advice of the period in its correlation of health with beauty and happiness. The Girl's Own Book of Health and Beauty implicitly argues against any form of external cosmetics by glorifying the relationship between inner health and pleasing external features.
AB - Beauty ideals for girls were intimately connected with the concept of health in late nineteenth-century print culture. The healthy girl would necessarily have a cheerful character and a pleasing appearance. In contrast, in the Girl's Own Book of Health and Beauty, Gordon Stables, a former Royal Navy surgeon who wrote the medical advice column for the popular British girls' magazine, the Girl's Own Paper, explains that unhealthy girls could be neither beautiful nor happy: Brightness of eyes, clearness of complexion, and happiness of expression, belong only to the possessor of health. The guide book is typical of representations of girls in fiction and advice of the period in its correlation of health with beauty and happiness. The Girl's Own Book of Health and Beauty implicitly argues against any form of external cosmetics by glorifying the relationship between inner health and pleasing external features.
KW - girlhood
KW - emotion
KW - children's literature
KW - Beauty
U2 - 10.4324/9781315266961-5
DO - 10.4324/9781315266961-5
T3 - Children's Literature and Culture
BT - Affect, Emotion, and Children's Literature
A2 - Moruzi, Kristine
A2 - Smith, Michelle J.
A2 - Bullen, Elizabeth
PB - Routledge
CY - New York NY USA
Smith M. 'She cannot smile the smile that wells up from the heart': beauty, health, and emotion in Six to Sixteen and The Secret Garden. In Moruzi K, Smith MJ, Bullen E, editors, Affect, Emotion, and Children's Literature: Representation and Socialisation in Texts for Children and Young Adults. 1st ed. New York NY USA: Routledge. 2018. p. 66-78. (Children's Literature and Culture). https://doi.org/10.4324/9781315266961-5


text:
How do you simplify fractions step by step?
How to Reduce Fractions
Write down the factors for the numerator and the denominator.
Determine the largest factor that is common between the two.
Divide the numerator and denominator by the greatest common factor.
Write down the reduced fraction.
What are the three types of sources?
In general, there are three types of resources or sources of information: primary, secondary, and tertiary. It is important to understand these types and to know what type is appropriate for your coursework prior to searching for information.
What is Craap currency test?
Currency refers to when the information was posted or published. It is also important to look at the entire website's timeliness. If it has remained dormant for some time, it may be a warning.
How do you do a Craap analysis?
Apply the CRAAP Test
Currency: the timeliness of the information.
Relevance: the importance of the information for your needs.
Authority: the source of the information.
Accuracy: the reliability, truthfulness, and correctness of the content, and.
Purpose: the reason the information exists.
How do you write a source analysis essay?
ANALYZE THE SOURCE/QUOTE: EXPLAIN ITS' MEANING… BRING IN EXACT WORDS and how it. reflects that perspective.
Topic sentence: This sentence should introduce the reason/argument is general way. REFER BACK TO THE SOURCE. Explain the reason/argument: fully explain the "WHY"
How do you solve expressions with variables?
A linear algebraic equation is nice and simple, containing only constants and variables to the first degree (no exponents or fancy stuff). To solve it, simply use multiplication, division, addition, and subtraction when necessary to isolate the variable and solve for "x". Here's how you do it: 4x + 16 = 25 -3x =
What are the steps to evaluate an expression?
Here are the steps for evaluating an expression:
Replace each letter in the expression with the assigned value. First, replace each letter in the expression with the value that has been assigned to it.
Perform the operations in the expression using the correct order of operations.
How do you simplify expressions with fractions?
Step 1: Factor both the numerator and denominator of the fraction. Step 2: Reduce the fraction. Step 3: Rewrite any remaining expressions in the numerator and denominator. Step 1: Factor both the numerator and denominator of the fraction.
What does the P in Craap mean?
for Purpose
How can you evaluate information quality?
Once you have found information that matches the topic and requirements of your research, you should analyze or evaluate these information sources. Evaluating information encourages you to think critically about the reliability, validity, accuracy, authority, timeliness, point of view or bias of information sources.
How do you simplify and evaluate expressions?
To evaluate an expression, we substitute the given number for the variable in the expression and then simplify the expression using the order of operations. in the expression, and then simplify.
What is a source analysis?
What is 'source analysis'? Analysis is the ability to demonstrate an understanding of the elements that contributed to the creation of a historical source. It answers the question: 'Why does this source exist in its current form?'
What are the five components of the Craap test?
The test provides a list of questions to ask yourself when deciding whether or not a source is reliable and credible enough to use in your academic research paper. CRAAP stands for Currency, Relevance, Authority, Accuracy, and Purpose.
How do you evaluate source?
As you examine each source, it is important to evaluate each source to determine the quality of the information provided within it. Common evaluation criteria include: purpose and intended audience, authority and credibility, accuracy and reliability, currency and timeliness, and objectivity or bias.
Previous: What is MLA style in documenting sources?
Next: What rights do we have in a democracy?


text:
Unequal distribution of fame and honours
Nature:
Some talented people are rewarded immediately, others late in life, still others after death, and many whose deeds merit it may never be recognized at all. Chance is a factor, as well as corruption. The greatest inequality is the denial of recognition because of nationality, race, beliefs, sex, youth, age or physical handicap.
Incidence:
Among astronomical, biological, psychological and other scientific discoverers, women have been insufficiently recognized, a recent example having occurred when despite contributions by both sexes, only men received recognition in DNA research. Americans, to take another instance, dominate world media and entertainment; their actors and actresses are glorified, sometimes well beyond their merits, but there is no Oscar for an Egyptian, Indian, African, or Latin-American local performer, for example. Many national systems of honours, such as in the UK, neglect singular voluntary work, while political bureaucrats and money-makers receive OBEs and MBEs. In the arts, commercialism prevails, and intrinsic merit is overlooked in favour of what sells. Writers of outstanding quality are suppressed or censored by political regimes and religious orders. Recognition, when it comes, comes too late to support those who have been isolated and obscure.
Only about one-tenth of the Nobel Prizes awarded since 1980 have gone to people from the South, with 86 percent of the winners being from the industrialized countries of North America, Europe and Japan. More than nine out of ten have been men.
Human inequality
Infrequent honour singing
Elitist public honour systems
Infrequent achievement of honours
Related Problems:
Inequality of opportunity
Stifled emerging leadership
Honouring special citizen contribution
Reducing inequality of distribution of fame and honours
Preserving inequality of distribution of fame and honours
Societal Problems → Imbalances


text:
Mitologia greca
 Filemone – marito di Bauci
 Filemone – figlio di Priamo

Onomastica
Filemone – nome proprio di persona italiano maschile

Persone
 Filemone – personaggio a cui Paolo di Tarso indirizza la lettera a Filemone
 Filemone di Siracusa – commediografo greco antico
 Filemone di Siracusa il Giovane – commediografo greco antico, figlio del precedente

redpajama_set_name: RedPajamaWikipedia


text:
Estheria bohemani är en tvåvingeart som först beskrevs av Camillo Rondani 1862.  Estheria bohemani ingår i släktet Estheria och familjen parasitflugor. Arten är reproducerande i Sverige. Inga underarter finns listade i Catalogue of Life.

Källor

Parasitflugor
bohemani


This image gallery named as Bros For Life Bodysuit T Shirt Set My 1st Years might be ideal solution for your decoration. As the author has insert this image into Enlivening Hooded Towels post section, would ease you to find the perfect match of you decor desire.
bros for life bodysuit t shirt set my 1st years is great to have in a towel. It has open shelves to save things needed and also to produce acceptable ornaments for a towel. It provides beauty, simplicity and usefulness. Do you possess it in your towel? It might be reached out of metal, wood, steel, and etc.. It typically is made up of two shelves. If you don't possess this and therefore are believing to acquire one for your towel, here are the thoughts below.
Other Classification of Vanities Cabinets. The opposite of classification of vanities cabinets are filling using all the modern day towel dressing table, conventional towel closets, along with contemporary towel vanities. It is my hope that this write-up will grant you the hint to locate the suitable of the vanities cabinet based on what you need. So, let us begin to have an appearance to find your bros for life bodysuit t shirt set my 1st years!
Tiny bronze chandelier is a type of chandelier which always shows in the older castle and mansion at Europe. They are so lots of sort of bronze such as Castlewood walnut silver finish 3- lighting chandelier, extravagant selection of headboard, Kathy Ireland ramas de luces bronze headboard, Crystorama calypso bronze perdant chandelier, plus a lot more.
Decorating the towel is likely to soon be quite hard issue particularly should folks have the towel with space. It is already hard for stuffing every important element in the tiny room of their towel so they actually do not want to get troubled using the decoration at the distance that's limited. In fact, bros for life bodysuit t shirt set my 1st years could be as straightforward as choosing the towel counter itself. People must spend the towel counter tops that comes with convenient design for the towel decoration motif. Next, people are able to create the equipment organization which could also serve as show for boosting the look of the towel. There is nothing wrong for including the decorative accent like vase or flower inside the vase in order to add freshness from the towel.
Because it's state that operational is equally vital for successful little towel design and style. Small distance may easily develop in to clutter and because of this, that you have to be certain there are only functional layout elements that you just place around the towel. By way of example, you can use glass jars for keeping cotton balls and swabs in shelves that are floating. Minimize your counter space by storing not showing into personal items. For adding pleasing and calm feeling, plan your shade palette into towel style and design. The neutral shade could be the most suitable for you. Utilize along with textures and pattern in neutral tones to make depth in bros for life bodysuit t shirt set my 1st years.


text:
Home RECENT LEGISLATION Private Housing (Tenancies) (Scotland) Act 2016
Private Housing (Tenancies) (Scotland) Act 2016
The BLA - admin
The Private Housing (Tenancies) (Scotland) Act 2016 has introduced important changes which Scottish landlords and tenants ought to familiarise themselves with. The new tenancy under Private Housing (Tenancies) (Scotland) Act 2016 will be known as a private residential tenancy ("PRT"). This new Act is expected to come into force in late 2017.
Under the Private Housing (Tenancies) (Scotland) Act 2016 the main points to note are:-
(1) Tenancy Terms Future regulations will set out statutory terms of a PRT which all landlords must include in the tenancy they wish to grant.
(2) All landlords are required to provide the tenant with a written tenancy which must contain information which may be set out under secondary legislation.
(3) The First-tier Tribunal will have the power to draw up terms if no lease is provided or if it is unlawful.
(4) If a landlord fails to provide information (one item of information) as required under the Act the First-tier Tribunal can sanction the landlord to pay the tenant up to the equivalent to 3 months rent. Landlord will have to pay up to 6 months' rent if there is a failure to provide both a lease and at least one other required item of information.
(5) You can only review the rent once every 12 months
(6) Should a landlord wish to review the rent then you must give the tenant 3 months advance notice of the review
(7) Within 21 days of receiving the notice the tenant can refer the rent-increase notice to the rent officer who will set the open market rent
(8) The landlord or tenant may appeal the rent officer's decision to the First-tier Tribunal which may set the rent
(9) The new PRT can only be ended in accordance with the Act.
(10) Lawfully granted sub-tenancies will have the same protection as the mid-landlord's tenancy
(11) Where ownership of a property let under a PRT is transferred the landlord's interest under the tenancy transfers with it Termination by the Tenant
(12) The tenant can bring the PRT to an end by providing the landlord with 28 days' written notice after the expiry of the initial term
(13)This notice period cannot be extended at the outset of the agreement but can be altered by agreement after the PRT has begun Termination by the Landlord
(14) The landlord can issue the tenant with a notice to leave at any point after the tenancy has commenced but only if one of the grounds specified in schedule 3 is met.
(15) If the tenant does not leave the landlord can apply to the First-tier Tribunal to issue an eviction order
(16) The First-tier Tribunal can issue an eviction notice if it finds that one of the eviction grounds in schedule 3 applies
(17) If the tenant has occupied the let property for less than 6 months the notice period is 28 days
(18) If the eviction is due to the tenant's breach of the lease or behaviour, the notice period is 28 days
(19) If the tenant has occupied the property for over 6 months and the eviction is not due to the tenant's breach of the lease or behaviour, the notice period is 84 days
(20) The landlord must notify the local authority that he is seeking to apply for an eviction notice from the First-tier Tribunal
(21) If the tenant does not leave the property after being issued an eviction notice, the case can then proceed to the Sheriff Court Wrongful Termination
(22) Where a PRT has been brought to an end by an eviction order from the First-tier Tribunal and it is then found that the Tribunal was misled into issuing the order, the Tribunal can issue a wrongful-termination order
(23) Where the PRT was brought to an end without an eviction order (tenant left on notice to leave) an application can be made to the Tribunal for a wrongful-termination order if it believed the tenant was misled into ceasing occupation
(24) A wrongful-termination order is an order requiring the landlord to pay the tenant an amount not exceeding six months' rent
(25) When the Tribunal issues a wrongful-termination order it must notify the local authority where the landlord is registered and that Order will then be raised in a landlord's re-registration process Death of the Tenant
(26) A PRT is not terminated on the death of a sole tenant if the PRT has not been inherited previously and there is a qualifying successor
(27) A qualifying successor is a partner, direct family member or carer and succession rights apply in that order
(28) The successor must have been living in the property as their principal home for at least 12 months before the lawful tenant died
(29) The landlord must be been given written notice that the person was living there as their principal home and would qualify as a successor should the tenant die.
Landlords will find that it is going to be more difficult to obtain vacant possession as the "no fault" ground for termination, which is commonly used at present to ensure that a short assured tenancy comes to an end on the due date, will disappear with the introduction of the new PRT
This will be of relevance to estates and farms with large or small portfolios of let properties
Note:- there is no ground for repossession if a cottage is required for an employee; this may make it difficult in rural areas where a new employee, perhaps for a diversified business, requires a accommodation.
properties that are situated in a Rent Pressure Zone rent increases will be limited to an inflation-linked formula (CPI +1%).
More In RECENT LEGISLATION
Breaking News: Repeal of Section 21 of the Housing Act 1988
Repeal of Section 21 After the first news concerning the section 21 evictions being abolis…
New Section 21 Notice comes into force 1st of June 2019
New Form of Section 21 Notice The Section 21 Notice is being amended to incorporate the c…
Cardigan Property Ltd V Monty Shooltz
Caridon Property Ltd v Monty Shooltz. Central London County Court. 2 February 2018 (See ju…
Tenants can sue landlords for Disrepair under new law from next month
34 year old Act Updated A new law will allow people in rented housing the ability to sue l…
Homes (Fitness for Human Habitation) Bill 2017-19 (3rd Reading house of Lords)
The purpose of the Bill Karen Buck's Homes (Fitness for Human Habitation) Bill 2017-19 is …
Government announces Deposits to be capped at maximum five weeks rent
The Ministry of Housing, Communities & Local Government has issued the following artic…
Deposit Prescribed Information Signed by Agents or Companies
Ali v Manaquel Company Limited, County Court at Central London (HHJ Hand QC), 15th April 2…
Old tenancies will have to comply with new section 21 rules from 1st October 2018
New section 21 rules 1st October 2018 Under the "Deregulation act 2015" hereinafter referr…
1st of October deadline for HMO's inching closer, are you ready?
Landlords and letting agents are you ready? Landlords & letting agents are reminded th…
Load More In RECENT LEGISLATION


text:
ABFI's Stephen Lynam goes to Retail Ireland
Former Senior Executive with the Alcohol Beverage Federation of Ireland Stephen Lynam has been appointed Director of Retail Ireland, the national representative body for the entire retail sector.
Stephen is also a former Policy Officer in the Office of the Leader of Fine Gael in Leinster House. He holds a Masters in Journalism from DCU and a Bachelors Degree in English Literature and Sociology from Trinity College.
Alliance calls for immediate establishment of Garda...
US imposes tariffs on French & German spirits
Introducing The Busker
John Quinn elected Drinks Ireland|Irish Whiskey...
Britvic reviewing Counterpoint "low...


text:
Blu-ray Review: Ninja III – The Domination
By BAADASSSSS! | June 11th, 2013 at 5:30 pm
Ninja III: The Domination
Starring Sho Kosugi, Lucinda Dickey, and Jordan Bennett
Ninjas. Remember those guys? We all wanted to be them when we were kids. They were big in the '80s. Every discount store you went into had some cheap plastic ninja toys that your mom would buy you because she had to use that money originally earmarked for your Atari 2600 to buy your little sister corrective orthopedic shoes. Almost every action movie heavy had a few ninjas – or even an army of them – at their disposal, and disposed they easily were in the final battle royale. For a few years during the rule of Ronald Reagan – yes, the actor – ninjas were even bigger than Jesus. Some of us even figured Christ himself could have been a ninja. He did some pretty ninja stuff in that Bible, you know. Ninjas ruled all. Film production companies from Hong Kong to Halifax were churning out their own ultra-violent chop socky epics at bargain prices for the waning grindhouses and drive-ins of the world and the thriving home video market.
Remember Cannon Films? The blowhard indie movie studio that specialized in cheapjack action flicks and endless movies about interchangeable dance crazes (thank heavens they didn't survive long enough to make Macarena: The Motion Picture) really loved ninjas. In fact, they banked their entire financial longevity on ninja movies. If they had made the Harry Potter movies somehow ninjas would have been worked into the narrative. Infamous studio heads Menahem Golan and Yoram Globus were the undisputed kings of low-rent cinematic trash that went better with pizza and brown ale than wine and pita crisps. Before Cannon's theatrical output consisted mostly of flag-waving Chuck Norris adventures and inner city revenge yarns, the studio released movies with ninjas or at least the word "ninja" in the title once a year on average. They have even their very own ninja franchise, unsurprisingly titled American Ninja.
Topics: Blu-ray, Blu-ray Review, Movies, Reviews, Sequels
Tags: Cannon Films, James Hong, James R. Silke, Lucinda Dickey, Ninja III: The Domination, Sam Firstenberg, Scream Factory, Shô Kosugi, Shout! Factory
Blu-ray Review: 'Ninja Assassin'
By The Movie God | @ | April 3rd, 2010 at 8:57 pm
DVD | Blu-ray
Written by Matthew Sand, J. Michael Straczynski
Starring Rain, Naomie Harris, Shô Kosugi, Ben Miles, Anna Sawai
When Ninja Assassin first made its presence known to us, it sounded like it could be one of the more entertaining flicks on its way to our eyes. Sometimes the production process is a long and trying one, however, and when the movie's release drew near and every single commercial break had a spot advertising it, I found myself personally losing interest at an alarming rate. The movie had gone from a fun and exciting prospect to a title that had seemingly over-done it before it had even hit theaters.
This of course wasn't the best of set-ups for someone like myself entering into a review of the movie, but it's been multiple months now since the theatrical run, allowing the persistent advertisement efforts to wear off enough for me to jump in.
Ninja Assassin tells the story of a secret society of ninjas who inherit orphaned children and turn them into the deadliest killers the world has ever seen, paid 100 pounds of gold (or its equivalent over time) to remove people who need removing. One of these boys is Raizo (Rain), one of the most promising students that their "Father" Ozunu (Shô Kosugi) has ever seen. As time goes on, Raizo realizes that the methods used to discipline the students is a little too extreme. These views are confirmed when it comes to a fellow-student named Kiriko (Anna Sawai), whom he cares deeply for, is punished. Raizo eventually turns his back on everything he's ever known and leaves this family of ninjas — something that they do not take too kindly to.
Topics: Blu-ray, DVD Reviews, DVDs, Reviews
Tags: Anna Sawai, Ben Miles, Blu-ray, J. Michael Straczynski, James McTeigue, Matthew Sand, Naomie Harris, Ninja Assassin, Rain, Shô Kosugi


text:
More Studies Link Dolutegravir to Weight Gain
The effect is greater for women, and it could have a detrimental effect on pregnancy outcomes at the population level.
August 20, 2020 • By Liz Highleyman
A growing body of evidence continues to show that people who use the integrase inhibitor dolutegravir are more likely to gain weight after starting treatment, according to reports presented last month at the International AIDS Conference (AIDS 2020:Virtual).
Weight gain after starting antiretroviral treatment has become a concern in recent years. People with advanced immune suppression and opportunistic illnesses often gain weight as they return to health after starting treatment, and some people with HIV develop lipohypertrophy, a specific type of weight gain that often involves accumulation of internal abdominal fat. But the weight gain that occurs among people who start treatment with modern antiretrovirals before they sustain serious immune system damage appears to be a different phenomenon.
Although weight gain can occur after starting any class of antiretroviral drug, it has most frequently been reported among those taking potent integrase inhibitors, including dolutegravir (Tivicay, also in the Triumeq, Juluca and Dovato coformulations), and tenofovir alafenamide (TAF), the newer version of the drug in Descovy and several other combination pills.
Weight Gain and Hyperglycemia
At AIDS 2020, Julie Ake, MD, MSc, of the U.S. Military HIV Research Program, presented findings from a study of weight gain and hyperglycemia (high blood glucose) during the transition to dolutegravir in Africa.
Dolutegravir is one of the most effective antiretrovirals, and U.S. and World Health Organization guidelines recommend it for first-line treatment. The U.S. President's Emergency Plan for AIDS Relief (PEPFAR) has adopted dolutegravir, tenofovir disoproxil fumarate (TDF, the older version of the drug) and lamivudine as the preferred regimen for its funded global programs.
The African Cohort Study (AFRICOS) enrolled nearly 2,000 HIV-positive participants between January 2013 and November 2019 at 12 PEPFAR-supported clinics in Kenya, Nigeria, Tanzania and Uganda.
Of these, 742 started treatment with dolutegravir/TDF/lamivudine, while 1,212 either started another regimen or had not yet started treatment. Although women and men were about equally represented in the study, use of dolutegravir was less common among women due to concerns about neural tube birth defects in children born to mothers taking the drug around the time of conception; these fears were allayed after further research.
Body mass index (BMI) was assessed every six months, and blood glucose levels were measured once a year. Overweight was defined as a BMI of 25 to 29, while obesity was defined as a BMI of 30 or above. Those with overweight, obesity or hyperglycemia at enrollment were excluded from the analysis.
People who used dolutegravir/TDF/lamivudine were 85% more likely to develop overweight or obesity than those taking other antiretroviral regimens after adjusting for sex, age, study site and the presence of depression. In contrast, those who had not yet started treatment were 55% less likely to develop overweight or obesity than those on non-dolutegravir regimens.
Compared with people on non-dolutegravir regimens, those taking dolutegravir/TDF/lamivudine were 27% more likely to develop hyperglycemia, while those not yet on treatment were 78% less likely. However, the difference between those taking dolutegravir/TDF/lamivudine and non-dolutegravir regimens did not reach statistical significance after adjusting for sex, age, study site and BMI.
The researchers concluded that antiretroviral therapy in general was associated with both weight gain and hyperglycemia. While dolutegravir was clearly associated with an increased risk for a high BMI, they noted that if there is an additional effect of dolutegravir on hyperglycemia, it is likely to be small.
Other studies presented at the conference also saw a link between dolutegravir and weight gain.
Simiso Sokhela, MBChB, of the University of the Witwatersrand in Johannesburg, reported the latest findings from the ADVANCE study, a large randomized trial that compared first-line treatment using dolutegravir/TAF/emtricitabine, dolutegravir/TDF/lamivudine or efavirenz/TDF/emtricitabine (the drugs in Atripla). The study enrolled more than 1,000 participants in South Africa. Almost all were Black, about 60% were women and the average age was 32.
As previously reported, treatment with the dolutegravir-based and efavirenz-based regimens was similarly effective at 48 weeks, and TDF and TAF were equally well tolerated, although people on TAF saw smaller changes in bone density and kidney function. But people starting dolutegravir experienced greater weight gain, and this was especially pronounced when it was combined with TAF.
These results held up at 96 weeks, Sokhela reported. At that point, the average weight gain among men in the study was 5.2 kilograms (about 12 pounds) in the dolutegravir/TAF/emtricitabine group, 3.6 kg (about 8 pounds) in the dolutegravir/TDF/lamivudine group and just 1.4 kg (about 3 pounds) in the efavirenz/TDF/emtricitabine group. Among women, the average gain was 8.2 kg (about 18 pounds), 4.6 kg (about 10 pounds) and 3.2 kg (about 7 pounds), respectively.
Weight continued to rise in a smaller subset of people followed through 144 weeks. At that point, the average gain among men reached 7.2 kg (about 16 pounds) in the dolutegravir/TAF/emtricitabine group, 5.5 kg (about 12 pounds) in the dolutegravir/TDF/lamivudine group and 2.6 kg (about 6 pounds) in the efavirenz/TDF/emtricitabine group. Among women, the average 144-week gain was 12.3 kg (about 27 pounds), 7.4 kg (about 16 pounds) and 5.5 kg (about 12 pounds), respectively.
Looking at body composition, the researchers found that the weight gain consisted largely of fat rather than lean muscle mass and was primarily distributed in the torso and limbs. Fat gain was significantly greater among women compared with men. What's more, people taking the dolutegravir-based regimens were more likely to develop metabolic syndrome, a cluster of cardiovascular risk factors that include abdominal fat, high blood pressure, and abnormal blood glucose and blood fat levels.
Another research group performed a systematic review of adverse pregnancy outcomes related to obesity in an effort to estimate the impact of antiretroviral treatment. Based on the ADVANCE results, they calculated that for every 1,000 pregnant women, 140 of those treated with dolutegravir/TAF/emtricitabine and 80 of those treated with dolutegravir/TDF/emtricitabine for 96 weeks would develop obesity.
Using these figures, they estimated that there could be an additional 77 adverse birth outcomes linked to dolutegravir/TAF/emtricitabine and 41 such outcomes linked to dolutegravir/TDF/emtricitabine. In the dolutegravir/TAF/emtricitabine group, these included an additional 19 Cesarean deliveries, 11 more cases of gestational hypertension, seven cases of gestational diabetes, 20 infants large for their gestational age (an effect of maternal diabetes), 10 more cases of preeclampsia and three additional preterm births.
Finally, another study analyzed more than 600 African adolescents (ages 10 to 19) who switched to a dolutegravir-based regimen, mostly taken with TDF and lamivudine. This study also saw an increasing likelihood of weight gain over time, with the odds of overweight or obesity rising by about 1% for every additional day on dolutegravir.
Taken together, these studies confirm prior research linking dolutegravir and weight gain, especially among women. Treatment-associated weight gain is still poorly understood—experts do not yet know what causes it or how best to manage it—but this is an active area of research, as overweight and obesity raise the risk of cardiovascular disease, diabetes and other health problems.
Click here to see all POZ coverage of AIDS 2020:Virtual.
Click here to learn more about weight gain among people with HIV.
#AIDS 2020
#antiretrovirals
#dolutegravir
#overweight
#tenofovir alafenamide
#tenofovir disoproxil fumarate
#weight gain
POZ at Home: HIV and Weight Gain [VIDEO]
U.S. Government Updates Pregnancy and Perinatal HIV Guidelines
2020 Top HIV Treatment Stories


The Wikipedia page on Jeanne Beijerman-Walraven gives precious little information about this composer. She was a Dutch national born in Indonesia. Another page says she studied piano with her mother and then returned to Holland. Her teacher there was Frits Koeberg. Her early compositions were in the romantic tradition, but then she turned expressionist coming under the influence of Schoenberg's music. I could only find one work on youtube dating from 1910. This website in Dutch has a longer entry about her under the name Jeanne Walraven translated badly to English here.


Magdalena is a Reviewing Editor for The Plant Cell and a Professor at UMass Amherst. Here she describes her research interests in a series of videos published by iBiology.
Part 1: Understanding cell shape: Big insights from little plants: Polarized cell growth in plants depends on the assembly and disassembly of actin filaments.
Part 2: Using reverse genetics to dissect the formin gene family: Formins promote nucleation and elongation of actin filaments and are required for polarized cell growth.
Part 3: Myosin and actin steer plant cell division: Plants have only two classes of myosins; myosin VIII and XI. Myosin VIII is required for proper location of the cell division plate.
Magdalena Bezanilla's lab is interested in understanding what determines cell shape at the molecular level. In Part 1 of her talk, Bezanilla explains why the moss, Physcomitrella patens, is an excellent model system to address this question. P. patens grows quickly and entire plants can be vegetatively regenerated from single cells. The genome is sequenced and its cells undergo efficient homologous recombination- the only plant known to do this! In the filamentous tissue that establishes the plant, cells at the tips grow in a polarized manner as flexible cell wall material is incorporated and then pushed out by turgor pressure. To study the role of actin in determining cell shape, Bezanilla's lab used a live-cell actin binding probe to label actin and imaged cell growth with fluorescence microscopy. They showed that polarized growth depended on the rapid disassembly and assembly of actin filaments; processes regulated by actin binding proteins.