text:
"""
Infer feasible routing plans according to user preferences
"""

from .datamodel import VERTEX_VALIDATION_CHECKER
from .orm_graphmodel import SwitchType, StreetJunction, Mode, Session, Vertex
from geoalchemy2.functions import ST_AsGeoJSON as st_asgeojson
import logging
import json

logger = logging.getLogger(__name__)

INTERNAL_SRID = 4326
# Read modes and switch_types from database instead of hard coding it here
MODES = {
    str(m_name): m_id
    for m_name, m_id in Session.query(Mode.mode_name, Mode.mode_id)
}
SWITCH_TYPES = {
    str(t_name): t_id
    for t_name, t_id in Session.query(SwitchType.type_name, SwitchType.type_id)
}

class RoutingPlan(object):
    """
    A plan of routing including transportation tools to use
    during the trip
    """
    mode_list = []
    switch_type_list = []
    switch_condition_list = []
    switch_constraint_list = []
    target_constraint = None
    public_transit_set = []
    cost_factor = ''
    description = ''
    source = {}
    target = {}

    def __init__(self,
                 desc,
                 source,
                 target,
                 modes,
                 cost,
                 switch_types=None,
                 switch_conditions=None,
                 switch_constraints=None,
                 target_constraint=None,
                 public_transits=None):
        self.description = desc
        self.source = source
        self.target = target
        self.mode_list = modes
        self.cost_factor = cost
        self.switch_type_list = [] if switch_types is None else switch_types
        self.switch_condition_list = [] if switch_conditions is None else switch_conditions
        self.switch_constraint_list = [] if switch_constraints is None else switch_constraints
        self.target_constraint = target_constraint
        self.public_transit_set = [] if public_transits is None else public_transits

    @property
    def is_multimodal(self):
        return True if (len(self.mode_list) >= 2) or \
            (MODES['public_transportation'] in self.mode_list) else False

    @property
    def has_public_transit(self):
        return True if MODES['public_transportation'] in self.mode_list \
                    else False

