text:
"""Configuration for ACLs."""

# Copyright (C) 2015 Brad Cowie, Christopher Lorier and Joe Stringer.
# Copyright (C) 2015 Research and Education Advanced Network New Zealand Ltd.
# Copyright (C) 2015--2019 The Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import netaddr

from faucet import valve_of
from faucet import valve_acl
from faucet.valve_of import MATCH_FIELDS, OLD_MATCH_FIELDS
from faucet.conf import Conf, test_config_condition, InvalidConfigError
from faucet.valve_table import wildcard_table

class ACL(Conf):
    """Contains the state for an ACL, including the configuration.

ACL Config

ACLs are configured under the 'acls' configuration block. The acls block
contains a dictionary of individual acls each keyed by its name.

Each acl contains a list of rules, a packet will have the first matching rule
applied to it.

Each rule is a dictionary containing the single key 'rule' with the value the
matches and actions for the rule.

The matches are key/values based on the ryu RESTFul API.
The key 'actions' contains a dictionary with keys/values as follows:

 * allow (int): if 1 allow the packet to continue through the Faucet \
       pipeline, if 0 drop the packet.
 * force_port_vlan (int): if 1, do not verify the VLAN/port association \
       for this packet and override any VLAN ACL on the forced VLAN.
 * meter (str): meter to apply to the packet
 * output (dict): used to output a packet directly. details below.
 * cookie (int): set flow cookie to this value on this flow

The output action contains a dictionary with the following elements:

 * tunnel (dict): the tunnel formation, creates a tunnel from the applied port(s) \
       to the specified destination
 * port (int or string): the port to output the packet to
 * ports (list): a list of the ports (int or string) to output the packet to
 * set_fields (list): a list of fields to set with values
 * pop_vlans: (int): pop the packet vlan before outputting
 * vlan_vid: (int): push the vlan vid on the packet when outputting
 * vlan_vids: (list): push the list of vlans on the packet when outputting, with option eth_type
 * swap_vid (int): rewrite the vlan vid of the packet when outputting
 * failover (dict): Output with a failover port (experimental)
"""

    defaults = {
        'rules': None,
        'exact_match': False,
        'dot1x_assigned': False,
    }
    defaults_types = {
        'rules': list,
        'exact_match': bool,
        'dot1x_assigned': bool,
    }
    rule_types = {
        'cookie': int,
        'actions': dict,
        'description': str,
    }
    actions_types = {
        'meter': str,
        'mirror': (str, int),
        'output': (dict, list),
        'allow': int,
        'force_port_vlan': int,
    }
    output_actions_types = {
        'tunnel': dict,
        'port': (str, int),
        'ports': list,
        'failover': dict,
        'set_fields': list,
        'pop_vlans': int,
        'swap_vid': int,
        'vlan_vid': int,
        'vlan_vids': list,
    }
    tunnel_types = {
        'type': (str, None),
        'tunnel_id': (str, int, None),
        'dp': str,
        'port': (str, int),
    }

    mutable_attrs = frozenset(['tunnel_sources'])

    def __init__(self, _id, dp_id, conf):
        self.rules = []
        self.exact_match = None
        self.dot1x_assigned = None
        self.meter = False
        self.matches = {}
        self.set_fields = set()
        self._ports_resolved = False

        # Tunnel info maintains the tunnel output information for each tunnel rule
        self.tunnel_info = {}
        # Tunnel sources is a list of the sources in the network for this ACL
        self.tunnel_sources = []
        # Tunnel rules is the rules for each tunnel in the ACL for each source
        self.dyn_tunnel_rules = {}

        for match_fields in (MATCH_FIELDS, OLD_MATCH_FIELDS):
            self.rule_types.update({match: (str, int) for match in match_fields})
        conf = copy.deepcopy(conf)
        if isinstance(conf, dict):
            rules = conf.get('rules', [])
        elif isinstance(conf, list):
            rules = conf
            conf = {}
        else:
            raise InvalidConfigError(
                'ACL conf is an invalid type %s' % _id)
        conf['rules'] = []
        for rule in rules:
            normalized_rule = rule
            if isinstance(rule, dict):
                normalized_rule = rule.get('rule', rule)
                if normalized_rule is None:
                    normalized_rule = {k: v for k, v in rule.items() if v is not None}
            test_config_condition(not isinstance(normalized_rule, dict), (
                'ACL rule is %s not %s (%s)' % (type(normalized_rule), dict, rules)))
            conf['rules'].append(normalized_rule)
        super(ACL, self).__init__(_id, dp_id, conf)

    def finalize(self):
        self._ports_resolved = True
        super(ACL, self).finalize()

    def check_config(self):
        test_config_condition(
            not self.rules, 'no rules found for ACL %s' % self._id)
        for rule in self.rules:
            self._check_conf_types(rule, self.rule_types)
            for rule_field, rule_conf in rule.items():
                if rule_field == 'cookie':
                    test_config_condition(
                        rule_conf < 0 or rule_conf > 2**16,
                        'rule cookie value must be 0-2**16')
                elif rule_field == 'actions':
                    test_config_condition(
                        not rule_conf,
                        'Missing rule actions in ACL %s' % self._id)
                    self._check_conf_types(rule_conf, self.actions_types)
                    for action_name, action_conf in rule_conf.items():
                        if action_name == 'output':
                            if isinstance(action_conf, (list, tuple)):
                                # New ordered format
                                for subconf in action_conf:
                                    # Make sure only one specified action per list element
                                    test_config_condition(
                                        len(subconf) > 1,
                                        'ACL ordered output must have only one action per element')
                                    # Ensure correct action format
                                    self._check_conf_types(subconf, self.output_actions_types)
                            else:
                                # Old format
                                self._check_conf_types(
                                    action_conf, self.output_actions_types)

    def build(self, meters, vid, port_num):
        """Check that ACL can be built from config."""

        class NullRyuDatapath:
            """Placeholder Ryu Datapath."""
            ofproto = valve_of.ofp

        self.matches = {}
        self.set_fields = set()
        self.meter = False
        if self.rules:
            try:
                ofmsgs = valve_acl.build_acl_ofmsgs(
                    [self], wildcard_table,
                    [valve_of.goto_table(wildcard_table)],
                    [valve_of.goto_table(wildcard_table)],
                    2**16-1, meters, self.exact_match,
                    vlan_vid=vid, port_num=port_num)
            except (netaddr.core.AddrFormatError, KeyError, ValueError) as err:
                raise InvalidConfigError(err)
            test_config_condition(not ofmsgs, 'OF messages is empty')
            for ofmsg in ofmsgs:
                ofmsg.datapath = NullRyuDatapath()
                ofmsg.set_xid(0)
                try:
                    ofmsg.serialize()
                except (KeyError, ValueError) as err:
                    raise InvalidConfigError(err)
                except Exception as err:
                    print(ofmsg)
                    raise err
                if valve_of.is_flowmod(ofmsg):
                    apply_actions = []
                    for inst in ofmsg.instructions:
                        if valve_of.is_apply_actions(inst):
                            apply_actions.extend(inst.actions)
                        elif valve_of.is_meter(inst):
                            self.meter = True
                    for action in apply_actions:
                        if valve_of.is_set_field(action):
                            self.set_fields.add(action.key)
                    for match, value in ofmsg.match.items():
                        has_mask = isinstance(value, (tuple, list))
                        if has_mask or match not in self.matches:
                            self.matches[match] = has_mask
        return (self.matches, self.set_fields, self.meter)

    def get_meters(self):
        """Yield meters for each rule in ACL"""
        for rule in self.rules:
            if 'actions' not in rule or 'meter' not in rule['actions']:
                continue
            yield rule['actions']['meter']

    def get_mirror_destinations(self):
        """Yield mirror destinations for each rule in ACL"""
        for rule in self.rules:
            if 'actions' not in rule or 'mirror' not in rule['actions']:
                continue
            yield rule['actions']['mirror']

    def _resolve_ordered_output_ports(self, output_list, resolve_port_cb, resolve_tunnel_objects):
        """Resolve output actions in the ordered list format"""
        result = []
        for action in output_list:
            for key, value in action.items():
                if key == 'tunnel':
                    tunnel = value
                    # Fetch tunnel items from the tunnel output dict
                    test_config_condition(
                        'dp' not in tunnel,
                        'ACL (%s) tunnel DP not defined' % self._id)
                    tunnel_dp = tunnel['dp']
                    test_config_condition(
                        'port' not in tunnel,
                        'ACL (%s) tunnel port not defined' % self._id)
                    tunnel_port = tunnel['port']
                    tunnel_id = tunnel.get('tunnel_id', None)
                    tunnel_type = tunnel.get('type', 'vlan')
                    # Resolve the tunnel items
                    dst_dp, dst_port, tunnel_id = resolve_tunnel_objects(
                        tunnel_dp, tunnel_port, tunnel_id)
                    # Compile the tunnel into an easy-access dictionary
                    tunnel_dict = {
                        'dst_dp': dst_dp,
                        'dst_port': dst_port,
                        'tunnel_id': tunnel_id,
                        'type': tunnel_type
                    }
                    self.tunnel_info[tunnel_id] = tunnel_dict
                    result.append({key: tunnel_id})
                elif key == 'port':
                    port_name = value
                    port = resolve_port_cb(port_name)
                    test_config_condition(
                        not port,
                        'ACL (%s) output port undefined in DP: %s' % (self._id, self.dp_id))
                    result.append({key: port})
                elif key == 'ports':
                    resolved_ports = [
                        resolve_port_cb(p) for p in value]
                    test_config_condition(
                        None in resolved_ports,
                        'ACL (%s) output port(s) not defined in DP: %s' % (self._id, self.dp_id))
                    result.append({key: resolved_ports})
                elif key == 'failover':
                    failover = value
                    test_config_condition(not isinstance(failover, dict), (
                        'failover is not a dictionary'))
                    failover_dict = {}
                    for failover_name, failover_values in failover.items():
                        if failover_name == 'ports':
                            resolved_ports = [
                                resolve_port_cb(p) for p in failover_values]
                            test_config_condition(
                                None in resolved_ports,
                                'ACL (%s) failover port(s) not defined in DP: %s' % (
                                    self._id, self.dp_id))
                            failover_dict[failover_name] = resolved_ports
                        else:
                            failover_dict[failover_name] = failover_values
                    result.append({key: failover_dict})
                else:
                    result.append(action)
        return result

    def _resolve_output_ports(self, action_conf, resolve_port_cb, resolve_tunnel_objects):
        """Resolve the values for output actions in the ACL"""
        if isinstance(action_conf, (list, tuple)):
            return self._resolve_ordered_output_ports(
                action_conf, resolve_port_cb, resolve_tunnel_objects)
        result = {}
        test_config_condition(
            'vlan_vid' in action_conf and 'vlan_vids' in action_conf,
            'ACL %s has both vlan_vid and vlan_vids defined' % self._id)
        test_config_condition(
            'port' in action_conf and 'ports' in action_conf,
            'ACL %s has both port and ports defined' % self._id)
        for output_action, output_action_values in action_conf.items():
            if output_action == 'tunnel':
                tunnel = output_action_values
                # Fetch tunnel items from the tunnel output dict
                test_config_condition(
                    'dp' not in tunnel,
                    'ACL (%s) tunnel DP not defined' % self._id)
                tunnel_dp = tunnel['dp']
                test_config_condition(
                    'port' not in tunnel,
                    'ACL (%s) tunnel port not defined' % self._id)
                tunnel_port = tunnel['port']
                tunnel_id = tunnel.get('tunnel_id', None)
                tunnel_type = tunnel.get('type', 'vlan')
                # Resolve the tunnel items
                dst_dp, dst_port, tunnel_id = resolve_tunnel_objects(
                    tunnel_dp, tunnel_port, tunnel_id)
                # Compile the tunnel into an easy-access dictionary
                tunnel_dict = {
                    'dst_dp': dst_dp,
                    'dst_port': dst_port,
                    'tunnel_id': tunnel_id,
                    'type': tunnel_type
                }
                self.tunnel_info[tunnel_id] = tunnel_dict
                result[output_action] = tunnel_id
            elif output_action == 'port':
                port_name = output_action_values
                port = resolve_port_cb(port_name)
                test_config_condition(
                    not port,
                    ('ACL (%s) output port undefined in DP: %s'\
                    % (self._id, self.dp_id))
                    )
                result[output_action] = port
            elif output_action == 'ports':
                resolved_ports = [
                    resolve_port_cb(p) for p in output_action_values]
                test_config_condition(
                    None in resolved_ports,
                    ('ACL (%s) output port(s) not defined in DP: %s'\
                    % (self._id, self.dp_id))
                    )
                result[output_action] = resolved_ports
            elif output_action == 'failover':
                failover = output_action_values
                test_config_condition(not isinstance(failover, dict), (
                    'failover is not a dictionary'))
                result[output_action] = {}
                for failover_name, failover_values in failover.items():
                    if failover_name == 'ports':
                        resolved_ports = [
                            resolve_port_cb(p) for p in failover_values]
                        test_config_condition(
                            None in resolved_ports,
                            ('ACL (%s) failover port(s) not defined in DP: %s'\
                            % (self._id, self.dp_id))
                            )
                        result[output_action][failover_name] = resolved_ports
                    else:
                        result[output_action][failover_name] = failover_values
            else:
                result[output_action] = output_action_values
        return result

    def resolve_ports(self, resolve_port_cb, resolve_tunnel_objects):
        """Resolve the values for the actions of an ACL"""
        if self._ports_resolved:
            return
        for rule_conf in self.rules:
            if 'actions' in rule_conf:
                actions_conf = rule_conf['actions']
                resolved_actions = {}
                test_config_condition(not isinstance(actions_conf, dict), (
                    'actions value is not a dictionary'))
                for action_name, action_conf in actions_conf.items():
                    if action_name == 'mirror':
                        resolved_port = resolve_port_cb(action_conf)
                        test_config_condition(
                            resolved_port is None,
                            ('ACL (%s) mirror port is not defined in DP: %s'\
                            % (self._id, self.dp_id))
                            )
                        resolved_actions[action_name] = resolved_port
                    elif action_name == 'output':
                        resolved_action = self._resolve_output_ports(
                            action_conf, resolve_port_cb, resolve_tunnel_objects)
                        resolved_actions[action_name] = resolved_action
                    else:
                        resolved_actions[action_name] = action_conf
                rule_conf['actions'] = resolved_actions
        self._ports_resolved = True

    def get_num_tunnels(self):
        """Returns the number of tunnels specified in the ACL"""
        num_tunnels = 0
        for rule_conf in self.rules:
            if self.does_rule_contain_tunnel(rule_conf):
                output_conf = rule_conf['actions']['output']
                if isinstance(output_conf, list):
                    for action in output_conf:
                        for key in action:
                            if key == 'tunnel':
                                num_tunnels += 1
                else:
                    if 'tunnel' in output_conf:
                        num_tunnels += 1
        return num_tunnels

    def get_tunnel_rules(self, tunnel_id):
        """Return the list of rules that apply a specific tunnel ID"""
        rules = []
        for rule_conf in self.rules:
            if self.does_rule_contain_tunnel(rule_conf):
                output_conf = rule_conf['actions']['output']
                if isinstance(output_conf, (list, tuple)):
                    for action in output_conf:
                        for key, value in action.items():
                            if key == 'tunnel' and value == tunnel_id:
                                rules.append(rule_conf)
                                continue
                else:
                    if output_conf['tunnel'] == tunnel_id:
                        rules.append(rule_conf)
        return rules

    def does_rule_contain_tunnel(self, rule_conf):
        """Return true if the ACL rule contains a tunnel"""
        if 'actions' in rule_conf:
            if 'output' in rule_conf['actions']:
                output_conf = rule_conf['actions']['output']
                if isinstance(output_conf, (list, tuple)):
                    for action in output_conf:
                        for key in action:
                            if key == 'tunnel':
                                return True
                else:
                    if 'tunnel' in output_conf:
                        return True
        return False

    def is_tunnel_acl(self):
        """Return true if the ACL contains a tunnel"""
        if self.tunnel_info:
            return True
        for rule_conf in self.rules:
            if self.does_rule_contain_tunnel(rule_conf):
                return True
        return False

    def add_tunnel_source(self, dp, port):
        """Add a source dp/port pair for the tunnel ACL"""
        self.tunnel_sources += ({'dp': dp, 'port': port},)
        for _id in self.tunnel_info:
            self.dyn_tunnel_rules.setdefault(_id, [])
            self.dyn_tunnel_rules[_id].append([])

    def verify_tunnel_rules(self):
        """Make sure that matches & set fields are configured correctly to handle tunnels"""
        if 'in_port' not in self.matches:
            self.matches['in_port'] = False
        if 'vlan_vid' not in self.matches:
            self.matches['vlan_vid'] = True
        if 'vlan_vid' not in self.set_fields:
            self.set_fields.add('vlan_vid')

    def update_source_tunnel_rules(self, curr_dp, source_id, tunnel_id, out_port):
        """Update the tunnel rulelist for when the output port has changed"""
        src_dp = self.tunnel_sources[source_id]['dp']
        dst_dp = self.tunnel_info[tunnel_id]['dst_dp']
        prev_list = self.dyn_tunnel_rules[tunnel_id][source_id]
        new_list = []
        if curr_dp == src_dp and curr_dp != dst_dp:
            # SRC DP: in_port, actions=[push_vlan, output, pop_vlans]
            new_list.append({'vlan_vid': tunnel_id})
            new_list.append({'port': out_port})
            new_list.append({'pop_vlans': 1})
        elif curr_dp == dst_dp and curr_dp != src_dp:
            # DST DP: in_port, vlan_vid, actions=[pop_vlan, output]
            new_list.append({'pop_vlans': 1})
            new_list.append({'port': out_port})
        else:
            # SINGLE DP: in_port, actions=[out_port]
            # TRANSIT DP: in_port, vlan_vid, actions=[output]
            new_list.append({'port': out_port})
        if new_list != prev_list:
            self.dyn_tunnel_rules[tunnel_id][source_id] = new_list
            return True
        return True

