text:
import argparse
import textwrap
import os
import sys

from _version import __version__

from core import *
import config
import config_printer
from config import SPECIAL_FIELDS
import log

import logging

try:
    from collections import OrderedDict
except:
    try:
        from ordereddict import OrderedDict
    except:
        print "ERROR: OrderedDict not found! It is required to run this script."
        sys.exit(1)

def add_args(parser, inherit, opts):
    for opt in opts:
        if inherit:
            opts[opt]['help'] = argparse.SUPPRESS
            opts[opt]['default'] = argparse.SUPPRESS
        opt_opt = dict(opts[opt])
        parser.add_argument(opt, **opt_opt)

def add_list_args(parser, inherit = False):
    opts = OrderedDict()
    opts['--data-single-date'] = \
        {
            'action'    : 'store',
            'metavar'   : 'DATE',
            'dest'      : 'data_single_date',
            'help'      : 'Use single date. Format should be "YYYY-MM-DD HHz". Negates the options below specifying dates and times.',
        }
    opts['--data-path-format'] = \
        {
            'action'    : 'store',
            'metavar'   : 'PATH_FORMAT',
            'dest'      : 'data_path_format',
            'help'      : 'Specify the path format for data.',
        }
    opts['--data-experiment-id'] = \
        {
            'action'    : 'store',
            'metavar'   : 'EXPERIMENT_ID',
            'dest'      : 'data_experiment_id',
            'help'      : 'Specify the experiment ID for data.',
        }
    opts['--data-start-date'] = \
        {
            'action'    : 'store',
            'metavar'   : 'DATE',
            'dest'      : 'data_start_date',
            'help'      : 'Specify the start date for data. Format should be "YYYY-MM-DD HHz".',
        }
    opts['--data-end-date'] = \
        {
            'action'    : 'store',
            'metavar'   : 'DATE',
            'dest'      : 'data_end_date',
            'help'      : 'Specify the end date for data. Format should be "YYYY-MM-DD HHz".',
        }
    opts['--data-instrument-sat'] = \
        {
            'action'    : 'store',
            'metavar'   : 'INSTRUMENT_SAT',
            'dest'      : 'data_instrument_sat',
            'help'      : 'Specify the instrument and satellite ID for data.',
        }
    opts['--data-step'] = \
        {
            'action'    : 'store',
            'metavar'   : 'STEP_TYPE',
            'dest'      : 'data_step',
            'help'      : 'Specify the step/type for the data. "anl" and "ges" are allowed. If you wish to specify more than one, use a pipe to seperate them, e.g. "anl|ges".',
        }
    opts['--data-time-delta'] = \
        {
            'action'    : 'store',
            'metavar'   : 'TIME_DELTA',
            'dest'      : 'data_time_delta',
            'help'      : """Specify the time interval for data. The time format is
                             expressed using the sleep command's format, "#U", where # is
                             a number and U is a letter representing a unit of time.""",
        }

    add_args(parser, inherit, opts)

def add_dump_args(parser, inherit = False):
    opts = OrderedDict()
    opts['--dump-columns'] = \
        {
            'action'    : 'store',
            'metavar'   : 'COLUMNS',
            'dest'      : 'dump_columns',
            'help'      : 'Specify the columns to dump/use, separated by commas.',
        }
    opts['--dump-all-channels'] = \
        {
            'action'    : 'store_true',
            'dest'      : 'dump_all_channels',
            'help'      : 'Specify to dump all channels. Negates the option below specifying channels to use.',
        }
    opts['--dump-channels'] = \
        {
            'action'    : 'store',
            'metavar'   : 'CHANNELS',
            'dest'      : 'dump_channels',
            'help'      : 'Specify the channels to dump/use, separated by commas. Ranges are also acceptable.',
        }
    opts['--dump-assim-only'] = \
        {
            'action'    : 'store_true',
            'dest'      : 'dump_assim_only',
            'help'      : 'Specify to use only assimilated data (iuse = 1).',
        }
    opts['--dump-suppress-warnings'] = \
        {
            'action'    : 'store_true',
            'dest'      : 'dump_suppress_warnings',
            'help'      : 'Specify whether to suppress data warnings or not. This will hide important warnings about data inconsistencies, so only enable if you are 100%% sure that your data is valid!',
        }

    add_args(parser, inherit, opts)

def add_plot_args(parser, inherit = False):
    opts = OrderedDict()
    opts['--plot-define-plots'] = \
        {
            'action'    : 'append',
            'metavar'   : 'PLOTS',
            'dest'      : 'plot_define_plots',
            'help'      : 'Define plots. Uses the value list system, specified by "plot1,plot2,plot3,...".',
        }
    opts['--plot-define-subplots'] = \
        {
            'action'    : 'append',
            'metavar'   : 'SUBPLOTS',
            'dest'      : 'plot_define_subplots',
            'help'      : 'Define subplots. Uses the key-value pair system, specified by "plot1:subplot1,subplotid2,...;".',
        }
    opts['--plot-define-axes'] = \
        {
            'action'    : 'append',
            'metavar'   : 'AXES',
            'dest'      : 'plot_define_axes',
            'help'      : 'Define axes for the subplot. Uses the key-value pair system, specified by "plot1|subplot1|y:ticks=5,label="test";...".',
        }
    opts['--plot-define-data'] = \
        {
            'action'    : 'append',
            'metavar'   : 'DATA',
            'dest'      : 'plot_define_data',
            'help'      : 'Define data to be plotted in the subplot. Uses the key-value pair system, specified by "plot1|subplot1|x:data_field_1;plot1|subplot1|y:...".',
        }
    opts['--plot-define-title'] = \
        {
            'action'    : 'append',
            'metavar'   : 'TITLE',
            'dest'      : 'plot_define_title',
            'help'      : 'Define the title for the plot, and optionally, subplot and legend. Uses the key-value pair system, specified by "plot1:title;plot1|subplot1:title;plot1|subplot1|legend:title;...".',
        }
    opts['--plot-define-output'] = \
        {
            'action'    : 'append',
            'metavar'   : 'OUTPUT_FILE',
            'dest'      : 'plot_define_output',
            'help'      : 'Define the output file for the plot. Uses the key-value pair system, specified by "plot1:output_file.png;...".',
        }
    opts['--plot-define-settings'] = \
        {
            'action'    : 'append',
            'metavar'   : 'SETTINGS',
            'dest'      : 'plot_define_settings',
            'help'      : 'Define the settings for the plot. Uses the key-value pair system, specified by "plot1:target_size=595x700,dpi=50;...".',
        }
    opts['--plot-define-custom-vars'] = \
        {
            'action'    : 'append',
            'metavar'   : 'CUSTOM_VARS',
            'dest'      : 'plot_define_custom_vars',
            'help'      : 'Define the custom variables for use in the output file and title. Uses the key-value pair system, specified by "myvar:123,myvar2:abc,...".',
        }
    opts['--plot-make-dirs'] = \
        {
            'action'    : 'store_true',
            'dest'      : 'plot_make_dirs',
            'help'      : 'Make directories if the specified output path does not exist.',
        }

    add_args(parser, inherit, opts)

def add_config_args(parser, inherit = False):
    opts = OrderedDict()
    opts['--config-display'] = \
        {
            'action'    : 'store_true',
            'dest'      : 'config_display',
            'help'      : 'Displays the configuration.',
        }
    opts['--config-load'] = \
        {
            'action'    : 'store',
            'metavar'   : 'FILE',
            'dest'      : 'config_load',
            'help'      : 'Load an existing configuration file. Note that this will override the main --config-file argument.',
        }
    opts['--config-save'] = \
        {
            'action'    : 'store',
            'metavar'   : 'FILE',
            'dest'      : 'config_save',
            'help'      : 'Save the currently loaded configuration to a file. Note that saved configuration may not be placed in order.',
        }

    add_args(parser, inherit, opts)