class RoutingPlanInferer(object):
    """
    Infer the feasible routing plans according to routing options
    """

    def __init__(self):
        self.options = {}

    def load_routing_options_from_file(self, options_file_path):
        with open(options_file_path) as options_file:
            self.options = json.load(options_file)

    def load_routing_options_from_string(self, options_json_string):
        self.options = json.loads(options_json_string)

    def load_routing_options(self, options_dict):
        self.options = options_dict

    def _reproject(self, old_x, old_y, old_srid, new_srid):
        # TODO: transform coordinate from given srid to 4326 in lon and lat
        return old_x, old_y

    def _geodecode(self, address):
        return 0, 0

    def _get_lon_lat_position(self, position_info):
        if position_info['type'] == 'coordinate':
            lon, lat = self._reproject(
                position_info['value']['x'], position_info['value']['y'],
                position_info['value']['srid'], INTERNAL_SRID)
        elif position_info['type'] == 'address':
            # TODO: Do geo-decoding to get the geo-coordinate
            lon, lat = self._geodecode(position_info['value'])
        return {"lon": lon, "lat": lat}

    def _find_nearest_point(self, location):
        point = 'POINT(' + str(location['lon']) + ' ' + \
            str(location['lat']) + ')'
        nearest_neighbor = Session.query(StreetJunction).order_by(
            StreetJunction.geom.distance_box(point)).first()
        raw_point_id = nearest_neighbor.osm_id
        point_geom = json.loads(Session.scalar(st_asgeojson(
            nearest_neighbor.geom)))
        logger.debug("found nearest neighbor, osm_id is " + str(raw_point_id))
        return {'point_id': raw_point_id, 'geometry': point_geom}

    def _find_candidate_vertices(self, raw_point_id):
        candidate_vertices = Session.query(Vertex).filter(
            Vertex.raw_point_id == raw_point_id).all()
        v_id_list = [str(v.vertex_id) for v in candidate_vertices]
        logger.debug("candidate vertices: " + ','.join(v_id_list))
        return {v.mode_id: v.vertex_id for v in candidate_vertices}

    def _get_cost_factor(self, objective):
        if objective == 'shortest': return 'length'
        elif objective == 'fastest': return 'speed'
        return 'speed'

    def _find_valid_source_target_pairs(self,
                                        sources,
                                        targets,
                                        modes,
                                        public_transit_modes=[]):
        s_mode = modes[0]
        t_mode = modes[-1]
        st_pairs = []
        if (s_mode != MODES['public_transportation']) and \
                (t_mode != MODES['public_transportation']):
            source = sources[s_mode] if s_mode in sources else None
            target = targets[t_mode] if t_mode in targets else None
            if (not source is None) and (not target is None):
                st_pairs.append({"source": source, "target": target})
        elif (s_mode == MODES['public_transportation']) and \
                (t_mode != MODES['public_transportation']):
            target = targets[t_mode] if t_mode in targets else None
            source_list = [sources[m] \
                           for m in public_transit_modes + [MODES['foot']] \
                           if m in sources]
            if (not target is None) and (len(source_list) > 0):
                st_pairs = map(lambda s: {"source": s, "target": target},
                                    source_list)
        elif (s_mode != MODES['public_transportation']) and \
                (t_mode == MODES['public_transportation']):
            source = sources[s_mode] if s_mode in sources else None
            target_list = [targets[m] \
                           for m in public_transit_modes + [MODES['foot']] \
                           if m in targets]
            if (not source is None) and (len(target_list) > 0):
                st_pairs = map(lambda t: {"source": source, "target": t},
                                    target_list)
        elif (s_mode == MODES['public_transportation']) and \
                (t_mode == MODES['public_transportation']):
            source_list = [sources[m] \
                           for m in public_transit_modes + [MODES['foot']] \
                           if m in sources]
            target_list = [targets[m] \
                           for m in public_transit_modes + [MODES['foot']] \
                           if m in targets]
            if (len(source_list) > 0) and (len(target_list) > 0):
                st_pairs = [{"source": s, "target": t} for s in source_list \
                                 for t in target_list]
        return st_pairs

    def generate_routing_plan(self):
        if self.options == {}:
            raise Exception('Empty routing options!')
        source_lon_lat = self._get_lon_lat_position(self.options['source'])
        target_lon_lat = self._get_lon_lat_position(self.options['target'])
        nearest_source = self._find_nearest_point(source_lon_lat)
        nearest_target = self._find_nearest_point(target_lon_lat)
        candidate_sources = self._find_candidate_vertices(nearest_source[
            'point_id'])
        candidate_targets = self._find_candidate_vertices(nearest_target[
            'point_id'])
        cost_factor = self._get_cost_factor(self.options['objective'])
        plans = []
        if self.options['objective'] == 'fastest':
            if len(self.options['available_public_modes']) == 0:
                if not self.options['has_private_car']:
                    # only can walk, mono-modal routing
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets, [MODES['foot']])
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        plans.append(RoutingPlan('Walking', routing_src,
                                                 routing_tgt, [MODES['foot']],
                                                 cost_factor))
                    return plans
                if self.options['has_private_car'] and \
                        (not self.options['need_parking']):
                    # somebody else will be the driver
                    # the car can be parked temporarily anywhere
                    # There are 3 possible mode combinations in this case:
                    # car; foot; car-foot with geo_connection as Switch Point
                    # 1st: car only
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets,
                        [MODES['private_car']])
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        car_plan = RoutingPlan(
                            'Take a car', routing_src, routing_tgt,
                            [MODES['private_car']], cost_factor)
                        if 'driving_distance_limit' in self.options:
                            car_plan.target_constraint = VERTEX_VALIDATION_CHECKER(
                                lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                        plans.append(car_plan)
                    # 2nd: foot only
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets, [MODES['foot']])
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        plans.append(RoutingPlan('Walking', routing_src,
                                                 routing_tgt, [MODES['foot']],
                                                 cost_factor))
                    # 3rd: car-foot with geo_connection as Switch Point
                    type_id = SWITCH_TYPES['geo_connection']
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets,
                        [MODES['private_car'], MODES['foot']])
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        car_foot_plan = RoutingPlan(
                            'By car first, then walking without parking',
                            routing_src, routing_tgt,
                            [MODES['private_car'], MODES['foot']], cost_factor,
                            [type_id], ["type_id=" + str(type_id) +
                                        " AND is_available=true"])
                        # FIXME: It is unreasonable to use driving distance limit
                        # as the extream driving distance because the driver can
                        # not drive any more after the passenger leaves. So it
                        # must be convenient to leave some gas for the driver.
                        # remaining_gas_factor = 0.75
                        if 'driving_distance_limit' in self.options:
                            car_foot_plan.switch_constraint_list = [
                                VERTEX_VALIDATION_CHECKER(
                                    lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                            ]
                        else:
                            car_foot_plan.switch_constraint_list = [None]
                        plans.append(car_foot_plan)
                    return plans

                if self.options['has_private_car'] and self.options[
                        'need_parking']:
                    # the user may be the driver
                    # and he/she surely need a parking lot for the car
                    # There are also 2 possible mode combinations in this case:
                    # foot; car-foot with parking as Switch Point
                    # 1st: foot only
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets, [MODES['foot']])
                    logger.debug("Found valid source target pairs: %s",
                                 st_pairs)
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        plans.append(RoutingPlan('Walking', routing_src,
                                                 routing_tgt, [MODES['foot']],
                                                 cost_factor))
                    # 2nd: car-foot with parking lots as Switch Point
                    type_id = SWITCH_TYPES['car_parking']
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets,
                        [MODES['private_car'], MODES['foot']])
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        car_foot_plan = RoutingPlan(
                            'Driving, parking and walking', routing_src,
                            routing_tgt, [MODES['private_car'], MODES['foot']],
                            cost_factor, [type_id], ["type_id=" + str(
                                type_id) + " AND is_available=true"])
                        remaining_gas_factor = 0.5
                        if 'driving_distance_limit' in self.options:
                            car_foot_plan.switch_constraint_list = [
                                VERTEX_VALIDATION_CHECKER(
                                    lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 * remaining_gas_factor else -1)
                            ]
                        else:
                            car_foot_plan.switch_constraint_list = [None]
                        plans.append(car_foot_plan)
                    return plans
            else:
                # can use public transportation system
                if not self.options['has_private_car']:
                    # the user can walk or take public transportation
                    # 2 possible mode combinations:
                    # 1. foot;
                    # 2. PT
                    #
                    # 1: foot only
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets, [MODES['foot']])
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        plans.append(RoutingPlan('Walking', routing_src,
                                                 routing_tgt, [MODES['foot']],
                                                 cost_factor))
                    # 2: public transportation
                    public_modes = [MODES[m] for m in \
                                    self.options['available_public_modes']]
                    st_pairs = self._find_valid_source_target_pairs(
                        candidate_sources, candidate_targets,
                        [MODES['public_transportation']], public_modes)
                    for st in st_pairs:
                        routing_src = {
                            'type': 'Feature',
                            'geometry': nearest_source['geometry'],
                            'properties': {'id': st['source']}
                        }
                        routing_tgt = {
                            'type': 'Feature',
                            'geometry': nearest_target['geometry'],
                            'properties': {'id': st['target']}
                        }
                        public_plan = RoutingPlan(
                            'Walking and taking public transit', routing_src,
                            routing_tgt, [MODES['public_transportation']],
                            cost_factor)
                        public_plan.public_transit_set = public_modes
                        plans.append(public_plan)
                    return plans

            if self.options['has_private_car'] and \
                    (not self.options['need_parking']):
                # somebody else will be the driver
                # the car can be parked temporarily anywhere
                # There are 5 possible mode combinations in this case:
                # 1. car;
                # 2. foot;
                # 3. car-foot with geo_connection as Switch Point;
                # 4. PT;
                # 5. car-PT with geo_connection as Switch Point;
                # 6. car-PT with kiss+R as Switch Point;
                #
                # 1: car only
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['private_car']])
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    car_plan = RoutingPlan('Take a car', routing_src,
                                           routing_tgt, [MODES['private_car']],
                                           cost_factor)
                    if 'driving_distance_limit' in self.options:
                        car_plan.target_constraint = VERTEX_VALIDATION_CHECKER(
                            lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                    plans.append(car_plan)
                # 2: foot only
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets, [MODES['foot']])
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    plans.append(RoutingPlan('Walking', routing_src,
                                             routing_tgt, [MODES['foot']],
                                             cost_factor))
                # 3: car-foot with geo_connection as Switch Point
                type_id = SWITCH_TYPES['geo_connection']
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['private_car'], MODES['foot']])
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    car_foot_plan = RoutingPlan(
                        'By car first, then walking without parking',
                        routing_src, routing_tgt,
                        [MODES['private_car'], MODES['foot']], cost_factor,
                        [type_id],
                        ["type_id=" + str(type_id) + " AND is_available=true"])
                    if 'driving_distance_limit' in self.options:
                        car_foot_plan.switch_constraint_list = [
                            VERTEX_VALIDATION_CHECKER(
                                lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                        ]
                    else:
                        car_foot_plan.switch_constraint_list = [None]
                    plans.append(car_foot_plan)
                # 4: public transportation
                public_modes = [MODES[m] for m in \
                                self.options['available_public_modes']]
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['public_transportation']], public_modes)
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    public_plan = RoutingPlan(
                        'Walking and taking public transit', routing_src,
                        routing_tgt, [MODES['public_transportation']],
                        cost_factor)
                    public_plan.public_transit_set = public_modes
                    plans.append(public_plan)
                # 5: car-PT with geo_connection as Switch Point
                type_id = SWITCH_TYPES['geo_connection']
                public_modes = [MODES[m] for m in \
                                self.options['available_public_modes']]
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['private_car'], MODES['public_transportation']],
                    public_modes)
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    car_public_plan1 = RoutingPlan(
                        'Driving and taking public transit', routing_src,
                        routing_tgt,
                        [MODES['private_car'], MODES['public_transportation']],
                        cost_factor, [type_id],
                        ["type_id=" + str(type_id) + " AND is_available=true"])
                    car_public_plan1.public_transit_set = public_modes
                    if 'driving_distance_limit' in self.options:
                        car_public_plan1.switch_constraint_list = [
                            VERTEX_VALIDATION_CHECKER(
                                lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                        ]
                    else:
                        car_public_plan1.switch_constraint_list = [None]
                    plans.append(car_public_plan1)
                # 6: car-PT with kiss+R as Switch Point
                type_id = SWITCH_TYPES['kiss_and_ride']
                public_modes = [MODES[m] for m in \
                                self.options['available_public_modes']]
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['private_car'], MODES['public_transportation']],
                    public_modes)
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    car_public_plan2 = RoutingPlan(
                        'Driving and taking public transit via Kiss+R',
                        routing_src, routing_tgt,
                        [MODES['private_car'], MODES['public_transportation']],
                        cost_factor, [type_id],
                        ["type_id=" + str(type_id) + " AND is_available=true"])
                    car_public_plan2.public_transit_set = public_modes
                    if 'driving_distance_limit' in self.options:
                        car_public_plan2.switch_constraint_list = [
                            VERTEX_VALIDATION_CHECKER(
                                lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                        ]
                    else:
                        car_public_plan2.switch_constraint_list = [None]
                    plans.append(car_public_plan2)
                return plans

            if self.options['has_private_car'] and self.options[
                    'need_parking']:
                # the user may be the driver
                # and he/she surely need a parking lot for the car
                # There are 5 possible mode combinations in this case:
                # 1. foot;
                # 2. car-foot with parking as Switch Point;
                # 3. PT;
                # 4. car-PT with parking as Switch Points;
                # 5. car-PT with P+R as Switch Points;
                #
                # 1: foot only
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets, [MODES['foot']])
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    plans.append(RoutingPlan('Walking', routing_src,
                                             routing_tgt, [MODES['foot']],
                                             cost_factor))
                # 2: car-foot with parking lots as Switch Point
                type_id = SWITCH_TYPES['car_parking']
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['private_car'], MODES['foot']])
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    car_foot_plan = RoutingPlan(
                        'Driving, parking and walking', routing_src,
                        routing_tgt, [MODES['private_car'], MODES['foot']],
                        cost_factor, [type_id],
                        ["type_id=" + str(type_id) + " AND is_available=true"])
                    remaining_gas_factor = 0.5
                    if 'driving_distance_limit' in self.options:
                        car_foot_plan.switch_constraint_list = [
                            VERTEX_VALIDATION_CHECKER(
                                lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 * remaining_gas_factor else -1)
                        ]
                    else:
                        car_foot_plan.switch_constraint_list = [None]
                    plans.append(car_foot_plan)
                # 3: public transportation
                public_modes = [MODES[m] for m in \
                                self.options['available_public_modes']]
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['public_transportation']], public_modes)
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    public_plan = RoutingPlan(
                        'Walking and taking public transit', routing_src,
                        routing_tgt, [MODES['public_transportation']],
                        cost_factor)
                    public_plan.public_transit_set = public_modes
                    plans.append(public_plan)
                # 4: car-PT with parking as Switch Point
                type_id = SWITCH_TYPES['car_parking']
                public_modes = [MODES[m] for m in \
                                self.options['available_public_modes']]
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['private_car'], MODES['public_transportation']],
                    public_modes)
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    car_public_plan1 = RoutingPlan(
                        'Driving, parking and taking public transit',
                        routing_src, routing_tgt,
                        [MODES['private_car'], MODES['public_transportation']],
                        cost_factor, [type_id],
                        ["type_id=" + str(type_id) + " AND is_available=true"])
                    car_public_plan1.public_transit_set = public_modes
                    remaining_gas_factor = 0.5
                    if 'driving_distance_limit' in self.options:
                        car_public_plan1.switch_constraint_list = [
                            VERTEX_VALIDATION_CHECKER(
                                lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 * remaining_gas_factor else -1)
                        ]
                    else:
                        car_public_plan1.switch_constraint_list = [None]
                    plans.append(car_public_plan1)
                # 5: car-PT with P+R as Switch Point
                type_id = SWITCH_TYPES['park_and_ride']
                public_modes = [MODES[m] for m in \
                                self.options['available_public_modes']]
                st_pairs = self._find_valid_source_target_pairs(
                    candidate_sources, candidate_targets,
                    [MODES['private_car'], MODES['public_transportation']],
                    public_modes)
                for st in st_pairs:
                    routing_src = {
                        'type': 'Feature',
                        'geometry': nearest_source['geometry'],
                        'properties': {'id': st['source']}
                    }
                    routing_tgt = {
                        'type': 'Feature',
                        'geometry': nearest_target['geometry'],
                        'properties': {'id': st['target']}
                    }
                    car_public_plan1 = RoutingPlan(
                        'Driving, parking and taking public transit',
                        routing_src, routing_tgt,
                        [MODES['private_car'], MODES['public_transportation']],
                        cost_factor, [type_id],
                        ["type_id=" + str(type_id) + " AND is_available=true"])
                    car_public_plan1.public_transit_set = public_modes
                    if 'driving_distance_limit' in self.options:
                        car_public_plan1.switch_constraint_list = [
                            VERTEX_VALIDATION_CHECKER(
                                lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                        ]
                    else:
                        car_public_plan1.switch_constraint_list = [None]
                    plans.append(car_public_plan1)
                return plans

            elif self.options['objective'] == 'shortest':
                if not self.options['can_use_public']:
                    if not self.options['has_private_car']:
                        # no car, walk only
                        st_pairs = self._find_valid_source_target_pairs(
                            candidate_sources, candidate_targets,
                            [MODES['foot']])
                        for st in st_pairs:
                            routing_src = {
                                'type': 'Feature',
                                'geometry': nearest_source['geometry'],
                                'properties': {'id': st['source']}
                            }
                            routing_tgt = {
                                'type': 'Feature',
                                'geometry': nearest_target['geometry'],
                                'properties': {'id': st['target']}
                            }
                            plans.append(RoutingPlan(
                                'Walking', routing_src, routing_tgt, [MODES[
                                    'foot']], cost_factor))
                    else:
                        # car
                        st_pairs = self._find_valid_source_target_pairs(
                            candidate_sources, candidate_targets,
                            [MODES['private_car']])
                        for st in st_pairs:
                            routing_src = {
                                'type': 'Feature',
                                'geometry': nearest_source['geometry'],
                                'properties': {'id': st['source']}
                            }
                            routing_tgt = {
                                'type': 'Feature',
                                'geometry': nearest_target['geometry'],
                                'properties': {'id': st['target']}
                            }
                            car_plan = RoutingPlan(
                                'Take a car', routing_src, routing_tgt,
                                [MODES['private_car']], cost_factor)
                            if 'driving_distance_limit' in self.options:
                                car_plan.target_constraint = VERTEX_VALIDATION_CHECKER(
                                    lambda v: 0 if v[0].distance <= float(self.options['driving_distance_limit']) * 1000.0 else -1)
                            plans.append(car_plan)
                        # foot
                        st_pairs = self._find_valid_source_target_pairs(
                            candidate_sources, candidate_targets,
                            [MODES['foot']])
                        for st in st_pairs:
                            routing_src = {
                                'type': 'Feature',
                                'geometry': nearest_source['geometry'],
                                'properties': {'id': st['source']}
                            }
                            routing_tgt = {
                                'type': 'Feature',
                                'geometry': nearest_target['geometry'],
                                'properties': {'id': st['target']}
                            }
                            plans.append(RoutingPlan(
                                'Walking', routing_src, routing_tgt, [MODES[
                                    'foot']], cost_factor))
                        return plans
                else:
                    # TODO: finish this branch
                    return []


text:
Q: Xcode iOS Cocoa framework is failing to link C static library I'm trying to link multiple C static library (libssl and testClib) to an iOS framework (dynamic lib) project to use them inside the framework's code (no need to be exposed by the compiled framework).
All seems fine to me: the target is including all static libs under "Linked Frameworks and Libraries", the left Xcode panel show correctly the libs (referring to the right path) and the "Build Settings" tab have correct references to "Headers Search Paths" and "Library Search Paths".
Even checking the linker command seems correct:
Ld /Users/<omissis>/Debug-iphonesimulator/MyFmw.framework/MyFmw normal x86_64
cd /Volumes/<omissis>/MyFmw
export IPHONEOS_DEPLOYMENT_TARGET=8.0
export PATH="<omissis>"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -dynamiclib
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.0.sdk
-L/Users/<omissis>/Build/Products/Debug-iphonesimulator
-L/Volumes/programming/git/<project_folder>/libs -F/Users/<omissis>/Products/Debug-iphonesimulator
-filelist /Users/<omissis> -exported_symbols_list <omissis> -install_name @rpath/<omissis> -Xlinker
-rpath -Xlinker @executable_path/Frameworks -Xlinker -rpath -Xlinker @loader_path/Frameworks
-mios-simulator-version-min=8.0 -dead_strip -Xlinker -object_path_lto -Xlinker /Users/<omissis>
-Xlinker -export_dynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc
-fobjc-link-runtime -lssl -ltestClib -lsqlite3 -single_module -compatibility_version 1 -current_version 1
-Xlinker -dependency_info -Xlinker /Users/<omissis> -o /Users/<omissis>

To be sure about the libraries content I've manually verified that the expected symbols were available for the target architecture.
The error I receive during framework linking phase is (an extract compiling for the Simulator):
 Undefined symbols for architecture x86_64:
 "_GenerateRandomData", referenced from:
  _CreateSt in Storage.o
 "_GetBytePtr", referenced from:
  _CreateSt in Storage.o
 "_GetLength", referenced from:
   _CreateSt in Storage.o
 ...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)