# NOTE: 802.1x steals the port ACL table.
PORT_ACL_8021X = ACL(
    'port_acl_8021x', 0,
    {'rules': [{'eth_type': 1, 'eth_src': '01:02:03:04:05:06', 'actions': {
        'output': {'set_fields': [
            {'eth_src': '01:02:03:04:05:06'}, {'eth_dst': '01:02:03:04:05:06'}]}}}]})
PORT_ACL_8021X.build({}, None, 1)

MAB_ACL_8021X = ACL(
    'mab_acl_8021x', 0,
    {'rules': [{'eth_type': valve_of.ether.ETH_TYPE_IP, 'eth_src': '01:02:03:04:05:06',
                'ip_proto': valve_of.inet.IPPROTO_UDP, 'udp_src': 68, 'udp_dst': 67, }]})
MAB_ACL_8021X.build({}, None, 1)

redpajama_set_name: RedPajamaGithub


text:
Home Cars BMW i3 specs / review
CarsMiscellaneous
BMW i3 specs / review
by Joan Didion January 11, 2016
BMW i3 specs
FUEL ECONOMY (CTY/HWY) 137/111 mpg
CAR TYPE Hatchback
TRANSMISSION 1-speed Direct Drive
BASIC WARRANTY 4 Yr./ 50000 Mi.
HEATED SEATS Yes
ENGINE TYPE Electric
TOTAL SEATING 4
CYLINDERSNot Available
NAVIGATION No
BMW's current success can be attributed to its brilliant range of high-performance petrol and diesel cars, but with its hi-tech i3 the company has shown it has one eye on the future.
In fact BMW is now an industry leader when it comes to electric models, and to prove it, the innovative i3 is packed with hi-tech materials and cutting-edge engineering. Plus, with a punchy 168bhp motor and traditional rear-wheel-drive layout, it's as entertaining to drive as any 'normal' BMW – although with its own characteristic feel. It's also the first mass-produced car to feature a lightweight carbon-fibre composite body structure.
The boldly styled BMW i3 hatchback is available in both pure electric and range-extending guises, the later including an optional motorcycle engine that keeps the batteries topped up on longer journeys.
Without the range extender the BMW i3's range stands at anywhere between about 80 miles and 125 miles depending on how you drive; with the range-extender those numbers could double.
There are four distinctive themes to choose from – Standard, Loft, Lodge and Suite – all with bright and stylish seat and carpet trims, many made from sustainable materials.
The BMW i3 is about the same size as a Ford Fiesta but it feels higher and larger inside. Compared to many electric cars, like theRenault ZOE or Vauxhall Ampera, it's also very lightweight thanks to its carbon fibre and aluminium construction – in fact, it's about 300kg lighter than a Nissan LEAF.
The i3 and its sister model, the i8 plug-in hybrid sportscar, are the first production cars from the environmentally-focused BMW i sub-brand which was announced in 2011, although neither car reached production until 2013. They are both assembled at BMW's state of the art facility in Leipzig, Germany, although the i3's carbon-fibre composite body is fabricated in the US.
Engines, performance and drive
Sprightly electric performance and good handling make the i3 fun; a compromised ride can't spoil it
It doesn't take long behind the wheel of the i3 to realise that it's infused with BMW's trademark fun driving experience.
A high-set driving position, excellent visibility and light controls help the i3 take crowded city streets in its stride, while the electric motor's instant response lets you zip through gaps in the traffic with confidence.
Surprisingly, it's on twisting back roads where the i3 feels least composed. The steering is quick and well weighted, and there's more grip than you'd expect from the thin tyres, but hit a mid-corner bump and the tall i3 quickly becomes unsettled.
The short-travel suspension struggles to contain large body movements, plus there's plenty of roll. It never feels like it's going to lose control, and the stability control intervenes smoothly, but it's enough to make you take things a bit easier.
As a result, the BMW is at its best when being used as a relaxed and refined cruiser, maximising the range in those batteries.
The suspension copes well on the motorway, wind noise is kept in check and the two-cylinder motorcycle engine 'generator' emits only a distant drone in the range-extender version– although it's more intrusive at lower speeds.
As mentioned above, there are two powertrain options for the BMW i3. If you opt for the pure electric version, you get a 125Kw (168bhp) electric motor connected to the back axle via a single-speed fixed-ratio transmission, and a liquid-cooled lithium-ion battery.
They're neatly packaged – the battery is integrated into the rear cabin floor, while the motor takes up one half of the space under the boot floor. Opt for the 32bhp range-extending two-cylinder petrol generator, and you'll find it tucked under the boot floor on the opposite side to the electric motor. (Remember the petrol engine doesn't drive the car directly, it simply provides electricity for the battery or motor).
With its powerful electric motor and lightweight 1,270kg carbon fibre structure, the BMW i3 is surprisingly fast, too. Thanks to the electric motor's instant torque, acceleration is rapid, and it manages a 0-60mph time of 7.2 seconds – 3.2 seconds quicker than the Toyota Prius Plug-in hybrid.
Adding the extra weight of the range-extender generator brings the 0-62mph time down a shade to 7.9 seconds, but the difference is barely noticeable on the road thanks to the electric motor's instant response to a dab on the accelerator.
MPG, CO2 and running
Day-to-day running is cheap as chips, but you pay for the privilege at both ends through a high list price and poor residuals
The BMW i3's economy will depend greatly on the driving you do. Keep the battery topped up and stick to the city, and the 80-mile electric-only range should be plenty. In the range-extender i3 REx we got through a fully charged battery and a tank of fuel with an economy figure of 118mpg.
An overnight charge should cost no more than a couple of pounds, while the i3 is currently exempt from road fund licence, Benefit-in-Kind company car tax and the London congestion charge.
There's a choice of Comfort, EcoPro and EcoPro+ drive modes, and the latter two are designed to save energy, with EcoPro+ going as far as switching off the climate control and limiting speed to 56mph to maximise range.
Unfortunately, even the i3 REx isn't well suited to longer journeys. The engine is limited by the tiny nine-litre fuel tank, and only adds another 80 miles of range. That means if you go on a long trip using the petrol engine alone, you'll have to fill up every 70 miles or so if you don't want to risk running out of juice. With the battery exhausted and running on generator charge alone, the i3 can barely manage 36mpg in the real world – but that's not really the point, and at least the car will get you home.
Plugged into a domestic socket, the batteries can be boosted to an 80 per cent charge within seven hours, but BMW's powerful £315 i Wallbox charger slashes this time to three hours.
As with most electric cars and plug-in hybrids, the price is high even with the Government's £5,000 Plug-in Car Grant, and residuals aren't great, but company car tax is super-low. BMW also offers fixed-price servicing, plus access to conventional models if you need to make longer journeys.
Both versions of the BMW i3 are in group 21 for insurance purposes, which certainly isn't cheap by city car standards – but then the performance is better than most, and the cost of repairs to that carbon body structure could be significant.
The only disappointment is the BMW's poor residuals, as our experts predict that the i3 will retain just 30.9 per cent of its original value after three years.
Interior, design and technology
Concept car looks and design-led interior set the scene for a technology masterclass
The i3 has been designed from the ground up as an EV – and it really shows. Taking its cues from the BMW Coupe Concept that debuted in 2012, the battery-powered car looks like it's driven straight off a designer's computer screen.
Tall and narrow proportions give the i3 the look of an MPV rather than a family hatch, but you could argue it stands in a class of its own. Lightweight plastics are used for the heavily sculpted body panels, while the bonnet and glass tailgate get a distinctive gloss black finish. Other highlights include the angular window line, swept-back headlamps and metallic blue trim for the faired-in grille and lower sills.
The futuristic feel continues inside. Access is easy thanks to the rear-hinged doors and lack of a B-pillar – although you have to step over the wide sill. Once in, you'll be able to enjoy the cleverly packaged and imaginatively designed layout that's easy to use and beautifully finished.
Climb into the high-set driver's seat and the first thing you'll spot is a pair of large TFT screens – one ahead of the driver and one that appears to 'float' above the centre of the dashboard. These units display everything from speed to sat-nav info, and are controlled via BMW's trademark iDrive dial. Metallic blue inserts add the final flourish, while the low-set dashboard and vast windscreen create a bright and airy feel.
Sat-nav, stereo and infotainment
You'd expect a cutting-edge machine like the BMW i3 to pack quite a punch in the infotainment stakes, but actually the car offers the same degree of connectivity and control as other cars in the BMW line-up.
That's hardly a disappointment though. There's a sophisticated sat-nav as standard, DAB radio, hands-free Bluetooth plus access to a variety of social media, music and email apps. You can also upgrade with a Harmon Kardon sound system, and the Media Package which gives you a bigger 10ins screen, iDrive touch controller, and the BMW Professional sat-nav system with real-time traffic info.
Practicality, comfort and boot space
The i3 is roomy and comfortable for four, thanks to great design and clever packaging
Clever packaging means the BMW i3 is quite roomy, and although the car doesn't take up much room on the road it feels bigger from the inside. That's largely thanks to an airy interior and a relatively high seating position compared to many city cars, which gives you a great view of the road.
There's lots of space for driver and passenger, and plenty of adjustment for the driving seat and steering wheel mean getting comfy won't be a problem. There are neat cup-holders, armrest storage and cargo nets, while the glovebox has a top opening lid. The controls are beautifully laid out too, but one criticism we have is with the slightly dim headlights.
The BMW i3 is a ground-up design that reflects its 'clean sheet of paper' origins where other electric cars have played safe with more familiar styling themes.
The i3's noticeably wheel-at-each-corner stance emphasises its compact footprint – at 3,999mm nose-to-tail it is shorter than both the 4,445mm Nissan Leaf and the 4,100mm Renault Zoe. An upright stance means it's taller than both too – 1,578mm (i3) plays 1,550mm (Leaf) and 1,516mm (Zoe).
Leg room, head room & passenger space
The BMW isn't quite a full five-seater – there's only two seats in the rear – and nor is it quite a five-door car. The rear passengers climb in and out through small rear-opening coach doors that can only be opened when its adjacent front door is open too. At least the fact there's no B-pillar in the middle makes it very easy to get in and out.
The boot has a high floor, thanks to the running gear underneath, but the 50:50 split seats fold flat.
There's no loading lip, so you can easily slide things in to the space that mesures 260 litres with all the seats in place. That capacity grows to 1,100 litres with the seats folded down.
In the nose, you get a shallow tray for the tyre repair kit, but the cord to open it is hidden behind a panel in the passenger footwell.
Reliability and Safety
There's an 8-year warranty on the battery, but pedestrian safety costs the BMW i3 vital Euro NCAP stars
BMW is new to electric car technology, but you can guarantee it's worked hard to make the i3 as reliable as its internal combustion-engined models. The combination of a strong carbon fibre- reinforced plastic structure, six airbags and standard stability control means the i3 has some decent safety credentials. However, the bluff front end cost it points in Euro NCAP's pedestrian assessments – resulting in a disappointing four-star score.
You can add a number of hi-tech safety options, though, such as the £790 Driving Assistant Plus. This clever kit brings adaptive cruise control, forward collision alert and Traffic Jam Assist, which will accelerate, steer and brake the car at speeds up to 24mph. A pedestrian warning noise generator is £85.
There aren't enough BMW i3s around yet for the model to feature in our Driver Power Survey, but BMW's manufacturer rating slid again in 2015 down to 14th overall. In 2014 it finished 10th.
In a bid to reassure buyers who may be nervous about living with unfamiliar electric drive technology, BMW provides an eight-year and 100,000-mile warranty for the lithium-ion battery pack. The rest of the car – including the electric power system and the motor itself – is covered by a standard three-year guarantee, much like the rest of the BMW range.
By way of comparison Renault covers the Zoe's entire electric drivetrain for five years and 100,000 miles, while Nissan offers the Leaf with its standard three-year warranty cover plus five years for the battery. Toyota covers its hybrid batteries for up to 11 years, if you satisfy the service schedule.
Buy an i3 and you'll be offered BMW Service Inclusive (£375) and BMW Service Inclusive Plus (£1,280) packs. The former covers the car's servicing costs for five years or 60,000 miles, while the latter covers both servicing and maintenance for the same period.
[posts-by-tag tags="cars" number="5″]
Download Audio Mp3
auto reviewautomobile newsBMW i3 specsBMW i3 specs / reviewcarcar and bike magazinecarsCars Featuresjaguarroad test
Chevrolet Cruze hatchback 2017
Chevy Spark EV specs / reviews
Plumber v1.0 is available for Linux...
Ubuntu 20.04 Focal Fossa is available...
GitLab Adopted by KDE
Olivia – Elegant Cloud Music Player...
Wonderwall – Powerful Desktop Wallpaper manager...
Ubuntu 16.04 Connect Bluetooth on Dell-Insprion...
Post on website
Have a Tech related news or announcement that you want get published on KtechPit ? You can submit it using our guest post system.
Note: Submitted Posts are reviewed before they get published.
Apps on Snapstore
MovieSquare | Opensource and free movies Discovery tool for Linux
How to create Youtube API key 2020
Wonderwall – Powerful Desktop Wallpaper manager for Gnome/Ubuntu Desktop
Play clash of clans on Ubuntu / Linux / Windows
QTubeDl is GUI for Downloading and watching Youtube
Keshav Bhatt
Software & Web developer, Linux geek, astute learner, quick to grapse technical material.. Contact- [email protected]
@2019 - Ktechpit. All Right Reserved. Designed and Developed by Keshav Bhatt

redpajama_set_name: RedPajamaCommonCrawl


But it wasn't meth. It was cotton candy.
Now she's filed a lawsuit against Monroe County and the three officers involved for wrongful imprisonment and violating her civil rights. The lawsuit also targets Sirchie Acquisition Company, the maker of the field kit the deputies used to produce the mistaken test result.
According to the lawsuit, Fincher was a passenger in a car that was pulled over by two Monroe County Sheriff's deputies on December 31, 2016.
The deputies initially said they stopped the car because they thought the tinting on the car's windows was too dark, but clarified at the scene that it was not a violation.
They asked the driver if they could search the vehicle and soon found "a large, open clear plastic bag which contained a light blue substance, spherical in shape," in the car's floorboards, the lawsuit says.
Fincher says during that time she missed "several major life events," including the births of her twin grandsons and her daughter's miscarriage. She also alleges she was refused medical attention for a broken hand and an ovarian cyst.
On March 22, 2017, the GBI finally issued a report that said there were "no controlled substances confirmed" in the blue matter. Still, Fincher wasn't released from jail for almost two more weeks, on April 4, the lawsuit says.
CNN has made multiple calls to the Monroe County Sheriff's office and has not received a response.
"At first I kept thinking I was going to get out, then the next day came, and I'd think, 'Maybe I'll get out tomorrow. Then tomorrow turned into the next day," she said.
She called home every day to speak to her children, but wasn't there when her daughter experienced a miscarriage or when her son and his wife welcomed twin boys.
She also wants closure on some of the aspects of the ordeal that still bother her. She still isn't sure, for instance, why it took so long for her to be released after the results of the forensics testing came back. She says she also never received an apology from the sheriff's department.


text:
Q: How do you style a Custom Element like a DIV? I'm looking for a consistent cross-browser solution to style custom elements like a DIV. (Ie: resetting to DIV styling as a starting point). Chrome seems to treat custom elements like a span.
Here's what I use custom elements for:

*

*For a Restrict: E angular directive.

*As part of a directive's template so I can select a child element using element.find('custom-element') from the directive's link or controller function. This is occasionally necessary when building a directive that requires calculating child element dimensions and/or position.

Is it as simple as doing this:
custom-element {
  display: block;
}

Or are there gotchas that I should be aware when dealing with certain browsers?

A: Custom tags is strongly discouraged by those who are working on HTML standards. IE8 and lower forms of Internet Explorer do not by default support unknown tags, the solution is to add a script to create the element.

HTML5 specifies that unknown tags are not erroneous for the browser, but they are for code checkers. Browsers should allow them to be styled with CSS just like tags that the browser is familiar with, and by default they are inline elements not blocks.
The purpose of this is not that everybody creates their own set of tags, which will cause confusion, but to allow new tags to be created into the future without breaking older systems.
Violations of HTML5 standards in the way you are implementing are considered will full violations and are used to consider how to improve the standard when things can not be done using the standards.
To accomplish what you are trying to accomplish, using standards, they have added data attribs and custom attribs http://html5doctor.com/html5-custom-data-attributes/ ...

document.querySelectorAll('[customElement]');

... which is what the html5 standards people would like you to use.
Note customElement="true" is a commonly used willful violation

redpajama_set_name: RedPajamaStackExchange


text:
Warcraft Movie
This is my review for the Warcraft movie, which is based off the video game.
I normally give a spoiler warning, but I won't say enough about the plot of the movie to ruin anyone's experience. But in case you are sensitive to any information and want to go in fresh, then you should stop reading now– but I doubt that since you've read this far already.
I do have some background in playing Warcraft III, World of Warcraft (WoW), Hearthstone, and other games from Blizzard Entertainment. I played WoW for 4-5 months, leveling my Tauren Warrior to level 52 before quitting because it took too much of my time. I have basic familiarity with the lore, but by no means am an expert or hardcore fan.
The movie was just okay for me. Definitely not good, but also not as bad as it's Rotten Tomatoes score: 27% currently.
Fantasy-based movies and TV shows are hard to make for a wide audience. No matter how much or how many people enjoyed the Lord of the Rings trilogy, some people will find it incredibly dull and won't watch it. The same could be said for the very popular Game of Thrones series. One thing they have in common is that need time to build out the fantasy world and characters– it's not a simple 1-2 hour commitment, it's many many hours.
You don't have to be a fan to enjoy the movie, but fans will enjoy the movie more because there are Easter eggs hidden throughout. I watched the movie in 3D, which I don't recommend for anyone because it's distracting to have the eyes wander around the screen looking for things.
Blizzard has been building and expanding on the fantasy world for more than 20 years now. There's no way that a movie can capture it in a few hours. There are more races, conflicts, characters than what is presented in the movie.
The best parts of the movie were the orcs and magic portrayed. Duncan Jones set out to portray both sides and he did a good job fleshing out the orc tribe. The CGI looked amazing and the actors were phenomenal. I really was taken into their characters that I just didn't see actors behind the animation at all. The magic didn't need any explaining, it was just fun.
The weakest parts of the movie were the humans– I just could not care about them or their race. The writing and casting was just weak over all. The human cities was big, but so short that as a viewer you don't get to breathe it all in.
The overall story was rather simple. That's why it's doing well in the box office in China and overseas– it's a visual story that doesn't require reading subtitles to understand what's going on. But there were still things that could have been better explained if they chose to do more narration. If you can't show it due to time constraints, explain it.
I hope that Blizzard will keep making movies based on their video game properties. What makes their games fun is their craft in making compelling characters and stories. Now this movie may not be a hit in the United States, but I'm sure it'll make them money world-wide. I want a Warcraft sequel. I want a Starcraft movie. I'd love to see an Overwatch TV series even. I would really love to see them stretch beyond video games.
Blizzard has a lot of stories to offer and I hope they break into the mainstream like Marvel has.
If you want something more in depth, check out these youTubers.
Warcraft: The Beginning Lore, Spoiler Discussion and Review by Alachia Queen
Warcraft Movie Review SPOILERS by Beyond the Trailer
Warcraft Movie Review and Easter Eggs by Emergency Awesome
Movies of 2018
Hugo v0.91.2 powered • Theme Beautiful Hugo adapted from Beautiful Jekyll • [516cf8a6]


Tradehill suspends trading due to "operational and regulatory issues"
Tradehill's founder and CEO has confirmed the bitcoin exchange platform has suspended trading due to "operational and regulatory issues" faced by its bank – the Internet Archive Federal Credit Union (IAFCU).
Jered Kenna said in a statement on reddit that trading on the Tradehill platform had stopped, but only temporarily.
"We have recently made the decision to temporarily suspend trading on the Tradehill platform.
Internet Archive Federal Credit Union has experienced operational and regulatory issues and we are no longer able to continue our relationship at this time.
Our unique relationship with IAFCU allowed our clients to hold their Tradehill balance in an account opened in their name and federally insured. If you had an account with Tradehill after our integration with IAFCU and would like to withdraw your funds please contact msr@archive.org.
Jordan Modell, of IAFCU, also wrote a blog post on the subject, claiming that his company has enjoyed serving some of those involved in the bitcoin space, but that until it receives some clarity from regulators, it can no longer continue to serve some of its "corporate members".
He suggests he is still interested in helping to create a "stable environment" for bitcoin to thrive in.
"Starting three months ago we have enjoyed serving some individuals and companies involved in bitcoin that are within our field of membership. While exciting, this has also been during a period of increased interest from the press, regulators, and other financial services entities that make up the financial community.
In doing this, certain operational and regulatory issues came up including some that apply to new credit unions like ours.
Our credit union has worked within the evolving regulatory environment, which has not always been easy. This is a long not a short road and sometimes with detours. Until we have further clarity, we are unable to service some of our corporate members.
Tradehill has had a pretty bumpy ride of things right from the get-go. The exchange first launched in early June 2011, but reported anomalies with Dwolla payments the following month. Fast-forward eight months to February 2012 and Tradehill was shut down after losing $100,000 in a dispute with the payment processor.
The company was back with a vengeance, though, in March of this year when it launched Prime – a B2B digital currency exchange.
"We are excited to present a new way for businesses and high-end investors to interact with the digital currency economy," Jered said at the time.
However, it hasn't been smooth sailing since then. On the day Tradehill relaunched, US financial regulator FinCEN released its regulation on virtual currencies, which confirmed that anyone selling units of a decentralised virtual currency to another person for real currency or its equivalent should be categorised as a money transmitter.
This guidance applies to businesses 180 days after they begin trading in bitcoin, so Tradehill has until mid-September to get its paperwork in order.
CoinDesk contacted both Tradehill and IAFCU but had not received comment at the time of publication, so it is not known what Tradehill's next steps are. Kenna's reddit statement suggests the company will be up and running again soon, so it is likely he is in talks with other potential banking partners.


The City of Port Colborne has a new Financial System, which will change the look of a few things as well as give you some more options with your Water/Wastewater Bills.
Payment arrangements for outstanding water accounts can be made by contacting the Water Clerk (see contact information below).
The billing of water and sewer services are produced based on actual usage through water meter readings plus fixed costs. Meter readings and billings are done on a quarterly basis for three different areas within the city.
Readings and billings are normally done as per a schedule, with specific due dates.


Final Monday the Obama administration disclosed the nation's first fuel-economic system guidelines for trucks and buses. These rules are to be established in 2014 which will require engine manufacturers to begin heavy research and growth on gas efficiency and air pollution controls. Beginning in 2018 these engines will likely be required to reduce gasoline utilization and carbon-dioxide emissions by 20%.
In conclusion, its clear that strain measurement can help environment friendly diagnostics, whether or not the failure is electronic or mechanical. The tools available for this measurement method is now easily out there and fairly priced. For those who buy the kit, maintain it useful within the workshop and follow making measurements frequently. You'll build up knowledge and be assured to hold out the method each time wanted. As well as, regular use can shorten diagnostic time, increase effectivity and shorten return-on-funding time after buying the package.
The second of Porter's Five Forces is Bargaining Energy of Suppliers". Almost each city in America has some kind of automotive dealership, with the number being relative to population and in some circumstances the income of the customer base. These suppliers rely very closely on the foremost automotive producers to supply their stock of latest automobiles and vans. Dealerships are below great strain to maintain good relationships with The Huge Three", which leads to the same situation as patrons where there's little power of affect. One other form of supplier in this market are those who present the parts of automobiles, like fenders, seats, tires, navigation techniques, and so on. Right here once more, the few variety of manufacturers, or buyers, significantly affect worth and amount, limiting the power of those suppliers.


For single target, it doesn't seem like spamming riptide on a target that already has it is very efficient or the best use. Am I wrong there? Is there a way to figure that out?
Rip Tide is on the gcd and usually more than one person is taking damage. I usually time this so i move my mouse over one unit then the other within that gcd time frame. Thus I dont stack it on one. After the initial use of its two heals the cd is fairly consistentlly used on cd.
How else would you want it?
I made some updates but spamming it still works well for me. If you want you can take it off the macro or put it into a modifier. However I prefer the current modifier set up.
I've removed Healing Surge from the AoE macro as it seemed to be only casting that for a while (during GC I think). The result is that far less mana is used and I can keep healing.
Check out the link and let me know how those work for you over there. Thanks for your input!


Several departments and offices contribute to or constitute the Haigazian University Publications. These include the President's Office, the Admissions Office, the Student Life Office, the Armenian Studies Department and the Armenian Diaspora Research Center.
Through official government entitlement since 2011, all publications are now released by the Haigazian University Press.
HU Press publications are all accessible and downloadable.


text:
Q: How to apply limit properties in this case? I was asked to find the following limit:
$$
\lim_{x \to 1} \frac{1 - \sqrt x}{1 - x}
$$
I worked it out using direct substitution that the limit is $\frac{1}{2}$.
Initially I was trying a more algebraic approach, finding separately the limits of
$$
\lim_{x \to 1} 1 - \sqrt x = 0
$$
$$
\lim_{x \to 1} 1 - x = 0
$$
And then applying limit properties for division and multiplication:
$$
\lim_{x \to a} (f \cdot g)(x) = l \cdot m
$$
$$
\lim_{x \to a} (\frac{1}{g})(x) = \frac{1}{m}
$$
But that doesn't work, since the limit in the denominator will $0$.
So besides direct substitution, the limit properties are of no use in this case when there is a $0$ in the denominator?

A: If it were not for cases like this, where it is NOT possible to find the limit just by finding the limits of the numerator and denominator separately, one would probably never use the concept of limits at all.
The answer by Alan Muniz gives you one way to do this. Here's another:
\begin{align}
& \lim_{x\,\to\,1} \frac{1-\sqrt x}{1-x} = \lim_{u\,\to\,\text{what?}} \frac{1-u}{1-u^2} \\[10pt]
& \text{(As $x\to1,$ then $u = \sqrt x \to \sqrt 1 = 1$.)} \\[10pt]
= {} & \lim_{u\,\to\,1} \frac{1-u}{(1-u)(1+u)} = \lim_{u\,\to\,1} \frac 1 {1+u} = \cdots
\end{align}

A: Hint;
Change the signs of the numerator and denominator to get
$$\frac{\sqrt x-1}{x-1}=\frac{f(x)-f(1)}{x-1}, \enspace\text{where } f(x)=\sqrt x$$
This is a rate of variation from $x=1$, hence the limit is …

A: Since the function involves a square root of $x$ we tacitly assume $x >0$ and from $x\to 1$ we assume that $x\neq 1$. Then we may use $1- x = (1 - \sqrt x)(1 + \sqrt x)$. It follows that
$$
\lim_{x \to 1} \frac{1 - \sqrt x}{1 - x} = \lim_{x \to 1} \frac{1 - \sqrt x}{(1 - \sqrt x)(1 + \sqrt x)} = \lim_{x \to 1} \frac{1}{1 + \sqrt x} = \frac{1}{2}
$$


text:
\section{Introduction}

The structure and dynamics of molecular clouds (MCs) has been the subject
of intensive investigation during the past two decades. Since MCs are the
sites of star formation, their properties provide insights into the
initial conditions needed to form stars. On the other hand, energy
injected into the clouds by young stars is also believed to play a crucial
role in the cloud dynamics and evolution (e.g. Whitworth 1979; Bally \&
Lada 1983; Miesch \& Bally 1994). The observed state of a cloud represents
the balance between energy injection and dissipation.

Observations show that cloud internal motions are highly supersonic,
incoherent, and random (e.g. Bally et al. 1987, 1989, 1990).
Furthermore, the cloud structure is complex and by many measures is
suggestive of the presence of random flows. Indeed, many authors have
attempted to describe clouds using various models of turbulence (e.g.
Ferrini, Marchesoni \& Vulpiani 1983; Henriksen \& Turner 1984; Scalo
1987; Fleck 1988; Fleck 1996) inspired by the scaling laws observed in the
interstellar medium (Larson 1981). More recently, there have been several
attempts to describe cloud morphology and velocity fields using fractals
(e.g. Scalo 1990; Falgarone \& Phillips 1991; Falgarone, Phillips \&
Walker 1991; Falgarone 1992; Larson 1995; Elmegreen 1997).

Most theoreticians have argued that clouds are supported by magnetic
fields (Mestel 1965; Strittmatter 1966; Parker 1973; Mouschovias 1976a,
b; McKee \& Zweibel 1995) and interpreted the observed line--widths in terms
of magneto--hydrodynamic (MHD) waves (Arons \& Max 1975; Zweibel \&
Josafatsson 1983; Elmegreen 1985, Falgarone \& Puget 1986). However,
comparison of the extinction statistics with recent models of supersonic
and super--Alfv\'{e}nic random flows suggests that such models may provide
a superior description of MCs (Padoan, Jones \& Nordlund 1997). OH
Zeeman measurements (Crutcher et al. 1993; Crutcher et al. 1996) have also
been shown to be consistent with the predictions of a super--Alfv\'{e}nic
random flow (Padoan \& Nordlund 1997).

In this paper, we compare some observed properties of the Perseus
molecular cloud with the predictions of supersonic and super--Alfv\'{e}nic
random flows. We start with a self--consistent MHD simulation of a random
flow in a 3--D $128^3$ grid (Padoan \& Nordlund 1997). We solve the
radiative transfer problem using a non--LTE Monte Carlo approach (Juvela
1997) to compute $^{13}$CO synthetic spectra on a 90 by 90 cell grid with
60 velocity channels. Remarkable agreement of these models with the data
is illustrated by several results. These results demonstrate that such
models provide an excellent description for the kinematics and structure
of molecular clouds despite the absence of gravity, external radiation
fields, or stellar outflows in the models.

\section{The Perseus Molecular Cloud}

Observations of the Perseus molecular cloud complex were made from 1985 to
1991 with AT\&T Bell Laboratories 7~m offset Cassegrain antenna in
Holmdel, New Jersey. Approximately a 6$^\circ$ by 4$^\circ$ region was
surveyed in the 110 GHz line of J=1$\rightarrow$0~$^{13}$CO . The observations were made on a
1{$^{\prime}$}\ grid with a 100{$^{\prime \prime}$}\ beam yielding 33,000 spectra, each with
128~$\times$~100~kHz channels (0.273~km~s{$^{-1}$} ). See Billawala et al. (1997)
for further details of observations and discussion of the cloud structure.

The Perseus molecular cloud is roughly a 6$^\circ$ by 2$^\circ$ region
located at a distance estimated to range from 200 to 350~pc (Herbig \&
Jones 1983; C\^ernis 1990) and has a projected size of 30 by 10~pc (see
figure 1). The cloud is part of the larger Taurus--Auriga--Perseus complex
and lies below the galactic plane ({\it b} $\sim\ -20^\circ $) with an
estimated mass of 10$^4$~M{$_{\odot}$}\ (Billawala et al. 1997).

The complex has produced some high mass stars at its eastern end which lie
near the centroid of Perseus OB2 association, a loose grouping of 5 to 10
O and B stars, that is about 7 million years old (Blaauw 1991). Perseus
OB2 has blown a 20$^\circ$ diameter (100~pc) supershell into the
surrounding interstellar medium that can be seen in 21~cm H~${\sc i}$ data
(Heiles 1984). The shell is partially superimposed on the Perseus
molecular cloud and may be interacting with it. Perseus contains two young
stellar clusters and a background of relatively inactive molecular gas
that has formed few stars.

Near the eastern end is the young ($<$ 7~Myr old) cluster IC348, which has
several hundred members and may still be forming (Strom, Grasdalen \&
Strom 1974; Lada, Strom \& Myers 1993; Lada \& Lada 1995). Omicron Persei,
a B1 III star, located near the center, is believed to be a few parsecs
in front of the cloud
(Bachiller et al. 1987). Lada \& Lada (1995) estimate a cluster population
of $\approx $ 380 stars with a highly centralized distribution falling off
inversely with distance from the inner 0.1~pc diameter core which contains
about $\sim$~200~M{$_{\odot}$}\ of stars and a density of 220~M{$_{\odot}$}~pc$^{-3}$.
Star formation has been going on for at least 5 to 7~Myr at a roughly
constant rate and with an efficiency of $\sim~50\%$.

A second and even younger cluster is embedded in the Perseus cloud several
degrees to the west near the reflection nebula NGC1333. This region
contains the most active site of ongoing star formation in Perseus.
NGC1333 contains an embedded $<$~1~Myr old infrared cluster, a large
number of molecular outflows (Knee \& Sandell 1997), Herbig--Haro objects
(Bally, Devine \& Reipurth 1996), and shock excited near--infrared H$_2$
emission regions (Aspin, Sandell \& Russell 1994; Hodapp \& Ladd 1995;
Sandell et al. 1994). Lada, Alves \& Lada (1996) find 143 young stars
in a 432 square
arc--minute region with most being members of two prominent sub--clusters.
More than half of these stars display infrared excess emission, a
signature of young stellar objects. Lada et al. estimate the age of the
cluster to be less than $10^6$ years with a star formation rate of
$4~\times~10^{-5}$~M{$_{\odot}$}~yr$^{-1}$.

Away from IC348 and NGC1333, the Perseus cloud contains about a dozen
dense cloud cores with low levels of star formation activity including the
dark cloud B5 (Langer 1989; Bally, Devine, \&  Alten  1996) at its eastern
end, the cold core B1 for which a magnetic field has been measured by
means of OH Zeeman (Goodman et al. 1989; Crutcher et al. 1993), and the
dark clouds L1448 and L1455 on the west end (Bally et al. 1997).

The cloud exhibits a wealth of sub--structures such as cores, shells, and
filaments and dynamical structures including stellar outflows and jets,
and a large scale velocity gradient. While emission at the western end of
the complex lies mostly near v$_{lsr}$~=~4~km~s{$^{-1}$}\ (L1448), the eastern end
of the complex has a velocity of v$_{lsr}$~=~10.5~km~s{$^{-1}$} (B5). This may be
an indication that we are seeing several smaller clouds partially
superimposed along the line of sight (C\^ernis 1990).

\section{Theoretical Models}

Padoan et al. (1997) computed synthetic molecular clouds containing grids
of 90~$\times$~90 spectra of different molecular transitions for a total of
more than a half a million spectra. The spectra were obtained with a
non--LTE Monte Carlo code (Juvela 1997) starting from density and velocity
fields that provide realistic descriptions of the observed physical
conditions in MCs. The density and velocity fields are obtained as
solutions of the magneto--hydrodynamic (MHD) equations in a 128$^3$ grid
and in both super--Alfv\'{e}nic and highly supersonic regimes of random
flows (Padoan \& Nordlund 1997). The resulting density fields span a
continuous range of values from 0.1 to 10$^5$ cm$^{-3}$ which produce
column densities ranging over three orders of magnitude or more. These
cloud models have already been shown to reproduce observed statistical
properties of MCs (Padoan, Jones \& Nordlund 1997; Padoan \& Nordlund
1997).

In this work we use a 90~$\times$~90 grid of spectra of J=1$\rightarrow$0~$^{13}$CO\ from a 5~pc
diameter artificial cloud. For a detailed description of the construction
of the synthetic spectra we refer the reader to Padoan et al. (1997).

The MHD numerical experiment which produces the synthetic cloud does not
account for gravity, stellar radiation, or stellar outflows. However, the
numerical flow is consistent with the general observed properties of dark
clouds such as the existence of random and supersonic motions. The mean
density and rms velocity in the model are related to the physical size of
the computational grid via Larson's interstellar medium scaling laws
(Larson 1981). A 5~pc model has been selected because the Perseus complex
looks like a string of smaller clouds with an estimated size of a few
parsecs. The mean density of the 5~pc model is 400 H$_2$ molecules
cm$^{-3}$. This corresponds to a total mass of $3.2 \times 10^3$~M{$_{\odot}$}\
(using a mean molecular weight of $\mu$~=2.6 to correct for He).

\section{Statistics of the Observed and Synthetic Spectra }

Figure 1 shows the integrated J=1$\rightarrow$0~$^{13}$CO\ map of the Perseus complex. The two
brightest emission regions lie near the young stellar clusters IC348
(left) and NGC1333 (right). Complex and filamentary structure is evident
in this image, in the individual channel maps, and in images of peak
antenna temperature (Billawala et al. 1997). Figure~2 left and center
panels show close--up views of the L1448 and B5 dark clouds respectively.
Figure~2 on the right shows one particular synthetic map used in our
analysis. It is obtained from the 5~pc cloud model and shows the
integrated antenna temperature of the J=1$\rightarrow$0~$^{13}$CO\ synthetic spectra as the
three observed maps in figures 1 and 2. As the real data, the synthetic
image shows filamentary structure, cores, and partial shells.

Fig.~3 shows the mean spectrum obtained by averaging all spectra lying
within the boundaries of the maps of each of three regions; B5, L1448, and
the entire Perseus complex. We over--plot the synthetic mean spectrum
computed from the 5~pc synthetic map (dashed lines). The spectra are
centered about their own mean. The high velocity blue--shifted tail in the
L1448 spectrum may be produced by an unrelated cloud superimposed along
the line--of--sight. The B5 cloud has been estimated to have a mass of
slightly less than $10^3$~M{$_{\odot}$}\ (Langer et al. 1989) while the mass of
L1448 has been estimated to be about 500~M{$_{\odot}$}\ by Bally et al. (1997).
These results are consistent with the narrower width of the mean spectra
as compared to the width of the mean spectrum of the more massive
(3200~M{$_{\odot}$} ) theoretical model. The mean spectrum of the entire Perseus
cloud is wider than that of the theoretical model for different reasons.
First, the total mass of the Perseus complex is about $10^4$~M{$_{\odot}$}\
(Billawala et al. 1997). Second, there is a large scale systematic
velocity gradient from the eastern to the western ends of the complex
which are not taken into account in our models. The projected length of
the cloud is 30~pc, far larger than the size of our model. Finally, there
is evidence that this gradient is produced by the superposition of two
clouds that may be as far as 100~pc distant from each other (C\^ernis
1990; Herbig \& Jones 1983).

The probability distributions of the velocity integrated
antenna temperature for L1448, B5, and the entire Perseus cloud are plotted
in Fig.~4. The theoretical result derived from the 5~pc diameter model cloud is
over--plotted in dashed lines. Though there are individual differences
between the clouds and the model, the overall shapes of the distributions
are qualitatively similar in that they are dominated by intermittent
tails. Differences between L1448 and B5 may be in part due to
line--of--sight confusion and small number statistics. For the entire
Perseus cloud, the main difference may be attributable to the fact that it
is a much larger cloud than our model. The distributions of larger models
are in fact expected to be more intermittent (Padoan \& Nordlund 1997).
Since the integrated antenna temperature is proportional to the column
density, this result shows that the theoretical density distribution is
consistent with the observed one.

Figure~5, 6, and 7 show 30 by 30 grids (30{$^{\prime}$}\ by 30{$^{\prime}$}\ for the real
data) of spectra for L1448, B5, and the model respectively. In all three
figures, we have selected the highest intensity regions of these three
maps. Note the qualitative similarity between the real data and the model
spectra.

Figure~8 through 11 show histograms of the first four statistical moments
of the individual spectra for all of Perseus, L1448, B5, and the model
respectively. The plots in the upper left show the distributions of
velocity centroids centered around their means. The upper right plots
show the distributions of the line velocity dispersions (the line widths).
The lower left plots show the skewness of these profiles which measures
the degree of asymmetry present in the profiles. The observed histograms,
like the theoretical ones, present a distribution of skewness values
around 0, that is the gaussian value. They have a bit more extended
tails than the theoretical histograms, but unfortunately the tails are
rather sensitive to the noise in the observed spectra, and there is no general
way to deal with the noise in order to make the tails statistically significant.
The lower right plots show the kurtosis which measures the intermittency
(high velocity tails) in the
spectra. The distribution of kurtosis for the theoretical cloud are
similar to the observed distributions. However, the observed peaks are
centered around 2.3 rather than 3.0 for the theoretical model. The
vertical dashed lines correspond to the values of the same statistical
moments in the mean spectra shown in figure~3.

Scatter plots of the equivalent width versus velocity
integrated antenna temperature are shown in Fig.~12.
The equivalent width is here defined as the velocity integrated
antenna temperature divided by the peak antenna temperature in
each spectrum. Note that the theoretical and real data agree
in magnitude, in dispersion, and have a similar overall shapes.
The observed values of the line--width at the lowest integrated
temperatures are a bit smaller than the theoretical ones, but that
region of the plots should not be compared with the theoretical
results, because the contribution from the noise in the observed
spectra is there too strong.
B5 apparently has a smaller equivalent width for every value of
integrated temperature probably because it is a smaller cloud and
is less dynamic than L1448. Over a half--dozen active outflows have
been discovered in L1448 (Bally et al. 1997) while only two are
known in B5 (Bally, Devine \& Alten 1996).

\section{Discussion and Results}

The model we constructed was built upon very general considerations and
not tailored to the specific characteristics of the Perseus molecular
cloud or individual cores. Only the general interstellar medium scaling
laws (Larson 1981) have been used to fix the physical size of the cloud
model. The model has been inspired by the observation that random
supersonic motions are ubiquitous in molecular clouds.

The dynamic range of length scales covered by the MHD calculations ranges
from 0.04~pc to 5~pc (128$^3$ grid--points). The radiative transfer
calculations and the resulting spectra cover a linear scale range from
0.05~pc to 5~pc (90$^3$ grid--points). However, numerical dissipation
effectively degrades this
resolution by a factor of two to an inner scale of about 0.1~pc. Thus the
inner scale of the theoretical models are comparable to the linear
resolution of the 100{$^{\prime \prime}$}\ beam used in our observations. The Bell Labs
7~meter telescope beam has a linear resolution of about 0.14 pc (assuming
a distance of 300~pc for the Perseus cloud) and the maximum extent of the
Perseus cloud that has been mapped is about 30~pc.

Giant molecular clouds (GMCs; M$~>~10^5$~M{$_{\odot}$}\ and L $\approx$ 20 to
50~pc) are gravitationally bound. This must be the case since the product
of the internal velocity dispersion squared times the density is one to
two orders of magnitude greater than the pressure of the surrounding
interstellar medium. Gravity must provide the restoring force on the
scale of a GMC, otherwise GMCs would be dispersed before they could form
any stars. Individual stars form from the gravitational contraction of
small cores with sizes of order 0.1~pc, while clusters of stars such as
IC348 and NGC1333 form from cores about 1~pc in diameter. Thus gravity
is certainly important on the very large scale of GMCs (L $>$ 20~pc) and
on the very small scales of dense star forming cores (L $\le$ 1~pc). Our
model and observations have linear dimensions intermediate between these
two scales. The results of this work show that on intermediate scales the
observed properties of molecular clouds and likely the initial conditions
for star formation can be appropriately described without explicitly
accounting for gravity. Self--gravitating cores may occasionally condense
from the random flow where a local over-density is produced statistically.
However, at any one time, only a fraction of the total mass is involved in
such condensations. If indeed self--gravitating cores condense from the
intermittency of the random flow, then it might be possible to predict the
mass spectrum of the resulting condensations which produce stars. This may
be an important ingredient in constructing the initial stellar mass
function (Padoan, Nordlund \& Jones 1997).

In this picture, the overall density structure inside a GMC is {\it not}
the result of gravitational fragmentation, but rather of the presence of
supersonic random motions together with the short cooling time of the
molecular gas. We predict that there are several shocks in the gas along
any line--of--sight with velocities comparable to the overall cloud
line--width. These shocks have velocities of order 1 to 10 km~s{$^{-1}$}\ which are
not observable in the forbidden lines in the visible portion of the
spectrum. However, there are several far--infrared transitions such as the
157~$\mu$m fine--structure line of C$^+$, the 63~$\mu$m line of O~{\sc i} \ , and
the 28, 17, and 12 $\mu$m v~=~0--0 lines of H$_2$ which are readily
excited by such shocks. The COBE and ISO satellites have shown that these
transitions together carry about 0.1\% of the total luminosity of a
typical galaxy (Wright et al. 1991; cf. Lord et al. 1996).
We predict that
roughly 10\% of this emission is produced by the shocks discussed above
because these transitions are the primary coolants in the post--shock gas.

The dissipation of the kinetic energy of internal motions, $E_{GMC}$, by
shocks in a GMC produces a luminosity of order $L_{GMC} ~\approx ~ E_{GMC}
/ \tau _{GMC} ~\approx $ $3 \times 10^3$~(L{$_{\odot}$}\ )~$E_{51} \tau _{4 \times
10^6}$ , where the dynamical time is taken to be a cloud crossing time,
$\tau _{GMC} ~=~R_{GMC}/ \sigma _{GMC}$ and $\sigma _{GMC}$ is the cloud
velocity dispersion. Since the above infrared transitions are the main
coolants in the post--shock layers of these low velocity shocks, we expect
that future observations of clouds like Perseus will show extended bright
emission in these infrared transitions.

Observations of young stellar populations show that stars form from GMCs
over a period of order 10 to 20 Myrs (Blaauw 1991) which implies that
clouds must survive for at least this long. Since this time--scale
exceeds the dissipation time, the internal motions must be regenerated.
There are several possible sources for such energy generation. When
massive stars are present, their radiation, winds, and supernova
explosions inject large amounts of energy into the surrounding gas.
However this amount of energy is far in excess of what is required to
balance the dissipation of kinetic energy in shocks. Massive stars are
likely to be responsible for cloud disruption.

The second candidate energy source is outflows from low mass stars which
form more uniformly throughout the cloud (Strom et al. 1989; Strom,
Margulis \& Strom 1989). The Perseus
molecular cloud contains only intermediate to low mass stars, which during
their first $10^5$ years of life produced jets and outflows. All the cores
studied here are known to have multiple outflows. Over a dozen outflows in
NGC1333, 8 groups of Herbig--Haro objects in L1448, and 2 outflows in B5
have been discovered. Outflows can provide the mechanism to stir the
clouds and balance the dissipation of the random supersonic motions.

The plots of equivalent width versus integrated antenna temperature in
figure 12 support the scenario described above. While the plot for L1448
is in excellent agreement with the model, the plot for B5 shows a
systematically lower equivalent width. This is consistent with the lower
number of outflows discovered in B5 relative to L1448.

However, the main source of energy for the small and intermediate scale
differential velocity field may simply be cascading of energy from larger
scales.  The dynamical times of intertial scale motions are short compared
to those of the larger scale motions. In the inertial range,
there is a quasi-stead flow of energy from larger scales towards the
energy dissipation scales.  The numerical simulations represents
only piece of the inertial range, and hence, on these scales, energy
input at the largest wavenumbers is to be expected.

On the largest, energy carrying scales, we have already remarked that
the motions must be constrained by gravity.  Gravity field
fluctuations large enough to constrain these clouds must come from
self-gravity, and from interactions with neighboring clouds and
embedded stars.  The time variations and tidal effects due to relative
motions of the self-gravitating masses is perhaps the main source
of energy input at the large scale end of the inertial cascade.

Padoan, Jones \& Nordlund (1997) and Padoan \& Nordlund (1997) have shown
that the statistics of infrared stellar extinction (Lada et al. 1994) and
the OH Zeeman measurements (Crutcher et al. 1993; Crutcher et al. 1996)
can be explained by our model of supersonic random flows. In the present
work, we have shown that the same model is consistent with molecular
clouds observed in the J=1$\rightarrow$0~$^{13}$CO\ line. These results together provide
compelling evidence that {\it supersonic and super--Alfv\'{e}nic random
flows correctly describe the structure and dynamics of molecular clouds.}

\acknowledgements

This work has been partially supported by the Danish National Research
Foundation through its establishment of the Theoretical Astrophysics
Center. Computing resources were provided by the Danish National Science
Research Council, and by the French `Centre National de Calcul
Parall\`{e}le en Science de la Terre'. PP is grateful to the Center for
Astrophysics and Space Astronomy (CASA) in Boulder (Colorado) for the warm
hospitality offered during the period in which this paper has been
written. JB and YB acknowledge support from NASA grant NAGW--4590 (Origins)
and NASA grant NAGW--3192 (LTSA). The work of MJ was supported by the
Academy of Finland Grant No. 1011055.

redpajama_set_name: RedPajamaArXiv