def make_argparser():
    parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, \
                epilog = textwrap.dedent("""\
                  Logging levels, from least to most importance:
                    DEBUG, INFO, WARNING, ERROR, CRITICAL
                  Setting a logging level will show messages that meet and
                  exceed that level. For instance, setting INFO will show
                  INFO, WARNING, ERROR, and CRITICAL messages.

                  Priority modes:
                    DUMMYMP_GENEROUS   - Generous mode. Very conservative about using any
                                         CPU, and ensures that no one else is disrupted.
                                         Note that this is VERY GENEROUS - if all CPUs are
                                         taken, DummyMP will wait until there are
                                         available CPUs! (All other modes will run a
                                         single process, regardless of CPU usage.) This is
                                         the slowest mode!
                    DUMMYMP_NORMAL     - Normal mode. Careful not to take up too much
                                         resources on the CPU, but it will try to get
                                         things done. This is faster than GENEROUS, but it
                                         isn't the fastest. This mode is the default and
                                         is recommended for most conditions.
                    DUMMYMP_AGGRESSIVE - Aggressive mode. This mode considers other users,
                                         but it may spawn processes anyway depending on
                                         how other processes behave. This is faster than
                                         NORMAL, and is recommended for semi-important
                                         conditions.
                    DUMMYMP_EXTREME    - Extreme mode. This mode somewhat considers other
                                         users, but unless the other processes are using
                                         a significant portion of the CPU, it will spawn
                                         spawn processes anyway. This is faster than
                                         AGGRESSIVE, and is recommended for important
                                         conditions.
                    DUMMYMP_NUCLEAR    - Nuclear mode. This mode does NOT consider other
                                         users, and just runs as many processes as it can
                                         allow (total number of cores). This is much
                                         faster than EXTREME, and is recommended for
                                         really important conditions. Note that this may
                                         earn you very angry co-workers knocking down your
                                         door with pitchforks, so use sparingly!

                  Quick Start Examples:
                    List data available:
                      %(prog)s --config-file=config.yaml list
                    Dump data:
                      %(prog)s --config-file=config.yaml dump
                    Make plots:
                      %(prog)s --config-file=config.yaml plot
                    Print configuration:
                      %(prog)s --config-file=config.yaml config
                    Make plots and log output:
                      %(prog)s --config-file=config.yaml --logging-output="stdout,file" \\
                               --logging-file="mylog.txt" plot
                  """),
                version = 'PyRadmon v' + __version__) # Old: %(prog)s evals to pyradmon.py

    subparsers = parser.add_subparsers(metavar="verb", dest = "verb", help='Description')

    main_opts = OrderedDict()
    main_opts['--config-file'] = \
        {
            'action'    : 'store',
            'dest'      : 'config_file',
            'metavar'   : 'FILE',
            'help'      : 'Load a configuration file for PyRadmon to use. Synonymous to --config-load, but for all verbs and options.',
        }
    main_opts['--config-unset'] = \
        {
            'action'    : 'append',
            'dest'      : 'config_unset',
            'metavar'   : 'VARS',
            'help'      : 'Unset (or remove) variables after all configuration settings (config file and command line) have been loaded. Format for VARS is "VARIABLE1;VARIABLE2;...". For core PyRadmon configuration, the variable syntax is "config.key". For plot configuration, the variable syntax follows the plot argument hierarchy format at any level, e.g. "plot|subplot|attr|subattr", "plot|subplot", or even "plot". (See plot help for more details regarding the plot hierarchy format.) Note that removing certain variables can cause PyRadmon to not run.',
        }
    main_opts['--logging-output'] = \
        {
            'action'    : 'store',
            'metavar'   : 'OUTPUT',
            'dest'      : 'logging_output',
            'help'      : 'Specify where to output to. Options include file, stdout, and stderr. Multiple outputs can be specified, seperated with a comma.',
        }
    main_opts['--logging-file'] = \
        {
            'action'    : 'store',
            'metavar'   : 'FILE',
            'dest'      : 'logging_file',
            'help'      : 'If outputting to a file, specify the file path to save to.',
        }
    main_opts['--logging-level'] = \
        {
            'action'    : 'store',
            'metavar'   : 'LOG_LEVEL',
            'dest'      : 'logging_level',
            'help'      : 'Set the logging level for PyRadmon.',
        }
    main_opts['--mp-disable'] = \
        {
            'action'    : 'store_true',
            'dest'      : 'mp_disable',
            'help'      : 'Disable multiprocessing (mp) optimizations in PyRadmon.',
        }
    main_opts['--mp-priority-mode'] = \
        {
            'action'    : 'store',
            'metavar'   : 'PRIORITY_MODE',
            'dest'      : 'mp_priority_mode',
            'help'      : 'Set the priority mode for the multiprocessing (mp) optimizations in PyRadmon. Options are GENEROUS, NORMAL, AGGRESSIVE, EXTREME, and NUCLEAR. GENEROUS yields to other CPU hungry processes, while NUCLEAR spawns as many processes as it can regardless of CPU usage.',
        }
    main_opts['--mp-cpu-limit'] = \
        {
            'action'    : 'store',
            'metavar'   : 'NUM_CPUS',
            'dest'      : 'mp_cpu_limit',
            'help'      : 'Limit the number of CPUs that the multiprocessing (mp) optimizations in PyRadmon can use.',
        }

    add_args(parser, False, main_opts)

    # A list command
    list_parser = subparsers.add_parser('list', help='Lists the data set available for use.', \
        description = 'Lists the data set available for use.',
        epilog = textwrap.dedent("""\
                 For --data-time-delta:
                   Available time units (case-sensitive):
                     s: seconds    m: minutes    h: hours    d: days
                     w: weeks      M: months     y: years
                   For instance, to specify 5 months, 3 minutes, 2 seconds:
                     "5M 3m 2s"

                   Multiple elements with same time units will be summed up,
                   regardless of position or order. "3m 2s 5m" == "8m 2s"

                   Years is not a native time delta, so this uses the
                   conversion "1 year = 365 days".

                   Note that specifying years may have some caveats, see:
                     http://stackoverflow.com/a/765990
                 """), \
                 formatter_class=argparse.RawDescriptionHelpFormatter)
    add_list_args(list_parser, False)

    # [dump]
    dump_parser = subparsers.add_parser('dump', help='Dumps data from the data set.', \
        description = textwrap.dedent("""\
        Dumps data from the data set.

        Inherits arguments from [list]. [list] arguments may be required to use
        [dump]. For information on [list] arguments, see the [list] help.
        """), \
        formatter_class=argparse.RawDescriptionHelpFormatter)
    add_list_args(dump_parser, True)
    add_dump_args(dump_parser, False)

    # [plot]
    plot_parser = subparsers.add_parser('plot', help='Creates a plot given plot parameters.', \
        description = textwrap.dedent("""\
        Creates a plot given plot parameters.

        Inherits arguments from [list] and [dump]. [list] and [dump] arguments
        may be required to use [plot]. For information on [list] and [dump]
        arguments, see their respective help.

        NOTE: These options are advanced - although you could (potentially)
              plot using these options, it would probably be very painful!
              All of these options can be defined via config file, which is
              much easier and less verbose! These options are meant to be
              used in conjunction with a config file for overriding certain
              configuration options and testing them.

        """), \
        epilog = textwrap.dedent("""\
        Definitions follow either a simple value list system or a simple
        key-value pair system.

        Value List System:
          The value list system looks like:
          "value1,value2,value3,..."

          For the value list system, values are separated with commas.

        Key-Value Pair System:
          The key-value pair system looks like:
          "key1:value1,value2;key2:value3,value4,..."

          For the key-value pair system, a key is followed by a colon,
          values are separated with commas, and key-value pairs are
          separated by semicolons.

          If settings are being set, values can look like subkey=value.
          It is a pair with a sub-key and a sub-value, separated by an
          equal sign.
          These are called sub-key-value pairs, and are in place of values
          in a key-value system.

          They can look like this:
          "key1:skey1=sval1,skey2=sval2;..."

        Key/Value Naming:
          Plots and subplots are indicated above with plot# and subplot#,
          respectively. They are simply IDs for the plots and subplots.
          You define them with --plot-define-plots and --plot-define-subplots.

          They can take on any name - for instance:
            --plot-define-plots="a,b" --plot-define-subplots="a:1,2;b:3,4"

          Hierarchy is done by starting with the highest hierarchy, and then
          adding additional lower levels to the right, sepearated by pipes.
          For instance:
            high|medium|low

          In the case of plots and subplots, the hierarchy is as follows:
            plot|subplot|attribute

          This is the naming scheme for keys in key/value pairs.

        Argument Definitions:
          Note that arguments can be specified multiple times to reduce
          the length of one argument. For instance:

            --plot-define-plots="plot1" --plot-define-plots="plot2"
          is the same as
            --plot-define-plots="plot1,plot2"

          This works regardless of argument order. This is encouraged, since
          this helps with argument organization. (In particular, arguments
          deals with a specific plot or subplot can be grouped together.)

          --plot-define-plots
            Value list of plot IDs.

            This argument is REQUIRED to produce a plot.

            Example:
              "plot1,abc2,superplot3"

          --plot-define-subplots
            Key-value pairs of plot IDs and subplot IDs.

            This argument is REQUIRED to produce a plot.

            Example (using above plot IDs):
              "plot1:sub1,sub2;abc2:abc,def;superplot3:s1,s2"

          --plot-define-axes
            Key-value pairs of plot/subplot IDs, and axes properties
            defined as sub-key-value pairs. This is the first argument to
            use key hierarchy naming.

            Available hierarchy attributes:
              plot|subplot|x
                X axis settings.
              plot|subplot|y
                Y axis settings.

            Available attributes (sub-key-value pairs):
              ticks=#
                Define number of ticks.
              label=LABEL
                Define the axis label.

            Example (using above info):
              "plot1|sub1|x:ticks=5,label=Hello world"

          --plot-define-data
            Key-value pairs of plot/subplot IDs, with data fields as
            values. This also uses key hierarchy naming.

            This argument is REQUIRED to produce a plot.

            Available hierarchy attributes:
              plot|subplot|x
                X plotting settings.
              plot|subplot|y
                Y plotting settings.

            Values:
              Data field elements. Specified using a different hierarchy
              system:
                STEP/TYPE|FIELD

              STEP/TYPE is either "ges" or "anl", but not both.

              For instance: ges|bc_total|mean

            Example (using above info):
              "abc2|abc|x:timestamp;abc2|abc|y:ges|bc_total|mean,ges|bc_total|stddev"

          --plot-define-title
            Key-value pairs of plot/subplot IDs, with titles as values. This
            also uses key hierarchy naming, but in a slightly different way.

            Available hierarchy attributes:
              plot|title
                Title for the whole plot.
              plot|subplot|title
                Title for the subplot.
              plot|subplot|legend
                Title for the subplot's legend.

            Values:
              The title for the specified title attribute.

            Example (using above info):
              "abc2|title:Title;abc2|abc|title:SubTitle;abc2|abc|legend:LegendTitle"
          --plot-define-output
            Key-value pairs of plot and output paths.

            Example (using above info):
              "plot1:myplot1.png;abc2:abcplot.png;superplot3:super.png"
          --plot-define-settings
            Key-value pairs of plot IDs, and settings defined as
            sub-key-value pairs.

            This argument is REQUIRED to produce a plot.

            Available attributes (sub-key-value pairs):
              target_size=#x#
                Define the output plot target size.
              dpi=#
                Define the output plot DPI.

            Example (using above info):
              "plot1:target_size=595x700,dpi=50"
          --plot-define-custom-vars
            Key-value pairs of custom variables to be used in the plot
            title and output file name. Variables are case insensitive.

            The suggested variable definition and usage standard is
            using lowercase for variable definition, and uppercase for
            variable usage in the title and/or output file name.

            Example:
              "expid:exp_2;author:theauthor"

              Applying custom variables to plot title and output file name:
                --plot-define-title  "plot1:Experiment %EXPID% - By %AUTHOR%"
                  Result:
                    Experiment exp_2 - By theauthor
                --plot-define-output "plot1:plot_%EXPID%-%AUTHOR%.png"
                  Result:
                    plot_exp_2-theauthor.png
          --plot-make-dirs
            If specified, automatically make non-existent directories,
            as needed. No additional arguments or options needed.

        NOTE: These options are advanced - although you could (potentially)
              plot using these options, it would probably be very painful!
              All of these options can be defined via config file, which is
              much easier and less verbose! These options are meant to be
              used in conjunction with a config file for overriding certain
              configuration options and testing them.
        """),
        formatter_class=argparse.RawDescriptionHelpFormatter)

    add_list_args(plot_parser, True)
    add_dump_args(plot_parser, True)
    add_plot_args(plot_parser, False)

    # [config]
    config_parser = subparsers.add_parser('config', help='Displays, loads, and saves the configuration.', \
        description = textwrap.dedent("""\
        Displays, loads, and saves the configuration.

        Inherits arguments from [list], [dump], and [plot]. [list], [dump],
        and [plot] arguments may be required to use [config]. For information
        on [list], [dump], or [plot] arguments, see their respective help.
        """), \
        formatter_class=argparse.RawDescriptionHelpFormatter)
    add_list_args(config_parser, True)
    add_dump_args(config_parser, True)
    add_plot_args(config_parser, True)
    add_config_args(config_parser, False)

    return parser