The same happens even changing target architecture.
Additional infos: I'm developing in ObjectiveC and using Xcode 9.0.

redpajama_set_name: RedPajamaStackExchange


On 15 January Norman Lamb, the Chair of parliament's Science and Technology Committee, sent Ryan Ding, President of Huawei's carrier business group, a letter entitled 'Security of the UK's communications infrastructure'. In it he noted the oversight board of the Huawei Cyber Security Evaluation Centre (HCSEC) had said in its latest report that it could only provide limited reassurance about the risk Huawei posed to the UK's critical networks.
Ding was given two weeks to respond and used all of it, pinging over his response on 29 January. That response has only just been published and you can read it in full here, but in case you've got too much other stuff on your plate, we've condensed it into words of one syllable for you.
It starts by praising the UK for its openness and notes Huawei has operated here for 18 years without any aggro. In that time it has invested loads of cash in the UK and would be happy to keep doing so, given half the chance. The main part of the letter addresses four questions posed by Lamb in his earlier correspondence, so here they are, accompanied by a summary of each response.
What reassurances can you give to demonstrate that your products and services pose no threat to UK national security?
We've been around for ages and nothing's gone wrong so far.
We do loads of work on cyber security.
The HCSEC Oversight Board still reckons that's the best way to keep an eye on us.
How do you respond to actions being taken over foreign involvement in communications networks by other nations, such as the UK's Five Eyes allies?
Coverage of this stuff has been overblown; Canada hasn't taken any action, New Zealand has only turned down one 5G proposal, only 5G is a problem for Huawei in Australia and even in the US legal restrictions only apply to federal funds. Furthermore banning us just creates a false sense of security because the supply chain is global.
How do you intend to respond to the HCSEC Oversight Board's latest annual report?
More references to points two and three of the answer to the first question followed by vows to double down on things like security and transparency. Ding infered it would help if policy makers would try to be a bit less uptight and give Huawei the benefit of the doubt every now and then.
To what extent could Huawei be compelled to assist Chinese national intelligence work using its UK-based hardware or software, or information gathered in the UK?
Huawei has never and will never do that stuff and if it did someone would notice and then it would be in serious trouble.
China's National Intelligence Law doesn't oblige companies to install security backdoors and Huawei has never been asked to do anything like that anyway. But even if that did happen, it would not be against Chinese law to refuse.
In closing the UK is really important to Huawei and we still plan to spend £3 billion there from 2018-2023 if you let us. Feel free to get in touch any time and even visit us in Shenzhen if you fancy it.
So, what to make of this exchange? It's good that our parliament is engaging with Huawei rather than just unilaterally acting against it and Huawei's response seems like a genuine attempt to reciprocate that gesture by answering the questions in a constructive and comprehensive manner. Having said that the attempts to downplay the restrictions already imposed on it, especially in Australia and the US, were bit of a reach.
There's nothing especially new in the response, however, as it's largely a restatement of the defence Huawei has been using for years. Huawei is essentially a proxy for deep, visceral distrust towards the Chinese state at this stage, which means there's a limited amount it can do to conclusively prove its innocence. Its fate in western markets probably hinges on a significant thawing of diplomatic relations between the US and China and there's little sign of that happening anytime soon.
I would not have expected any other response from Huawei. Lest we not forget, China is a one party state, where alternative parties are not allowed. This is also one of the most regulated countries of the world in terms of how they control their people in terms of censorship and other means. If there was some form of conflict, Huawei or some other Chinese company would toe the party line. The impact on a nation if Huawei were to allow some form of retaliation could be immense – from either shutting down the network or eavesdropping on calls/data and gathering intelligence.
Ignore Australia's actions, they don't count because Australia just does what Washington tells it to do.


After the death of Ish-bosheth, the men of Israel come to David seeking to anoint him king over the rest of the tribes as well as Judah. David also moves his capital to Jerusalem. According to the IVP Bible Background Commentary1, Jerusalem had a number of things going for it that made it a prime location for a capital city.
It is located at a crossroads for two major roads.
east-west road between Jericho and the coastal highway.
north-south road between Beersheba and Beth Shan.
It is also located along the border between Judah and Benjamin.
Mount Zion has valleys on the east and west sides making it defensible.
It makes sense then for David to move from Hebron to Jerusalem for strategic purposes. This would also be popular with the people of Benjamin it was still occupied by Jebusites even though it was on the border of the tribes of Judah and Benjamin. Of course there are also other more spiritual reasons for this move as well.
Melchizedek was the king of Salem whom Abraham greeted and gave a tenth of the spoils from the victory over the armies that took Lot and other captive. Also the Israelites could not completely drive out the Jebusites who inhabited the city so the Jebusites had lived among the people of Benjamin since the time of the its capture under Joshua. David captured the city and set about fortifying the city and building himself a palace.
Jerusalem from this point on plays an even more significant role in the lives of the Jewish people. Solomon built the first temple there and there are numerous psalms written about the city and its inhabitants.
Psalm 122 is probably the most significant psalm about Jerusalem. In it the reader is urged to pray for the peace of Jerusalem, not for the sake of the inhabitants but "for the sake of the house of the LORD our God". While the temple has been destroyed and its services are no longer in effect because of the death and resurrection of Jesus, this command is still worth following, for we know that the city is usually in turmoil to some degree because of the various people groups living there which are opposed to each other.
Lord God, we pray for the peace of Jerusalem that its inhabitants might seek peaceful resolution to disputes. Most importantly we pray that all its inhabitants might come to know the true Messiah/Christ, Your Son Jesus, because He is the true source of peace that can truly satisfy. May Your will be done on earth as it is in heaven, in Jesus' name. Amen.
1 – Walton, John H. et al. IVP Bible Background Commentary. InterVarsity Press; e-Sword, 2000.
A devotional for 2 Samuel 5.