def parse_to_config(parse):
    # Init a few variables:
    pyradmon_config = {}
    plot_dict = {}

    ## Core args
    # First, examine the core arguments.
    if isset_obj("config_file", parse):
        # OK, check if the file exists.
        if os.path.isfile(parse.config_file):
            # Attempt to load
            res = config.load(parse.config_file)

            if res == None:
                print "ERROR: Could not open configuration file!"
                return (None, None, None)

            pyradmon_config = res[0]
            plot_dict = res[1]
        else:
            print "ERROR: Configuration file path does not exist!"
            return (None, None, None)

        # Validate configuration
        config.validate(pyradmon_config, plot_dict)

    # Now check for logging args!
    file_enabled = False

    if isset_obj("logging_output", parse):
        logging_output = parse.logging_output

        if logging_output != "":
            logging_output = logging_output.split(",")
            logging_output = [x.strip() for x in logging_output]

            final_logging_output = []

            for log_o in logging_output:
                if log_o == 'file':
                    file_enabled = True
                elif log_o == 'stdout':
                    final_logging_output.append(sys.stdout)
                elif log_o == 'stderr':
                    final_logging_output.append(sys.stderr)
                else:
                    print "ERROR: Invalid logging output! Valid output: stdout, stderr, file"
                    return (None, None, None)
            logging_output = final_logging_output
    else:
        logging_output = [ sys.stdout ]

    if logging_output and file_enabled and isset_obj("logging_file", parse):
        logging_file = parse.logging_file
    else:
        logging_file = None

    if isset_obj("logging_level", parse):
        logging_level = parse.logging_level
        logging_level = logging_level.strip()
        if logging_level == "INFO":
            logging_level = logging.INFO
        elif logging_level == "WARNING":
            logging_level = logging.WARNING
        elif logging_level == "ERROR":
            logging_level = logging.ERROR
        elif logging_level == "CRITICAL":
            logging_level = logging.CRITICAL
        elif logging_level == "DEBUG":
            logging_level = logging.DEBUG
        else:
            print "ERROR: Invalid logging level specified!"
            print "Valid levels: INFO, WARNING, ERROR, CRITICAL, DEBUG"
            return (None, None, None)
    else:
        logging_level = logging.INFO

    if isset_obj("mp_disable", parse):
        pyradmon_config['mp_disable'] = parse.mp_disable

    if isset_obj("mp_priority_mode", parse):
        mp_priority_mode = parse.mp_priority_mode
        mp_priority_mode = mp_priority_mode.strip()
        if mp_priority_mode == "GENEROUS":
            pyradmon_config['mp_priority_mode'] = "GENEROUS"
        elif mp_priority_mode == "NORMAL":
            pyradmon_config['mp_priority_mode'] = "NORMAL"
        elif mp_priority_mode == "AGGRESSIVE":
            pyradmon_config['mp_priority_mode'] = "AGGRESSIVE"
        elif mp_priority_mode == "EXTREME":
            pyradmon_config['mp_priority_mode'] = "EXTREME"
        elif mp_priority_mode == "NUCLEAR":
            pyradmon_config['mp_priority_mode'] = "NUCLEAR"
        else:
            print "ERROR: Invalid multiprocessing (mp) priority mode specified!"
            print "Valid levels: GENEROUS, NORMAL, AGGRESSIVE, EXTREME, NUCLEAR"
            return (None, None, None)
    else:
        pyradmon_config['mp_priority_mode'] = "NORMAL"

    if isset_obj("mp_cpu_limit", parse):
        if (parse.mp_cpu_limit).isdigit():
            pyradmon_config['mp_cpu_limit'] = int(parse.mp_cpu_limit)
        else:
            print "ERROR: Invalid multiprocessing (mp) CPU limit! The CPU limit"
            print "must specify an integer number of CPUs to limit use to."
            return (None, None, None)

    # We're ready - let's set up logging!
    logger = log.init(logging_level, logging_output, logging_file)

    # From now on, we'll stick to using the log module to print stuff
    # out.

    ## Config args, part 1
    if parse.verb == "config":
        # We will only read --config-load here. All others will be
        # checked at the end.
        if isset_obj("config_load", parse):
            if isset_obj("config_file", parse):
                warn("Detected --config-load when --config-file is already specified! --config-load will override the configuration file specified in --config-file. You should only specify one argument, preferrably --config-file.")

            # OK, check if the file exists.
            if os.path.isfile(parse.config_load):
                # Attempt to load
                res = config.load(parse.config_load)

                if res == None:
                    critical("ERROR: Could not open configuration file!")
                    return (None, None, None)

                pyradmon_config = res[0]
                plot_dict = res[1]
            else:
                critical("ERROR: Configuration file path does not exist!")
                return (None, None, None)

            # Validate configuration
            config.validate(pyradmon_config, plot_dict)

    ## Plot args
    # FUN TIME

    if parse.verb == "plot" or parse.verb == "config":
        if isset_obj("plot_define_plots", parse):
            plots = ",".join(parse.plot_define_plots).split(",")
            # Cleanup
            plots = [x.strip() for x in plots]

            for plot in plots:
                if not plot in plot_dict:
                    if plot == "":
                        warn("Invalid plot ID detected - plot ID can't be blank!")
                        warn("This plot definition will be skipped.")
                        continue
                    plot_dict[plot] = {}

        if isset_obj("plot_define_subplots", parse):
            # "plot1:sub1,sub2;abc2:abc,def;superplot3:s1,s2"
            subplots_def = ";".join(parse.plot_define_subplots).split(";")
            # Cleanup
            subplots_def = [x.strip() for x in subplots_def]
            for subplot_def in subplots_def:
                # Chunk: plot1:sub1,sub2
                subplot_def_split = subplot_def.split(":")
                subplot_def_split = [x.strip() for x in subplot_def_split]

                # SAAAAAAAANITY CHECK!!!!!!!1111

                # Sanity check 1: do we have 2 elements?
                if len(subplot_def_split) != 2:
                    warn("Invalid subplot definition detected - invalid key-value pair '%s'!" % subplot_def)
                    warn("(Key-value pair should be key:value - make sure there are no extra colons!)")
                    warn("This subplot definition will be skipped.")
                    continue

                # OK, now seperate it out!
                subplot_def_plot = subplot_def_split[0]
                subplot_def_subplots = subplot_def_split[1]

                # Sanity check 2: does the plot named exist?!?
                if not subplot_def_plot in plot_dict:
                    warn("Invalid subplot definition detected - the plot specified, '%s', does not exist!" % subplot_def_plot)
                    warn("Ensure spelling is correct. If it is a new plot, make sure it is defined.")
                    warn("This subplot definition will be skipped.")
                    continue

                # OK, let's process subplots.
                subplot_def_subplots = subplot_def_subplots.split(",")
                subplot_def_subplots = [x.strip() for x in subplot_def_subplots]

                # Prep plot_dict
                if not "plots" in plot_dict[subplot_def_plot]:
                    plot_dict[subplot_def_plot]["plots"] = []

                # Add away!
                for subplot_def_subplot in subplot_def_subplots:
                    plot_dict[subplot_def_plot]["plots"].append({ subplot_def_subplot : {} })

                # Done!

        if isset_obj("plot_define_axes", parse):
            # "plot1|sub1|x:ticks=5,label=Hello world"
            axes_def = ";".join(parse.plot_define_axes).split(";")
            # Cleanup
            axes_def = [x.strip() for x in axes_def]
            for axis_def in axes_def:
                # Chunk: plot1|sub1|x:ticks=5,label=Hello world
                axis_def_split = axis_def.split(":")
                axis_def_split = [x.strip() for x in axis_def_split]

                # SAAAAAAAANITY CHECK!!!!!!!1111

                # Sanity check 1: do we have 2 elements?
                if len(axis_def_split) != 2:
                    warn("Invalid axis definition detected - invalid key-value pair '%s'!" % axis_def)
                    warn("(Key-value pair should be key:value - make sure there are no extra colons!)")
                    warn("This axis definition will be skipped.")
                    continue

                # OK, now seperate it out!
                # Chunk: plot1|sub1|x --> [plot1, sub1, x]
                axis_def_plot_subplot_axis = axis_def_split[0].split("|")
                # Chunk: ticks=5,label=Hello world
                axis_def_attrs = axis_def_split[1]

                # Sanity check 2: does the plot/subplot/axe key have 3 elements?
                if len(axis_def_plot_subplot_axis) != 3:
                    warn("Invalid axis definition detected - the key is invalid! It should only have")
                    warn("3 elements - plot|subplot|x/y!")
                    warn("This axis definition will be skipped.")
                    continue

                # OK, let's seperate that out!
                axis_def_plot = axis_def_plot_subplot_axis[0]
                axis_def_subplot = axis_def_plot_subplot_axis[1]
                axis_def_axis = axis_def_plot_subplot_axis[2].lower()

                # Sanity check 3: does the plot/subplot named exist?!?
                if not axis_def_plot in plot_dict:
                    warn("Invalid axis definition detected - the plot specified, '%s', does not exist!" % axis_def_plot)
                    warn("Ensure spelling is correct. If it is a new plot, make sure it is defined.")
                    warn("This axis definition will be skipped.")
                    continue

                # OK, plot exists. How about subplot?
                # We have to do some strange magic here...
                axis_def_subplot_found = False
                axis_def_subplot_dat = None
                for axis_def_subplot_dict in plot_dict[axis_def_plot]['plots']:
                    if axis_def_subplot in axis_def_subplot_dict:
                        axis_def_subplot_dat = axis_def_subplot_dict[axis_def_subplot]
                        axis_def_subplot_found = True
                        break

                if not axis_def_subplot_found:
                    warn("Invalid axis definition detected - the subplot specified, '%s', does not exist!" % axis_def_subplot)
                    warn("Ensure spelling is correct. If it is a new subplot, make sure it is defined and")
                    warn("in the right subplot. This axis definition will be skipped.")
                    continue

                # Sanity check 4: Is the axis valid?
                if axis_def_axis != "x" and axis_def_axis != "y":
                    warn("Invalid axis definition detected - the axis specified, '%s', is invalid!" % axis_def_axis)
                    warn("'x' and 'y' are the only axes allowed. This axis definition will be skipped.")
                    continue

                # OK, let's setup shop.
                if not "axes" in axis_def_subplot_dat:
                    axis_def_subplot_dat["axes"] = {}

                if not axis_def_axis in axis_def_subplot_dat["axes"]:
                    axis_def_subplot_dat["axes"][axis_def_axis] = {}

                # OK, let's process attributes.
                axis_def_attrs = axis_def_attrs.split(",")
                axis_def_attrs = [x.strip().split("=") for x in axis_def_attrs]

                # Sanity check 5: Are these valid key-value pairs?
                kvpair_bad = False
                for kvpair in axis_def_attrs:
                    if len(kvpair) != 2:
                        warn("Invalid axis definition detected - the key/value subpair, '%s', is invalid!" % '='.join(kvpair))
                        kvpair_bad = True
                    if type(kvpair[0]) != str:
                        warn("Invalid axis definition detected - the key '%s' in the subpair, '%s', is a non-string!" % (str(kvpair[0]), '='.join(kvpair)))

                if kvpair_bad:
                    warn("(Key-value subpair should be key=value - make sure there are no extra =s!)")
                    warn("This axis definition will be skipped.")
                    continue

                # Whew, so much sanity lost from sanity checking!

                # Install attributes!
                for kvpair in axis_def_attrs:
                    if kvpair[0] == 'ticks':
                        axis_def_subplot_dat["axes"][axis_def_axis][kvpair[0]] = int(kvpair[1])
                    else:
                        axis_def_subplot_dat["axes"][axis_def_axis][kvpair[0]] = kvpair[1]

                # Done!!!!!1111

        if isset_obj("plot_define_data", parse):
            # "abc2|abc|x:timestamp;abc2|abc|y:ges|bc_total|mean,ges|bc_total|stddev"
            data_defs = ";".join(parse.plot_define_data).split(";")
            # Cleanup
            data_defs = [x.strip() for x in data_defs]
            for data_def in data_defs:
                # Chunk: abc2|abc|x:timestamp
                # Chunk: abc2|abc|y:ges|bc_total|mean,ges|bc_total|stddev
                data_def_split = data_def.split(":")
                data_def_split = [x.strip() for x in data_def_split]

                # SAAAAAAAANITY CHECK!!!!!!!1111

                # Sanity check 1: do we have 2 elements?
                if len(data_def_split) != 2:
                    warn("Invalid data definition detected - invalid key-value pair '%s'!" % data_def)
                    warn("(Key-value pair should be key:value - make sure there are no extra colons!)")
                    warn("This data definition will be skipped.")
                    continue

                # OK, now seperate it out!
                # Chunk: abc2|abc|x --> [abc2, abc, x]
                data_def_plot_subplot_attr = data_def_split[0].split("|")
                # Chunk: timestamp
                data_def_attrs = data_def_split[1]

                # Sanity check 2: does the plot/subplot/axe key have 3 elements?
                if len(data_def_plot_subplot_attr) != 3:
                    warn("Invalid data definition detected - the key is invalid! It should only have")
                    warn("3 elements - plot|subplot|x/y!")
                    warn("This data definition will be skipped.")
                    continue

                # OK, let's seperate that out!
                data_def_plot = data_def_plot_subplot_attr[0]
                data_def_subplot = data_def_plot_subplot_attr[1]
                data_def_attr_name = data_def_plot_subplot_attr[2].lower()

                # Sanity check 3: does the plot/subplot named exist?!?
                if not data_def_plot in plot_dict:
                    warn("Invalid data definition detected - the plot specified, '%s', does not exist!" % data_def_plot)
                    warn("Ensure spelling is correct. If it is a new plot, make sure it is defined.")
                    warn("This data definition will be skipped.")
                    continue

                # OK, plot exists. How about subplot?
                # We have to do some strange magic here...
                data_def_subplot_found = False
                data_def_subplot_dat = None
                for data_def_subplot_dict in plot_dict[data_def_plot]['plots']:
                    if data_def_subplot in data_def_subplot_dict:
                        data_def_subplot_dat = data_def_subplot_dict[data_def_subplot]
                        data_def_subplot_found = True
                        break

                if not data_def_subplot_found:
                    warn("Invalid data definition detected - the subplot specified, '%s', does not exist!" % data_def_subplot)
                    warn("Ensure spelling is correct. If it is a new subplot, make sure it is defined and")
                    warn("in the right subplot. This data definition will be skipped.")
                    continue

                # Sanity check 4: Is the attr field valid?
                valid_attrs = [ "x", "y", "colors", "labels" ]
                if not data_def_attr_name in valid_attrs:
                    warn("Invalid data definition detected - the attribute specified, '%s', is invalid!" % data_def_data)
                    warn("%s are the only attributes allowed. This data definition will be skipped." % (",".join(valid_attrs[:-1]) + ", and " + valid_attrs[-1]))
                    continue

                # OK, let's setup shop.
                if not "data" in data_def_subplot_dat:
                    data_def_subplot_dat["data"] = {}

                # OK, let's process attributes.
                data_def_attrs = data_def_attrs.split(",")

                # Whew, so much sanity lost from sanity checking!
                # (But not as bad as the axes part...)

                # Install attributes!
                if len(data_def_attrs) == 1:
                    data_def_subplot_dat["data"][data_def_attr_name] = data_def_attrs[0]
                else:
                    if not data_def_attr_name in data_def_subplot_dat["data"]:
                        data_def_subplot_dat["data"][data_def_attr_name] = []
                    for attr_val in data_def_attrs:
                        data_def_subplot_dat["data"][data_def_attr_name].append(attr_val)

                # Done!

        if isset_obj("plot_define_title", parse):
            # "abc2|title:Title;abc2|abc|title:SubTitle;abc2|abc|legend:LegendTitle"
            title_defs = ";".join(parse.plot_define_title).split(";")
            # Cleanup
            title_defs = [x.strip() for x in title_defs]
            for title_def in title_defs:
                # Chunk: abc2|title:Title
                # Chunk: abc2|abc|title:SubTitle
                # Chunk: abc2|abc|legend:LegendTitle
                title_def_split = title_def.split(":")
                title_def_split = [x.strip() for x in title_def_split]

                # SAAAAAAAANITY CHECK!!!!!!!1111

                # Sanity check 1: do we have 2 elements?
                if len(title_def_split) != 2:
                    warn("Invalid title definition detected - invalid key-value pair '%s'!" % title_def)
                    warn("(Key-value pair should be key:value - make sure there are no extra colons!)")
                    warn("This title definition will be skipped.")
                    continue

                # OK, now seperate it out!
                # Chunk: abc2|title      --> [abc2, title]
                # Chunk: abc2|abc|title  --> [abc2, abc, title]
                # Chunk: abc2|abc|legend --> [abc2, abc, legend]
                title_def_plot_subplot_attr = title_def_split[0].split("|")
                # Chunk: Title
                # Chunk: SubTitle
                # Chunk: LegendTitle
                title_def_title = title_def_split[1]

                # Sanity check 2: does the plot(/subplot)/attr key have 2 or 3 elements?
                if (len(title_def_plot_subplot_attr) != 3) and (len(title_def_plot_subplot_attr) != 2):
                    warn("Invalid title definition detected - the key is invalid! It should only have")
                    warn("2-3 elements - plot|title or plot|subplot|title/legend!")
                    warn("This title definition will be skipped.")
                    continue

                # OK, let's seperate that out!
                # ...except this varies, so let's take it a bit slow.

                title_def_plot_subplot = [ title_def_plot_subplot_attr[0] ]

                if len(title_def_plot_subplot_attr) == 3:
                    title_def_plot_subplot.append(title_def_plot_subplot_attr[1])

                title_def_attr_name = title_def_plot_subplot_attr[-1].lower()

                # Sanity check 3: does the plot/subplot named exist?!?
                if not title_def_plot_subplot[0] in plot_dict:
                    warn("Invalid title definition detected - the plot specified, '%s', does not exist!" % title_def_plot)
                    warn("Ensure spelling is correct. If it is a new plot, make sure it is defined.")
                    warn("This title definition will be skipped.")
                    continue

                # OK, plot exists. How about subplot?
                # We have to do some strange magic here...
                # ...but only if we need to.

                if len(title_def_plot_subplot) == 2:
                    title_def_subplot_found = False
                    title_def_subplot_dat = None
                    for title_def_subplot_dict in plot_dict[title_def_plot_subplot[0]]['plots']:
                        if title_def_plot_subplot[1] in title_def_subplot_dict:
                            title_def_subplot_dat = title_def_subplot_dict[title_def_plot_subplot[1]]
                            title_def_subplot_found = True
                            break

                    if not title_def_subplot_found:
                        warn("Invalid title definition detected - the subplot specified, '%s', does not exist!" % title_def_subplot)
                        warn("Ensure spelling is correct. If it is a new subplot, make sure it is defined and")
                        warn("in the right subplot. This title definition will be skipped.")
                        continue

                # Sanity check 4: Is the attr field valid?
                # Title is valid for both, but legend is only valid for
                # plot|subplot.
                if title_def_attr_name != "title" and not ( (len(title_def_plot_subplot) == 2) and (title_def_attr_name == "legend") ):
                    warn("Invalid title definition detected - the attribute specified, '%s', is invalid!" % title_def_title)
                    warn("legend (for plot|subplot) and title are the only attributes allowed.")
                    warn("This title definition will be skipped.")
                    continue

                # OK, let's go!
                if len(title_def_plot_subplot) == 1:
                    plot_dict[title_def_plot_subplot[0]]["title"] = title_def_title
                else:
                    if title_def_attr_name == "legend":
                        if not isset_obj("legend", title_def_subplot_dat):
                            title_def_subplot_dat["legend"] = {}
                        title_def_subplot_dat["legend"]["title"] = title_def_title
                    else:
                        title_def_subplot_dat["title"] = title_def_title

                # Done!

        if isset_obj("plot_define_output", parse):
            # "plot1:myplot1.png;abc2:abcplot.png;superplot3:super.png"
            output_defs = ";".join(parse.plot_define_output).split(";")
            # Cleanup
            output_defs = [x.strip() for x in output_defs]
            for output_def in output_defs:
                # Chunk: plot1:myplot1.png
                output_def_split = output_def.split(":")
                output_def_split = [x.strip() for x in output_def_split]

                # SAAAAAAAANITY CHECK!!!!!!!1111

                # Sanity check 1: do we have 2 elements?
                if len(output_def_split) != 2:
                    warn("Invalid output definition detected - invalid key-value pair '%s'!" % output_def)
                    warn("(Key-value pair should be key:value - make sure there are no extra colons!)")
                    warn("This output definition will be skipped.")
                    continue

                # OK, now seperate it out!
                # Chunk: plot1
                output_def_plot = output_def_split[0]
                # Chunk: myplot1.png
                output_def_output = output_def_split[1]

                # Sanity check 2: does the plot named exist?!?
                if not output_def_plot in plot_dict:
                    warn("Invalid output definition detected - the plot specified, '%s', does not exist!" % output_def_plot)
                    warn("Ensure spelling is correct. If it is a new plot, make sure it is defined.")
                    warn("This output definition will be skipped.")
                    continue

                # OK, plot exists. This is super easy, so we're free to
                # fly from here!
                plot_dict[output_def_plot]["output"] = output_def_output

                # Done!

        if isset_obj("plot_define_settings", parse):
            # "plot1:target_size=595x700,dpi=50"
            settings_def = ";".join(parse.plot_define_settings).split(";")
            # Cleanup
            settings_def = [x.strip() for x in settings_def]
            for settings_def in settings_def:
                # Chunk: plot1:target_size=595x700,dpi=50
                settings_def_split = settings_def.split(":")
                settings_def_split = [x.strip() for x in settings_def_split]

                # SAAAAAAAANITY CHECK!!!!!!!1111

                # Sanity check 1: do we have 2 elements?
                if len(settings_def_split) != 2:
                    warn("Invalid settings definition detected - invalid key-value pair '%s'!" % settings_def)
                    warn("(Key-value pair should be key:value - make sure there are no extra colons!)")
                    warn("This settings definition will be skipped.")
                    continue

                # OK, now seperate it out!
                # Chunk: plot1
                settings_def_plot = settings_def_split[0]
                # Chunk: ticks=5,label=Hello world
                settings_def_attrs = settings_def_split[1]

                # Sanity check 2: does the plot/subplot named exist?!?
                if not settings_def_plot in plot_dict:
                    warn("Invalid settings definition detected - the plot specified, '%s', does not exist!" % settings_def_plot)
                    warn("Ensure spelling is correct. If it is a new plot, make sure it is defined.")
                    warn("This settings definition will be skipped.")
                    continue

                # OK, let's setup shop.
                if not "settings" in plot_dict[settings_def_plot]:
                    plot_dict[settings_def_plot]["settings"] = {}

                # OK, let's process attributes.
                settings_def_attrs = settings_def_attrs.split(",")
                settings_def_attrs = [x.strip().split("=") for x in settings_def_attrs]

                # Sanity check 5: Are these valid key-value pairs?
                kvpair_bad = False
                for kvpair in settings_def_attrs:
                    if len(kvpair) != 2:
                        warn("Invalid settings definition detected - the key/value subpair, '%s', is invalid!" % '='.join(kvpair))
                        kvpair_bad = True
                    if type(kvpair[0]) != str:
                        warn("Invalid settings definition detected - the key '%s' in the subpair, '%s', is a non-string!" % (str(kvpair[0]), '='.join(kvpair)))

                if kvpair_bad:
                    warn("(Key-value subpair should be key=value - make sure there are no extra =s!)")
                    warn("This settings definition will be skipped.")
                    continue

                # Whew, so much sanity lost from sanity checking!

                # Install attributes!
                for kvpair in settings_def_attrs:
                    if kvpair[0] == 'target_size':
                        size_arr = [ int(x) for x in kvpair[1].lower().split("x") ]
                        if len(size_arr) != 2:
                            warn("Key-value pair for target_size is invalid - should be INTxINT!")
                            warn("Skipping key-value pair.")
                            continue
                        plot_dict[settings_def_plot]["settings"]["target_size"] = size_arr
                    elif kvpair[0] == 'dpi':
                        if not kvpair[1].isdigit():
                            warn("Key-value pair for dpi is invalid - value is not an int!")
                            warn("Skipping key-value pair.")
                            continue
                        plot_dict[settings_def_plot]["settings"][kvpair[0]] = int(kvpair[1])
                    else:
                        # Strange stuff
                        warn("Key '%s' in not defined - setting anyway." % str(kvpair[0]))
                        plot_dict[settings_def_plot]["settings"][kvpair[0]] = kvpair[1]

                # Done!!!!!1111
        if isset_obj("plot_define_custom_vars", parse):
            # "customvar1:value1;customvar2:value2"
            custom_var_defs = ";".join(parse.plot_define_custom_vars).split(";")
            # Cleanup
            custom_var_defs = [x.strip() for x in custom_var_defs]
            for output_def in output_defs:
                # Chunk: customvar1:value1
                custom_var_def_split = custom_var_def.split(":")
                custom_var_def_split = [x.strip() for x in custom_var_def_split]

                # Sanity check!

                # Sanity check 1: do we have 2 elements?
                if len(custom_var_def_split) != 2:
                    warn("Invalid custom variable definition detected - invalid key-value pair '%s'!" % output_def)
                    warn("(Key-value pair should be key:value - make sure there are no extra colons!)")
                    warn("This custom variable definition will be skipped.")
                    continue

                # OK, now seperate it out!
                # Chunk: customvar1
                custom_var_def_var = custom_var_def_split[0]
                # Chunk: value1
                custom_var_def_val = custom_var_def_split[1]

                # OK, we got everything. This is super easy, so we're free to
                # leap from here!
                if "custom_vars" not in pyradmon_config:
                    pyradmon_config["custom_vars"] = {}
                pyradmon_config["custom_vars"][custom_var_def_var] = custom_var_def_val

                # Done!
        if isset_obj("plot_make_dirs", parse) and parse.plot_make_dirs:
            pyradmon_config["make_dirs"] = parse.plot_make_dirs

            # Done!

    ## Dump args
    if parse.verb == "dump" or parse.verb == "plot" or parse.verb == "config":
        # --dump-columns
        if isset_obj("dump_columns", parse):
            for data_column in (parse.dump_columns).split(","):
                data_column = data_column.strip()
                if not data_column in SPECIAL_FIELDS:
                    if not ((data_column.startswith("ges|") or data_column.startswith("anl|"))):
                        die("ERROR: Invalid data column '%s' specified in --dump-columns! Must have ges| or anl| as a prefix." % data_column)

            pyradmon_config["data_columns"] = parse.dump_columns

        # --dump-all-channels
        if isset_obj("dump_all_channels", parse) and parse.dump_all_channels:
            pyradmon_config["data_all_channels"] = parse.dump_all_channels

        # --dump-channels
        if isset_obj("dump_channels", parse):
            if isset_obj("dump_all_channels", parse) and parse.dump_all_channels:
                die("ERROR: You can not specify --dump-all-channels and --dump-channels at the same time!")
            for data_channel in (parse.dump_channels).split(","):
                data_channel = data_channel.strip()

                if not ( (data_channel.isdigit()) or \
                    ( (len(data_channel.split("-")) == 2) and data_channel.split("-")[0].isdigit() and data_channel.split("-")[1].isdigit() ) ):
                    die("ERROR: Invalid data channel '%s' specified in --dump-channels! Must be a number or a numeric range (#-#)." % data_channel)

            pyradmon_config["data_channels"] = parse.dump_channels

        # --dump-assim-only
        if isset_obj("dump_assim_only", parse):
            pyradmon_config["data_assim_only"] = parse.dump_assim_only

        # --dump-suppress-warnings
        if isset_obj("dump_suppress_warnings", parse):
            pyradmon_config["data_suppress_warnings"] = parse.dump_suppress_warnings

    ## List args
    if parse.verb == "list" or parse.verb == "dump" or parse.verb == "plot" or parse.verb == "config":
        # --data-single-date (action flag)
        if isset_obj("data_single_date", parse):
            pyradmon_config["data_start_date"] = parse.data_single_date
            pyradmon_config["data_end_date"] = parse.data_single_date

        # --data-path-format
        if isset_obj("data_path_format", parse):
            pyradmon_config["data_path_format"] = parse.data_path_format

        # --data-experiment-id
        if isset_obj("data_experiment_id", parse):
            pyradmon_config["data_experiment_id"] = parse.data_experiment_id

        # --data-start-date
        if isset_obj("data_start_date", parse):
            if isset_obj("data_single_date", parse):
                die("ERROR: You can not specify --data-single-date and --data-start-date at the same time!")

            # FORMAT: YYYY-MM-DD HHz
            pyradmon_config["data_start_date"] = parse.data_start_date

            if not (pyradmon_config["data_start_date"][:4].isdigit() and \
                pyradmon_config["data_start_date"][5:7].isdigit() and \
                pyradmon_config["data_start_date"][8:10].isdigit() and \
                pyradmon_config["data_start_date"][11:13].isdigit()):
                die("ERROR: Start date '%s' specified in --data-start-date is not valid! It must be in 'YYYY-MM-DD HHz' format!" % pyradmon_config["data_start_date"])

        # --data-end-date
        if isset_obj("data_end_date", parse):
            if isset_obj("data_single_date", parse):
                die("ERROR: You can not specify --data-single-date and --data-end-date at the same time!")

            # FORMAT: YYYY-MM-DD HHz
            pyradmon_config["data_end_date"] = parse.data_end_date

            if not (pyradmon_config["data_end_date"][:4].isdigit() and \
                pyradmon_config["data_end_date"][5:7].isdigit() and \
                pyradmon_config["data_end_date"][8:10].isdigit() and \
                pyradmon_config["data_end_date"][11:13].isdigit()):
                die("ERROR: End date '%s' specified in --data-end-date is not valid! It must be in 'YYYY-MM-DD HHz' format!" % pyradmon_config["data_end_date"])

        # --data-instrument-sat
        if isset_obj("data_instrument_sat", parse):
            pyradmon_config["data_instrument_sat"] = parse.data_instrument_sat

        # --data-step
        if isset_obj("data_step", parse):
            pyradmon_config["data_step"] = parse.data_step
            if not ((pyradmon_config['data_step'] == "anl") or \
                (pyradmon_config['data_step'] == "ges") or \
                (pyradmon_config['data_step'] == "anl|ges") or \
                (pyradmon_config['data_step'] == "ges|anl")):
                die("ERROR: Data step '%s' specified in --date-step is not valid! Must either be 'anl', 'ges', or the two combined with a pipe ('anl|ges')." % pyradmon_config["data_step"])

        # --data-time-delta
        if isset_obj("data_time_delta", parse):
            pyradmon_config["data_time_delta"] = parse.data_time_delta

            dtd_split = pyradmon_config['data_time_delta'].split(" ")
            unit_valid = [ "s", "w", "m", "M", "h", "y", "d" ]

            for dtd in dtd_split:
                #  s: seconds    m: minutes    h: hours    d: days
                #  w: weeks      M: months     y: years
                if not ( (dtd[-1] in unit_valid) and (dtd[:-1].isdigit()) ):
                    die("ERROR: Invalid delta time '%s' specified in --data-delta-time! Must be a # followed by a valid unit letter. ([s]ecs, [m]inutes, [h]ours, [d]ays, [w]eeks, [M]onths, [y]ears)" % pyradmon_config["data_delta_time"])

    if isset_obj("config_unset", parse):
        # "config.var1;plot1|subplot1"
        config_unset_def = ";".join(parse.config_unset).split(";")

        for config_def in config_unset_def:
            if config_def.startswith("config."):
                pyr_config_var = config_def.split("config.")[1:]

                if len(pyr_config_var) > 1:
                    warn("WARNING: Detected strange unset entry, but continuing anyway.")
                    pyr_config_var = "config.".join(pyr_config_var)
                else:
                    pyr_config_var = str(pyr_config_var[0])

                info("Unsetting pyradmon_config variable %s." % pyr_config_var)

                pyradmon_config.pop(pyr_config_var, None)
            else:
                plot_config_var = config_def.split("|")
                info("Unsetting plot_dict variable %s." % "|".join(plot_config_var))
                if not plot_config_var[0] in plot_dict:
                    warn("Invalid unset definition detected - the plot specified, '%s', does not exist!" % title_def_plot)
                    warn("Ensure spelling is correct. If it is a new plot, make sure it is defined.")
                    warn("This unset definition will be skipped.")
                    continue

                # OK, plot exists. How about subplot?
                # We have to do some strange magic here...
                # ...but only if we need to.

                if len(plot_config_var) >= 2:
                    plot_config_subplot_found = False
                    title_def_subplot_dat = None
                    for subplot_dict in plot_dict[plot_config_var[0]]['plots']:
                        if plot_config_var[1] in subplot_dict:
                            subplot_dat = subplot_dict[plot_config_var[1]]
                            plot_config_subplot_found = True
                            break

                    if not plot_config_subplot_found:
                        warn("Invalid unset definition detected - the subplot specified, '%s', does not exist!" % title_def_subplot)
                        warn("Ensure spelling is correct. If it is a new subplot, make sure it is defined and")
                        warn("in the right subplot. This unset definition will be skipped.")
                        continue

                    # Check
                    if len(plot_config_var) == 2:
                        plot_dict[plot_config_var[0]]['plots'].remove(subplot_dict)
                    else:
                        # Now recursively delete!
                        delete_keys_from_dict(subplot_dat, plot_config_var[2:])
                else:
                    plot_dict.pop(plot_config_var[0], None)

    #import pprint
    #pprint.pprint(plot_dict)

    #print plot_dict

    return (pyradmon_config, plot_dict, parse)