text:
From the wonderful to the weird, spanning every budget and every age, we have put together the best dang gift guide you're going to read this holiday season. HO HO HO, y'all!
From the wonderful to the weird, spanning every budget and every age, we have put together the best dang gift guide you're going to read this holiday season. We challenge you to make it through all of the recs in our six shopping categories without caving and buying half of them for yourself.
*VILLAINOUS LAUGH*
Seriously though, we have some great suggestions. So, if you're stumped on gift ideas, you definitely came to the right place.
Old Dogs, New Tricks
Gifts for Analog People in a Digital World
REMARKABLE TABLET - $599. reMarkable combines the realistic look and feel of paper with the convenience of a tablet device. It's an elegant, simple solution for reading, writing and sketching without any of the distractions of notifications, web browsing or apps.
IPHONE & ANDROID FILM SCANNER - $59. Rejoice, all you diehard #filmisnotdead folks! Photojojo has created a cheap, clever way to skip the flatbed and scan 35mm film directly to your smartphone. At this price point, we think it's totally cool to order two: one for that hard-to-buy-for person on your shopping list AND one for yourself.
RETRO TURNTABLE & SPEAKER SYSTEM - $145. Music streaming via Bluetooth? Check. 3-speed turntable? Check. Vinyl to USB encoding? Check. Double cassette deck? Check. Whether listening, recording or digitizing, this is the ultimate all-in-one stereo system for music junkies who want to keep one foot in the analog world and one in digital.
VIEW-MASTER VR STARTER PACK - $18. View-Master found an irresistible way to tap into the multi-generational nostalgia kick that's made fanny packs, cassettes and Stranger Things so wildly popular. Kids of all ages (read: especially old millennials) will love Mattel's immersive, updated take on a classic childhood toy.
POLAROID SNAP TOUCH - $192. Polaroid's colorful, easy-to-use camera pairs the analog fun of instant photo prints with the convenient sharability (that's a word, right?) of modern digital photography. With a 3.5-inch LCD touchscreen, a 13mp CMOS sensor and 1080p HD video recording, this baby packs a lot of functionality into a surprisingly reasonable price point.
Head Starts for Future Smarts
Gifts for Curious Kiddos
CUBETTO CODING TOY - $225. You want your kids to appreciate life outside of screens, but you also want them to become tech-savvy thinkers. So, what's a 21st century parent to do? Enter Cubetto, a friendly wooden robot that teaches logic and programming fundamentals with nary a screen in sight.
STEM CLUB TOY SUBSCRIPTION - $20/MONTH. Available for ages 3-4, 5-7 and 8-13, Amazon's new STEM Club program exposes kids to concepts related to science, technology, engineering and math via monthly shipments of educational toys, each handpicked by experts.
NATIONAL GEOGRAPHIC MEGA FOSSIL MINE - $27. Jurassic Park IRL! (But, y'know, without the constant threat of evisceration by raptors…) With this NatGeo set, kids use real paleontological tools to uncover real remnants of dinosaurs, sharks, brachiopods and more. So, if your little ones are fascinated by fossils, this is the kit to their hearts.
KLUTZ LEGO CHAIN REACTIONS KIT - $15. A NAPPA Silver Award-winner, this next-level LEGO kit helps kids design and build 10 different moving machines, which can be combined with one another, as well as any basic LEGO bricks, to start chain reactions and create more complex machines.
TOYBOX 3D PRINTER - $399. Billing itself as "the last toy you ever need to buy," Toybox is one of the only 3D printers specifically designed for kids. The compact, desktop printer expands imaginations and STEM skills by empowering children to design and print their own toys.
Gamers Gone Wild
Gifts for Dice-Rollers and Remote-Controllers
BOB ROSS: THE ART OF CHILL - $25. "Earn 'chill points' by painting landscape features like Happy Little Trees and Almighty Mountains using colors and brushes from your hand of cards. Finish one of Bob Ross's masterpieces before he does to win 'chill' status." If you've ever wondered what it might be like to combine Clue with one of those group painting classes, here ya go!
SUPER NES CLASSIC EDITION - $80. Like slap bracelets, dial-up and Lisa Frank, Super NES was a fundamental part of growing up in the 90's. Eager to cash in on the nostalgia wave, Nintendo recently rebooted the much-beloved home console in miniature form, preloaded with 20 classic games, including Legend of Zelda, Super Mario World and Donkey Kong Country.
JIM HENSON'S LABYRINTH BOARD GAME - $50. This season, give the gift of dark 80's puppet fantasy opera to your favorite Bowie fan/tabletop gamer. Featuring beautifully crafted character pieces and two different versions of gameplay, the Labyrinth board game pays fitting tribute to Jim Henson's masterpiece and doesn't take 13 hours to play!
CAMPY CREATURES - $25. "A ghoulish game of bluffing, deduction, and set collection," Campy Creatures tasks each mad scientist (player) with the goal of capturing mortals (humans?) for experiments. Sounds simple, sure, but things get slippery when you start dealing with point-sucking traps and artifact-enhanced opponents. Ooooooooooooh...
OCULUS RIFT - $399. Born from a Kickstarter campaign five years ago, Rift has been making waves in the VR world, even capturing the imagination of social media juggernaut, Facebook. From mesmerizing gameplay to revolutionary entertainment experiences, Oculus' flagship headset is leading the pack, while maintaining a realistic price point.
Big Impacts, Small Price Tags
Cool Gifts Under $50
6-PACK BIKE SADDLEBAG - $34. As Memphis becomes more bike-friendly with each passing day, an ever-growing number of folks are adapting a two-wheeled approach to navigating the city. Naturally, all of these cyclists need a convenient way to transport their sodas (beer). So, here's a gift for your freewheeling friends.
AMAZON FIRE TV STICK WITH ALEXA - $40. Being budget-conscious shouldn't stop you from giving your friends and family a fun tech gift. Beyond streaming your favorite content anytime, anywhere, the newest gen Amazon Fire TV Stick also integrates with Alexa. So, with the press of a button, your voice can summon music or order pizza. ("Thanks, robot stick!" your mom will exclaim.)
PENGUIN HARDCOVER CLASSICS - $18-25. Go ahead, judge these books by their covers -- they'll stand up to the scrutiny. Penguin's breathtaking hardcover classics feature intricate patterns stamped on linen cases, playfully colored endpapers and ribbon markers, each volume illustrated by acclaimed designer, Coralie Bickford-Smith. America, let's make reading great again. (Please?)
RECHARGEABLE HAND WARMER - $33. Winter is the worst, right? It's dark all the time, everything is cold, and you basically just want to hibernate like a bear until life thaws out. This handy little gadget can't make the season pass any faster, but it can make the experience more BEAR-able (hyuk) by providing the holy trifecta of winter needs: warmth, light and power for the devices that keep you sane.
ACOUSTIC ELECTRIC KALIMBA - $42. The mbira (aka: kalimba or thumb piano) is an African instrument that's been produced in some form or fashion for a few thousand years now. It's played by flicking or thumping the metal tines attached to its wooden board, which produces dreamy, melodic tones similar to those of a marimba. The instrument's simple interface makes it inviting to folks of all ages and all musical abilities, and this version's electronic component makes it perfect for 21st century dabblers.
Gifts for RF Crew Members (HINT HINT)
STAR WARS ART: RALPH MCQUARRIE - $152.
"Ralph McQuarrie is awesome, and he had a lot of impact on visual inspiration throughout my life." - Ryan (Front End Developer)
RUSH: THE UNOFFICIAL ILLUSTRATED HISTORY - $20.
"Who doesn't love Rush?!" - Reuben (CEO, frequent wearer of Rush shirts)
GRANSFORS BRUK SCANDINAVIAN FOREST AXE - $194.
"Gransfor Bruk is one of the leaders in individually forged axes. It's Swedish, cold-forged steel, one of the hardest tempered steels in the world." - Josh (Senior Front End Developer)
STAR WARS PLANETARY GLASSWARE SET - $50.
"I just really, really want this." - Alli (Account Manager)
STAY AT HOME SCARFACE: COLORING & ACTIVITY BOOK FOR GANGSTER PARENTS - $10.
"I know it's technically for parents, but I have cats. That's close enough, right?" - Katie (Senior Social Media Strategist)
LEGO ARCHITECTURE LONDON SKYLINE - $39.
"It's London! It's LEGO! I love it!" - Whitney (Senior Designer)
THE X-FILES AS VERTIGO - $86.
"I want to believe in Saul Bass." - Lindsey (Copywriter & Creative Strategist)
Gifts for Nic Cage Lovers
CAGES THROUGH THE AGES LIP GLOSS COLLECTION - $2-9. Nothing says Nicolas Cage quite like a historically sardonic set of lip glosses in an attractive array of colors, right? ...... Anyway! Here are a few highlights from the collection:
Nic Cage Churning Butter One Crisp Thanksgiving Morn (nude, slightly sheer)
Nic Cage Resigned to a Loveless Marriage for the Good of the Realm (vermilion with coral and rose undertones)
Nic Cage Nibbling Petit Fours in a Posh Victorian Tearoom (opaque dusty rose with pearl finish)
NICOLAS CAGE "PAPER" DOLL MAGNET - $12. This doll has all the best accessories, including a John Travolta face! If you've ever wanted to treat an unhinged celebrity scene-chewer like a plaything (and who hasn't?), then this is right up your alley. Bonus points for serving a functional purpose because #magnet.
SNAKE EYES: A NICOLAS CAGE ACTIVITY BOOK - $10. Amazon user Andrew Jenkins says it best: "Lots of different activities, although a lot of them don't actually have anything for you to do." Sounds like a winner!
NICOLAS CAGE FACE T-SHIRT "WITH HIP HOP SLEEVES" - $17. After carefully reviewing this listing several times, with the aid of several drinks, we never could figure out what the heck "hip hop sleeves" are. Regardless, who could turn down the chance to wear an unsettling amount of sublimated Nic Cage grimiles? (That's grimace + smile.) We sure couldn't!
NICOLAS CAGE NAIL DECALS - $6. This fashionable set of decals will help you celebrate Mr. Cage's epic oeuvre, while keeping him just at your fingertips. MEOW, y'all. (Other sexy animal sounds as well!)
NICOLAS CAGE NOUVEAU SHAMANIC SOAP - $6. "With an eclectic scent blend of ancient Egyptian artifacts, rare dinosaur bones, volcanic ash, a haunted mansion in New Orleans, the faded dreams of becoming Superman, and a hint of peach." Ignore the fact this soap looks more like Harry Dean Stanton than Nicolas Cage, and just bask in its mystical properties!
Happy holidays, everyone. Share the turkey with your sister.
Example for New Memphis
Example 2 for NM
email facebook linkedin twitter googleplus pinterest

redpajama_set_name: RedPajamaCommonCrawl


Whether it's a birthday, anniversary, christening or personal celebration, The Cairndale Hotel offers a range of private function suites in which to host your function. With a number of different sized function suites, The Cairndale Hotel caters for all party sizes.
Experienced team of chefs are on hand to deliver a superb sit down dinner or buffet for your event.
Tailor your party menu by using the Banqueting Menu Selector and Banqueting Wine List and create a perfect meal or buffet for your guests.
First class customer service throughout the organisation and running of your function.
To make a function enquiry simply enquire online or contact the hotel direcly on 01387 254111.
For smaller private functions and events The Cairndale Hotel in Dumfries also offers a choice of alternative options. Choose to hold a private dinner in one of the private function rooms or perhaps for a less formal option the High Tea menu offers a delicious meal at the hotel which can be arranged for your group.
For private functions such as funeral teas, the private function rooms offer a personal space for you and the hotel is at hand to arrange all details for you.
Enquire about a private function online or call the hotel directly on 01387 254111.


Whew … thought we were actually going to go through a whole week without something in 77018.
@Claire: Ha! I don't stand still for long while walking dogs considering I'm circa 1961 – Mel Reyna might aim a bulldozer at me and plant a "Building Soon" sign in my twitching corpse.
I thought 77018 was getting a holiday respite, but there just aren't enough Tuscan Craftsman Hill Country villas yet.


text:
MODERN MARINE ENGINEERS MANUAL VOLUME II
MODERN MARINE ENGINEERS MANUAL VOLUME II : Volume II
Everett C. Hunt , Associate Editors: James A. Harbach & Alan L. Rowen, Contributing Editors: Robert S. Behr, Davis Brown, R. D. Jacobs, Aaron R. Kramer, Thomas P. Mackey, James Mercanti, William B. Morgan, Keith Wilson, and Conrad C. Youngren
This manual, first published in 1943, has been indispensable to ship? engineers for generations. The third edition, revised and updated by a team of marine engineers/professors, follows in the venerable style of its predecessors. Text relating to obsolete equipment has been eliminated, information on systems that are still current has been updated, and new material has been added to reflect innovations in equipment and operative practices. Extensive coverage on the newest medium-speed diesel engine has been added to the text. Environmental concerns have been recognized with a section on engine exhaust emissions and information about new refrigerants and the maintenance of refrigeration systems. New equipment for trash handling, sewage processing, bilge water discharge, and incineration are discussed with reference to international regulations. Ship trial procedures and the new equipment used in trial data collection are presented in detail.
Size: 6" x 9" | Pages:904 | 624 illustrations, 46 b/w photos


You've heard of the Sharing Economy because of some well-known start-ups with giant valuations like ride-sharing service, Uber, and home-rental platform, AirBnB. The sharing economy is growing fast. But how are mid-market companies being affected by this trend?
The sharing economy is influencing the energy industry through the development of the smart grid especially distributed generation which relies on electricity-generating technology used by a customer or independent producer. For companies that manufacture or service these technologies, the growth potential is huge. This new distributed model makes it easier to share resources reducing the need for companies to buy expensive wholesale energy during peak demand periods. This cuts costs and boosts revenue for them. Retailers and consumer goods companies are also being affected by this trend thanks to rising demand for sharing services. Today's customers are willing to share a surprising number of things. The sharing economy reduces price sensitivity for high margin goods meaning retailers can raise prices on high quality products without seeing major sales losses.
The sharing economy can also help with retail space. Platforms like Storefront, which works with 80,000 brands, let retailers partner with other merchants to create pop-up shops inside of stores or sell their goods at existing locations. This provides new ways for brands to reach in-person customers while helping larger retailers earn extra revenue from unused space. Commercial real estate companies are used to seeing their holdings as hard assets instead of providing short-term accommodations, amenities and services. But access is the new ownership and companies are more flexible about where and how long they keep office space. Providing access to these spaces like WeWork does is a new priority. Firms can focus on sub-leasing and short-term configurable work spaces to reduce vacancy time and lower idle capacity. Since 50% of the U.S. workforce is expected to be freelance by 2020, there will be more demand for temporary work spaces. The sharing economy is one of the fastest growing business trends in the world. That means it's time to start paying attention to sharing.


aren't all forum games cheating the system?
That's different because the objective isn't to spam.
After this page is filled, I'm cutting this game short.
I AM ROCKETING UP POSTS AS YOU SPEAK.
It's one of the best games though!
In that case who are you guys voting for?
Subject: Re: Last Reply Wins!


text:
#import "NSObject-Protocol.h"

@protocol SBUIBannerView <NSObject>
- (id)bannerContext;
@end

redpajama_set_name: RedPajamaGithub


Pre-trip orientation: $1800.00 plus airfare.
Capstone: Can fulfill ENVS and BIOL capstone requirements.
Eligibility: All participants must have permission of the instructor to apply. Students interested in applying should provide a statement of interest, a letter of recommendation and meet with the program directors for an interview.
Fill out this form: Yes I am interested in going to Panama!


Lighter, stronger, and more durable.
Tipping the scales at a paltry 422 grams, the SRAM XX1 Eagle DUB SL Crankset is one of the lightest cranks available on the market, lending itself to professional racers and discerning cross-country riders shaving weight from their Eagle 12-speed drivetrain. You'll find it's approximately 43 grams lighter than previous XX1 Eagle Cranksets with its new spindle diameter and Carbon Tuned crank arms (80 grams less with DUB bottom bracket), which is a big deal when you're counting every last gram that goes on your cross-country race bike. Additionally, it retains the quiet, mud-shedding performance of the X-Sync 2 chainring, plus the ability to retain your chain without a guide. Please note, this particular version is made solely for 12 x 142-millimeter rear axle spacing.
Very well made, has a sticker on the arm and a plastic cover at the bottom of the cranks to protect it from rocks.