if __name__ == "__main__":
    parser = make_argparser()
    parse = parser.parse_args()
    print parse_to_config(parse)


Will Stocks Surmount a Wall of Worry?
With the bull market for stocks just a few months shy of celebrating its sixth anniversary, it's understandable why market skeptics are plentiful.
But that very skepticism and caution among investors is exactly what could fuel the market's further rise, writes E.S. Browning, the Wall Street Journal's veteran markets writer.
In his article, Browning quotes Savita Subramanian, head U.S. stock strategist at Bank of America Merrill Lynch, who says that Wall Street caution "is one of the main reasons we are bullish" on stocks.
Ms. Subramanian tracks Wall Street stock recommendations as an indicator of market froth. "The more excited the strategists are, the worse the outlook. Strategists are, in other words, a contrarian indicator," according to Subramanian.
Browning writes that Subramanian watches strategists' recommendations to clients about the percentage of assets to hold in stocks, and also their forecasts for stock gains. "Of all her models, she said, this one is particularly reliable. And right now, strategists' measured advice to clients signals more stock gains to come," the article states.
This notion that stock markets like to climb a wall of worry is hardly new and may seem flimsy as well as folksy to some. But it never seems to go away. In the past few years, stocks have continued to rise in the face of skepticism born of the 2008 financial crisis. Might it be that there's something to it?
Meanwhile, The New York Times ran an interesting piece on Sunday that appears to debunk a widely-held belief among the investing cognoscenti that stocks benefit when Congress and the presidency are controlled by different political parties.
Is Gridlock Really Good for Stocks?
Written by Jeff Sommer, a long-time Sunday business-section editor, the piece questions whether Wall Street should like gridlock as much as it does.
"Stocks have been on a tear since the 2010 midterms, but if you go back further in history, it's hard to demonstrate much of a connection between institutional gridlock and stock performance," writes Sommer.
Sommer points out that Edward Yardeni, an independent economist and strategist who writes newsletter for clients, has helped popularize the belief that gridlock is good for stocks.
"I called him about that statement, and he readily acknowledged that it wasn't based on statistics," Sommer wrote.
Good for Sommer for seeking to put a widely-held belief to the test.
I'll close with a Bloomberg piece that succeeds in casting further suspicion around high-priced, hedge-fund style investment strategies.
The article, written by Bloomberg's Ben Steverman, states that many mutual fund companies are starting firms that employ some of the same hedging strategies that hedge funds have long provided.
He writes that unreliable and disappointing performance is getting to be as common among alternative funds as among hedge funds.
An average expense ratio of 1.74% may not be as high as the hedge fund industry's "two and twenty." But the regular folks who buy mutual funds shares shouldn't get used to a management fee this high.


text:
Bolton Declines to Share His Opinion of Trump's Call with Ukraine's President
By Nicholas Ballasy 2019-10-01T13:53:34
WASHINGTON -- Former National Security Advisor John Bolton declined to comment on President Donald Trump's phone conversation with Ukraine President Volodymyr Zelensky, which is at the center of House Speaker Nancy Pelosi's impeachment inquiry.
"Did the president abuse his power with the Ukraine call?" Bolton was asked on Monday after his first public speech since he left the Trump administration at the Center for Strategic and International Studies (CSIS).
The former U.N. ambassador declined to respond.
Bolton was also asked, "Did you hear the call when you were in the White House? Did you raise any concerns about the call, sir?" He waved to the camera but declined to answer.
According to NBC News, Bolton opposed the call with Zelensky. Bolton also had reportedly advocated for Trump to release about $400 million in military aid to Ukraine that was put on hold in July.
A panel discussion followed Bolton's speech about North Korea on Monday at CSIS but he was not asked questions about Ukraine.
https://pjmedia.com/video/bolton-declines-to-share-his-opinion-of-trumps-call-with-ukraines-president/

redpajama_set_name: RedPajamaCommonCrawl


text:
Home All News Celebrities Watch Marvel's Video Tribute to the 'Unmatchable Accomplishments' of Stan Lee (1922-2018)
Watch Marvel's Video Tribute to the 'Unmatchable Accomplishments' of Stan Lee (1922-2018)
McKinley Corbley
Stan Lee, the mastermind behind some of the Marvel universe's most beloved superheroes and storylines, passed away earlier this week at the age of 95.
According to a family representatives, he died early Monday morning at Cedars-Sinai Medical Center in Los Angeles, California.
In addition to being the former editor-in-chief of Marvel Comic Books, he was also the creator of such famous storybook icons as Spiderman, Iron Man, the Mighty Thor, Daredevil, the Fantastic Four, the X-Men, the Incredible Hulk, and Black Panther.
Though he had humble beginnings as the son of a poor Romanian immigrant who worked as a dress cutter in New York City, Lee eventually landed a position with Timely Comics that paid $8 per week, according to the Hollywood Reporter.
RELATED: Guy Hitchhikes for the First Time Only to Get a Ride From Chris Hemsworth in a Helicopter
As his comic book empire grew over the decades, he went on to sell Marvel Entertainment to The Walt Disney Co. for $4 billion in 2009.
The Marvel movie series has since given birth to some of the world's highest-grossing superhero box office flicks of all time.
We've lost a creative genius. Stan Lee was a pioneering force in the superhero universe. I'm proud to have been a small part of his legacy and .... to have helped bring one of his characters to life. #StanLee #Wolverine pic.twitter.com/iOdefi7iYz
— Hugh Jackman (@RealHughJackman) November 12, 2018
There will never be another Stan Lee. For decades he provided both young and old with adventure, escape, comfort, confidence, inspiration, strength, friendship and joy. He exuded love and kindness and will leave an indelible mark on so, so, so many lives. Excelsior!!
— Chris Evans (@ChrisEvans) November 12, 2018
RIP my friend. Thank you for the incredible adventures your stories took all of us on. My love and support goes out to all your friends and family #stanlee #legend pic.twitter.com/pTGY8Ffieg
— Chris Hemsworth (@chrishemsworth) November 13, 2018
Lots of love for Stan Lee at his star on the Hollywood walk of fame. #RIPStanLee pic.twitter.com/isG7jnGa2D
— Dustin Sandoval (@DustinMSandoval) November 13, 2018
Celebrities and fans have been quick to pay tribute to Lee on social media. Many actors who worked alongside Lee for the Marvel movies, such as Hugh Jackman and Chris Hemsworth, have also expressed their love for the late writer.
"Stan Lee was as extraordinary as the characters he created," Disney chairman and CEO Bob Iger said in a statement.
"A superhero in his own right to Marvel fans around the world, Stan had the power to inspire, to entertain and to connect," added Iger. "The scale of his imagination was only exceeded by the size of his heart."
(WATCH Marvel's video tribute below)
Be Sure And Share The Tribute With Your Own Friends On Social Media


My editorial assistant (and son), Matthew Sketchley, joins us again today for a conversation with Michael Stratton from Without Proof. Matthew blogs at Probably Nothing Interesting.
Matthew: We've got Michael Stratton here today, he's one of the main characters in Without Proof. How are you doing, Michael?
Michael: I'm a bit frustrated today, actually. One of my friends is a journalist, and he just reopened an accident I'd like to leave in the past… and suggested to my assistant, Amy, that it could have been sabotage. Just when I'd hoped we were moving beyond this.
Matthew: That accident is the reason you have Amy as an assistant, right? Would you mind elaborating a little on your business and how it's been affected?
Michael: Amy had just moved here to Nova Scotia to marry my best friend, Gilles. When he was killed in the plane crash, she needed a place to recover from her injuries, so I invited her to stay with me. My aunt moved in, too to help. Amy started helping with my accounts, to take her mind off her loss. I think she felt she needed to pay me back, too, although I never would have asked for it. Helping her was helping Gilles, and I'd have done whatever I could.
Anyway, Amy worked herself into a job. Now she handles the books, promotions, and even some of the framing. I'm a painter – nature scenes, mostly. Anything to do with water, although I'll do the occasional portrait as well. I'm hopeless with numbers, so gaining Amy as an assistant has been a definite plus.
I'm based in Nova Scotia, which is a bit far from the larger markets. Two years ago, when the crash happened, I was in the process of moving my business to central Canada. When Gilles died, and Amy needed me, I scrapped those plans and came home. It might not have been the smartest thing, business-wise, but I have no regrets.
Matthew: It sounds like you and Gilles were quite close. I've heard a bit about him already, but could you tell me about your friendship?
Gilles was everything I'm not. Outgoing, adventurous, athletic, charming. From a wealthy French family. We were paired in an exchange program one summer in our teens. He came here first, and let's just say some of the antics we got up to – at his instigation – bonded us closer than brothers. I still can't believe he's gone.
Matthew: I guess I should ask you this, although you've sort of already given an answer. What do you think about this sabotage theory?
Michael: Just because there are apparently ways to crash a plane like his without leaving clues doesn't mean it happened. For a crime, you need motive. Everyone loved Gilles, and there's not even a hint of evidence of sabotage. What makes me so angry about this coming up is that Amy's finally starting to heal. We're coming up to the second anniversary of the crash, and she doesn't need anything to stir up her grief.
Matthew: I can understand that. You're pretty protective of her, right?
Michael: More protective than she likes, sometimes. Amy carries a lot of hurt, from losing Gilles, the way his family treated her afterward, and from something else, something she thinks disqualifies her from a relationship with God. I'd give anything to see her whole again.
Matthew: So how does your business operate? Do you find sales tricky as an introvert, or do you let Amy handle that for you?
Michael: I run a small gallery from my home, conveniently situated for tourists, and I'm building a network of consignment sales through independent gift shops. I also take part in the major craft and gift fairs, and do exhibits in other galleries when I can get them. I let Amy handle as much of the people and paper as possible. She seems to like it. For the public venue events, people really like to meet the artist. I do my best, but schmoozing drains me.
Matthew: Yeah, people are the worst. Well, that's all the questions I have for you today. Any parting words you want to leave us with?
Michael: Hey, people are fine… the right people, and in small numbers. But crowds? Definitely stressful. I'm getting ready for a major show in Toronto. Amy's agreed to go with me, which will help. Here's hoping some time away helps her forget that sabotage nonsense. Thanks for taking time to chat, Matthew.
Matthew: No problem, Michael, it's been good talking to you. Good luck in your Toronto show.
This entry was posted in Interviews, Without Proof and tagged character interview, fictional characters, Matthew Sketchley, Without Proof on October 16, 2015 by Janet Sketchley.


- Date: 10/2011, Series D: $81 M (post valuation: undisclosed amount).
- Date: 02/2011, Series D: $48 M (post valuation: undisclosed amount).
- Date: 04/2010, Series C: $15 M (post valuation: undisclosed amount).
- Date: 01/2008, Series B: $6 M (post valuation: undisclosed amount).
- Date: 10/2006, Series A: $1.5 M (post valuation: undisclosed amount).
Box was featured in a VatorNews article: "Dropbox vs Box: how do their IPOs compare?"
Box was featured in a VatorNews article: "When Box was young: the early years"
Box was featured in a VatorNews article: "Now that Dropbox has 500M users, is an IPO imminent? "
Box was featured in a VatorNews article: "Box and IBM partner up in deal to integrate services"
Box was featured in a VatorNews article: "Box acquires 3D technology company Verold"
Box was featured in a VatorNews article: "Box beefs up security with acquisition of Subspace "
Box was featured in a VatorNews article: "Box embraces financial services as new growth driver"
Box was featured in a VatorNews article: "Box sets IPO price at $14 a share to raise $175M"
Box was featured in a VatorNews article: "Box puts its long-delayed IPO back on schedule"
Box was featured in a VatorNews article: "Raising a lot of money doesn't guarantee success"
Box was featured in a VatorNews article: "Facebook, Yelp, recent Internet IPOs buck downturn"
Box was featured in a VatorNews article: "Box buys MedXT to take deep dive into healthcare"
Box was featured in a VatorNews article: "See Jessica Alba, Brian Lee at Vator Splash LA, Oct. 2"
Box was featured in a VatorNews article: "Lending Club files for IPO, looks to raise $500 million"
Box was featured in a VatorNews article: "Box raises $150 million round at $2.4B valuation"
Box was featured in a VatorNews article: "Box files for IPO, looks to raise $250 million "
Box was featured in a VatorNews article: "Report: Box files for confidential IPO"
Box was featured in a VatorNews article: "Box gives away 50GB for free in honor of updated apps"
Box was featured in a VatorNews article: "File sharing company Hightail raises $34 million"
Box was featured in a VatorNews article: "Aaron Levie: 92% of Fortune 500 companies use Box"


text:
Q: Target Device ID (0x0) does not match expected Device ID (0x18620000). dsPIC33 I have a problem with dsPIC33EP256MU810. I'm using PICkit3 and after I want to load the program to the MCU, MPLAB shows the following message:
Target Device ID (0x0) does not match expected Device ID (0x18620000).

I searched some solutions on forums, everything is OK but on VCAP (10uF tantalum) pin I have no voltage. It may be 1.8V, but I have 0 V.
PGC and PGD are working normally. I have this problem on 2 prototype PCBs.

A: I found the problem: I forgot to connect USB3V3.

redpajama_set_name: RedPajamaStackExchange


text:
Respect paying ceremony held for late Senior Lieutenant General Nguyen Thanh Cung
PANO – A respect paying ceremony for Senior Lieutenant General Nguyen Thanh Cung, former member of the Party Central Committee, former member of the Standing Committee of the Central Military Commission, and former Deputy Defense Minister, was held on December 3 at the Southern National Funeral House.
Sen. Lieut. Gen. Nguyen Thanh Cung visits Corps 4
Senior Lieutenant-General Nguyen Thanh Cung visits Division 5
Senior-Lieutenant General Nguyen Thanh Cung visits Germany
General Phan Van Giang leading the delegation of the Central Military Commission and the Ministry of National Defense paying tribute to Senior Lieutenant General Nguyen Thanh Cung
The delegation of the Central Military Commission and the Ministry of National Defense led by General Phan Van Giang, Politburo member, Deputy Secretary of the Standing Committee of the Central Military Commission, and Defense Minister, paid tribute to Senior Lieutenant General Nguyen Thanh Cung.
The delegation of the Secretariat of the Party Central Committee and the Ho Chi Minh municipal Party Committee, People's Council, People's Committee, Vietnam Fatherland Front Committee led by comrade Nguyen Van Nen, Politburo member, Secretary of the Ho Chi Minh municipal Party Committee; the delegation of the Central Public Security Party Committee and the Ministry of Public Security led by General To Lam, Politburo member, Secretary of the Central Public Security Party Committee, Minister of Public Security; the delegation of the General Department of Political Affairs led by Lieutenant General Trinh Van Quyet, member of the Party Central Committee, Deputy Chief of the General Department of Political Affairs; the delegation of the General Staff of the Vietnam People's Army led by Major General Pham Truong Son, Deputy Chief of the General Staff, paid homage to the late General.
Leaders and former leaders of the Party, State, and military; representatives of agencies, units, military academies and schools under the Ministry of National Defense; Party Committees and authorities of localities also bid last farewell to the former Deputy Defense Minister.
After paying respect to Senior Lieutenant General Nguyen Thanh Cung, delegations' representatives wrote in the condolence book, expressing their sorrow for the passing of comrade Nguyen Thanh Cung. General Phan Van Giang wrote in the book that during more than half a century-revolutionary career, in any positions, he always upheld the virtue of a Communist Party member, wholeheartedly serving the Fatherland and the people, successfully completing all tasks assigned by the Party, State, military, and people.
The delegation of the General Department of Political Affairs led by Lieutenant General Trinh Van Quyet paying respect to Senior Lieutenant General Nguyen Thanh Cung
Comrade Nguyen Thanh Cung was an exemplary, ingenious, brave, decisive cadre with contribution to the cause of building and combat of the military, the struggle for national liberation, and Fatherland construction and defense.
After the respect paying ceremony, a memorial and burial service for Senior Lieutenant General Nguyen Thanh Cung was held at Ho Chi Minh City Cemetery
Translated by Chung Anh
Tag(s): Senior Lieutenant General Nguyen Thanh Cungfuneral


text:
Maryland Olympic Sports
Maryland women's soccer didn't see the progress it hoped for in 2018
The Terps improved in some ways, but still have offensive issues they need to sort out in 2019.
By Henry Malone@henrymalone_ Nov 12, 2018, 8:00am EST
Share All sharing options for: Maryland women's soccer didn't see the progress it hoped for in 2018
Lila Bromberg-Testudo Times
After improving to 7-8-3 last season following 2016's 3-15-1 campaign, 2018 looked like the year Maryland women's soccer could continue to build and get over the .500 mark for the first time since 2012. That didn't happen. Even though Maryland fared better in conference play this year, the Terps won three fewer games overall to finish at 4-10-5.
Here's what worked and what didn't this season, as well as what to expect in 2019.
Things that went well
One of the strong points for the Terps this season was their stout defense. Despite having to play with an often stagnant offense, Maryland's back line was able to do its part to keep the team in games.
Statistically, the Terrapin defense was under attack more in 2018, but still put up better numbers in terms of limiting goals than it did in 2017. Last season, Maryland faced 213 shots in 18 matches, allowing 25 in all. This year, the Terps faced 288 shots and only allowed 22 goals, improving a 1.39 opponent goals-per-game rate down to only 1.16.
A lot of that improvement can be attributed to goalkeeper Rachel Egyed, who finished off her impressive Maryland career with her best season statistically since she's been in College Park. Although she split time with junior Erin Seppi in four games, Egyed was able to hit new career bests in saves (93), save percentage (.830), and goals-against average (1.12). She finished top three in the Big Ten in half of the major goalkeeping statistics, and was named third team All-Big Ten.
Jarena Harmon also improved from 2017 to 2018, although her team-leading six goals this season weren't so much of an improvement as they were a return to form. Last year, she scored just once in 16 matches after scoring seven and eight goals in her freshman and sophomore seasons. But in 2018 she looked like the Harmon of old, serving as the team's most efficient finisher around the goal.
While Harmon got most of the glory offensively, redshirt freshman Alyssa Poarch showed a lot of potential. The young forward only scored two goals this year, but her 43 shots and 16 shots on goal led the team by a wide margin. It'll be interesting to see how she carries her play into 2019 given her strong season and Harmon's departure as a primary goal-scorer.
Things that didn't go well
Despite the few bright spots scattered among the Terrapin offense, the attack held the team back this season. Maryland's attack was just as ineffective as it was last year, as the Terps again only scored 16 goals over the 19-game season.
Part of the reason for the low scoring for the season was multiple lengthy scoreless droughts. In non-conference play, Maryland only scored one goal over its final five games. The Terps improved slightly in Big Ten play, picking up impressive wins over Iowa and then No. 14 Northwestern, but only had two multi-goal performances during the 11-game conference slate.
Maryland's scoring struggles were compounded by the team's inability to perform consistently on the road. In nine away games, the Terps finished 0-6-3, scoring just four goals in the process. This is down from the three road wins they picked up last season despite only notching six away goals.
Who's leaving
The Terps only graduate four seniors, but all of them were important contributors.
Egyed's time in goal for Maryland is over, leaving a large void at the back end of the defense that will likely be filled by rising senior Erin Seppi. Even though Seppi played well with the time she was given, replacing Egyed will be difficult.
Two of the more active forwards for the team will also be graduating, as neither Harmon nor Kady Badham will be with the team next season. While Harmon's contributions scoring will obviously be missed, Badham's presence will be hard to replace too. She was listed as a forward, but ended up being a Swiss Army knife of a player that could serve as a defender and midfielder as well. She also showed an aptitude to play the ball down the sideline and probe for opportunities to play the ball into the box.
The final departing senior was another one of the mainstays of the Maryland defense. Jenna Surdick appeared in all 19 games for Maryland this season, finishing fifth on the team minutes played. Her teammates referred to her as a calming presence for the defensive unit.
Who's staying
The good news for the Terps is that most of the team will be returning. The young Maryland squad will be bringing back several key playmakers that figure to be important contributors again. The two most important returners are midfielders Hope Lewandoski and Darby Moore. Both were heavily involved in the the team's offensive buildup play and will have the opportunity to assume more of the scoring load with Harmon leaving.
Also returning at the midfield position will be rising juniors Malikae Dayes and Anissa Mose. Both players played in the same kind of multi purpose role as Badham, as their versatility definitely played a role in them playing in every game this season. If anything, the Maryland midfield will, for the most part, remain intact.
One player who Terps fans didn't see this year but should make an impact next season is midfielder Jlon Flippens. She appeared in 14 matches and started all but one of those for Maryland in 2017, contributing two goals and three assists in a little over 1300 minutes. Flippens was sidelined for all of 2018 with an injury, but will be adding her ability as a shot creator to what will already be a very deep corps of midfielders.
Finally, the biggest change from this season to next will be Seppi replacing Egyed in goal. In the limited action she saw in the early parts of the season, Seppi made eight saves in five matches with a 0.93 goals-against average. It will be the first time since she's been a Terp that she won't be playing behind Egyed, so how she responds to being the starting goalkeeper will likely have a significant effect on how Maryland fares in 2019.


text:
Tabu – album zespołu Kombi nagrany w 1988 roku w studiu Sławomira Łosowskiego i wydany w roku następnym – 1989. W sferze brzmieniowej był on połączeniem muzyki z lat 1976-1982 i tej późniejszej z okresu "elektronicznego". Przede wszystkim bardziej niż w poprzednich albumach jest słyszalna gitara Grzegorza Skawińskiego, co nie oznacza że syntezatory nie są tu wszechobecne. Sławomir Łosowski utrzymał zestaw klawiszowy użyty w LP Kombi 4, lecz komputer perkusyjny Yamaha RX11 zastąpiony został wielobarwnym modelem Yamaha RX5. W zestawie także użyto dodatkowego modułu basowego 360 Midi Bass Systems. Płyta zawiera takie przeboje jak: "Nietykalni – skamieniałe zło", "Pamiętaj mnie", "Tabu - Obcy Ląd", "Też chciałbym tak". Na koncercie 15-lecia Kombi muzykom została wręczona za album Tabu złota płyta.

Lista utworów
 "Tabu – obcy ląd" (muz. Sławomir Łosowski – sł. Waldemar Tkaczyk) – 3:22
 "Nietykalni – skamieniałe zło" (muz. Sławomir Łosowski – sł. Waldemar Tkaczyk) – 4:07
 "Też chciałbym tak" (muz. Waldemar Tkaczyk – sł. Waldemar Tkaczyk) – 3:24
 "Bez szans" (muz. Sławomir Łosowski – sł. Jacek Cygan) – 3:23
 "Nadziei coraz mniej" (muz. Waldemar Tkaczyk – sł. Waldemar Tkaczyk) – 3:51
 "Pamiętaj mnie" (muz. Sławomir Łosowski – sł. Marek Dutkiewicz) – 3:54
 "Jak pogodzić dwie strony" (muz. Grzegorz Skawiński – sł. Jacek Cygan) – 3:30
 "Tyle dzieje się" (muz. Grzegorz Skawiński – sł. Waldemar Tkaczyk) – 2:53
 "Matka noc" (muz. Grzegorz Skawiński – sł. Marek Dutkiewicz) – 4:16
 "Obiecany raj" (muz. Sławomir Łosowski – sł. Waldemar Tkaczyk) – 4:04

Skład
 Sławomir Łosowski – instrumenty klawiszowe, programowanie
 Grzegorz Skawiński – gitara, śpiew
 Waldemar Tkaczyk – gitara basowa

Reżyser dźwięku: Marian Ślusarczyk. Producent: Sławomir Łosowski.

Przypisy

Bibliografia

Albumy Polskich Nagrań Muza
Albumy Kombi
Albumy muzyczne wydane w roku 1989

redpajama_set_name: RedPajamaWikipedia


Cookies are small text files sent to the user's device by the visited Site. Cookies are stored in the device's memory, thus allowing the Site to recognize user and store certain information concerning them, in order to permit or improve the service offered.
There are different types of cookies. Some are necessary to navigate on the Site, others have a different purpose such as ensuring internal security, performing system administration tasks and statistical analysis, understanding which sections of the Site are more relevant to users, or offering a personalized experience on the Site.
Two types of cookies may be used, "session cookies" and "persistent cookies". Session cookies are stored temporarily on the device and are deleted when the user closes the browser. Persistent cookies remain longer on your device, for the duration of each specific cookie, and will be automatically deleted at the end of their "lifetime".
Disabling cookies may limit the ability to use the Site and prevent from benefitting in full of the features and services offered on the Site. In order to decide which cookies to accept or reject, please find below a description of the cookies used on the Site.
Third Party Cookies: Third party cookies are set from a different domain than the one visited by the user. When a user visits a website and a different company sends the information through that website using cookies, these cookies are third party cookies.
7FAM has no access nor control over cookies, web beacons and other tracking technologies used by third party websites which the user may access from the Website. 7FAM expressly disclaims any responsibility accordingly for such third party websites and their cookies. The user is encouraged to read the privacy policies of third party websites accessed through the Site, to understand the conditions applicable to the processing of personal data on such websites.
Persistent Cookies: Persistent cookies are stored on the user's device between browser sessions, allowing the Site to remember preferences and actions on the Site. These cookies can be used for different purposes, e.g. to remember preferences and choices when using the Site.
Functional Cookies: These cookies are used to identify a user that returns to the Site. They allow to customize the content of the Site and to remember the user's preferences (such as the language or country). These cookies do not collect information that can identify the user.
Cookies for sharing on Social Networks: These cookies facilitate the sharing of the Site content through social networks such as Facebook and Twitter. To review the respective privacy policies cookies, you can visit the social networks websites. In the case of Facebook and Twitter please visit https://www.facebook.com/help/cookies and https://twitter.com/privacy.
Below is the list of cookies specifically used by this Site and their description and functionality, including their duration.
Google sets a number of cookies on any page that includes a Google Map. While we have no control over the cookies set by Google, they appear to include a mixture of pieces of information to measure the number and behavior of Google Maps users.
These cookies are created by Twitter. In this case they are present because a Twitter widget or button is being used on the website and to monitor referral links, and login status.
These cookies, provided by Facebook, are set when a visitor is logged in to or otherwise using their service. This allows a user to easily comment or share an article with their peers through the social network.
These cookies allow Google to authenticate you if you share the site using Google +1 button.
Most browsers automatically accept cookies, but the User can usually manage preferences on cookies through browser settings It is possible to delete all cookies, block all types of cookies, or agree to receive only some of them disabling others. The "Options" or "Favorites" sections in the browser menu permit to accept or avoid receiving cookies and other tracking technologies, as well as to receive notification from the browser when these technologies are used. Alternatively, it is possible to manage cookies consulting the "Help" section of the toolbar present in most browsers. It is also possible to select the browser from the list below and follow the instructions: - Internet Explorer; - Chrome; - Safari; - Firefox; - Opera. For mobile: - Android; - Safari; - Windows Phone; - Blackberry.


text:
Q: Physics2D.OverlapBox shows inconsistent behaviour Recently I started working with Unity, this is the first time I'm trying to build a 2d platformer.
For some reason, when I press the jump button, there is a random chance that it will actually make the player jump. Probably around 1 in 50 that it actually jumps.
I just can't figure out why its doing that. Do you know what I'm doing wrong here?
using UnityEngine;

public class Player : MonoBehaviour
{
    public float movespeed = 5f;
    public float jumpforce = 5f;
    public Rigidbody2D player;

    public LayerMask layerMaskPlatforms;

    private float movementHorizontalInput;
    private bool jumpInput;

    private float lastTimeOnGroundInSeconds = 0f;
    private float lastTimePressedJump = 0f;

    void OnBecameInvisible()
    {
        // todo: restart game
    }

    void Update()
    {
        movementHorizontalInput = Input.GetAxisRaw("Horizontal");
        jumpInput = Input.GetButtonDown("Jump");
    }

    void FixedUpdate()
    {
        if (jumpInput)
        {
            AttemptJump();
            lastTimePressedJump = 0.2f;
        }
        else if (lastTimePressedJump > 0)
        {
            AttemptJump();
            lastTimePressedJump -= Time.deltaTime;
        }

        if (IsOnGround())
        {
            lastTimeOnGroundInSeconds = 0.2f;
        }
        else if (lastTimeOnGroundInSeconds > 0)
        {
            lastTimeOnGroundInSeconds -= Time.deltaTime;
        }

        player.velocity = new Vector2(movementHorizontalInput * movespeed * Time.deltaTime * 50f, player.velocity.y);
    }

    private void AttemptJump()
    {
        if (lastTimeOnGroundInSeconds > 0)
        {
            player.AddForce(new Vector2(0, jumpforce), ForceMode2D.Impulse);
            lastTimeOnGroundInSeconds = 0;
        }
    }

    private bool IsOnGround()
    {
        Vector2 groundedCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
        var overlapBox = Physics2D.OverlapBox(groundedCheckPosition, transform.localScale, 0, layerMaskPlatforms);
        return overlapBox;
    }
}

A: One major issue is that the jump input is being polled every frame (Update), but the jump code is done every several frames (FixedUpdate), so if you press jump, it is most likely the FixedUpdate method will never see that jump, explaining why it happens so rarely.
You'd need to save the jump state (maybe in a boolean), so by the time Fixed Update happens, it knows that that a jump occurred. Then set that jump to false, and do the jump logic.