text:
from __future__ import division, print_function, unicode_literals

import re
import os
import fnmatch

import requests_oauthlib
import oauthlib
import yaml_io

try:
    from htmlentitydefs import name2codepoint
except ImportError:
    # Must be Python 3.x
    from html.entities import name2codepoint
    unichr = chr

def unescaper(match):
    """Custom un-escape function.

    """
    name2codepoint_work = name2codepoint.copy()
    name2codepoint_work['apos']=ord("'")

    code = match.group(1)
    if code:
        return unichr(int(code, 10))
    else:
        code = match.group(2)
        if code:
            return unichr(int(code, 16))
        else:
            code = match.group(3)
            if code in name2codepoint_work:
                return unichr(name2codepoint_work[code])

    return match.group(0)

def decode(s, encoding='utf-8'):
    """Decode string entity.

    """
    EntityPattern = re.compile(u'&(?:#(\d+)|(?:#x([\da-fA-F]+))|([a-zA-Z]+));')
    result = EntityPattern.sub(unescaper, s.decode(encoding))

    return result

def extract_url(text):
    result = re.search("(?P<url>https?://[^\s]+)", text)
    if result:
        url = result.group("url")
    else:
        url = None

    return url

#####################################################

def file_finder(paths_search, file_patterns='*'):
    """An iterator that yields files matching a pattern.

    Parameters
    ----------
    paths_search : a string or a sequence of strings.
    file_patterns : a string or a sequence of strings.

    Useage
    ------
        finder = file_finder('/usr/local', '*.c')
        for f in finder:
            print(f)
    """

    if isinstance(paths_search, basestring):
        paths_search = [paths_search]

    if isinstance(file_patterns, basestring):
        file_patterns = [file_patterns]

    # Loop over base paths for recursive search.
    for path_work in paths_search:
        path_work = os.path.normpath(path_work)

        # Iterate over found files and folders.
        for root, dirnames, filenames in os.walk(path_work):
            local_matches = []
            for fp in file_patterns:
                for f in fnmatch.filter(filenames, fp):
                    local_matches.append(os.path.join(root, f))

            # Yield found matches to caller.
            for f in local_matches:
                yield os.path.normpath(f)

def authenticate(fname_api='twitter_api.yml'):
    """Generate a requests.Session object authorized via OAuth-2.

    Twitter API urls:
     - url_api = 'https://api.twitter.com'
     - url_request_oauth1_token = url_api + '/oauth/request_token'
     - url_request_oauth2_token = url_api + '/oauth2/token'
     - url_authorize = url_api + '/oauth/authorize'
     - url_access_token = url_api + '/oauth/access_token'
    """
    # Load application's Twitter API details.
    info_twitter = yaml_io.read(fname_api)

    client_key = info_twitter['consumer_key']
    # client_secret = info_twitter['consumer_secret']
    access_token = info_twitter['access_token']

    # Backend client / desktop client application workflow.
    client = oauthlib.oauth2.BackendApplicationClient(client_key)
    token = {'access_token': access_token, 'token_type': 'Bearer'}

    # Generate requests.Session object.
    session = requests_oauthlib.OAuth2Session(client, token=token)

    return session

def rate_limit_from_api(session, resources='search'):
    """Query Twitter API for current rate limit status.
    """
    url_status = 'https://api.twitter.com/1.1/application/rate_limit_status.json'
    params = {'resources': resources}

    # Request information from Twitter.
    response = session.get(url_status, params=params)

    # Interpret the results.
    info_status = response.json()

    try:
        info_search = info_status['resources']['search']['/search/tweets']
    except KeyError:
        code = info_status['errors'][0]['code']
        if code == 88:
            message = info_status['errors'][0]['message']
            raise ValueError(message)
        else:
            raise

    limit = info_search['limit']
    remaining = info_search['remaining']
    reset = info_search['reset']

    info = {'limit': limit, 'remaining': remaining, 'reset': reset}

    return info

def rate_limit_from_header(hdr):
    """Parse rate limit information from response header.
    """
    try:
        limit = hdr['x-rate-limit-limit']
        remaining = hdr['x-rate-limit-remaining']
        reset = hdr['x-rate-limit-reset']

        info = {'limit': limit, 'remaining': remaining, 'reset': reset}
    except KeyError:
        info = None

    return info

if __name__ == '__main__':
    pass


text:
package org.apache.camel.component.spring.ws.bean;

import java.net.URI;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.camel.RuntimeCamelException;
import org.apache.camel.component.spring.ws.SpringWebserviceConsumer;
import org.apache.camel.component.spring.ws.SpringWebserviceEndpoint;
import org.apache.camel.component.spring.ws.type.EndpointMappingKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.ws.server.endpoint.MessageEndpoint;
import org.springframework.ws.soap.addressing.core.MessageAddressingProperties;
import org.springframework.ws.soap.addressing.messageid.MessageIdStrategy;
import org.springframework.ws.soap.addressing.server.AbstractAddressingEndpointMapping;
import org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping;
import org.springframework.ws.transport.WebServiceMessageSender;

/**
 * Provides support for full WS-Addressing. Supported are faultAction and
 * response action. For more details look at @see
 * {@link AbstractAddressingEndpointMapping}. Implementation of the
 * {@link org.springframework.ws.server.EndpointMapping} consumer interface that
 * uses the camel uri to map to a WS-Addressing {@code Action} header.
 *

 */
public class WSACamelEndpointMapping extends AbstractAddressingEndpointMapping implements CamelSpringWSEndpointMapping {

    private static final Logger LOG = LoggerFactory.getLogger(WSACamelEndpointMapping.class);

    private Map<EndpointMappingKey, MessageEndpoint> endpoints = new ConcurrentHashMap<>();

    private String outputActionSuffix = AnnotationActionEndpointMapping.DEFAULT_OUTPUT_ACTION_SUFFIX;

    private String faultActionSuffix = AnnotationActionEndpointMapping.DEFAULT_OUTPUT_ACTION_SUFFIX;

    @Override
    protected Object getEndpointInternal(MessageAddressingProperties map) {
        // search the endpoint with compositeKeyFirst
        for (EndpointMappingKey key : endpoints.keySet()) {
            String compositeOrSimpleKey = null;
            switch (key.getType()) {
                case ACTION:
                    compositeOrSimpleKey = getActionCompositeLookupKey(map);
                    break;
                case TO:
                    compositeOrSimpleKey = getToCompositeLookupKey(map);
                    break;
                default:
                    throw new RuntimeCamelException(
                            "Invalid mapping type specified. Supported types are: spring-ws:action:<WS-Addressing Action>(optional:<WS-Addressing To>?<params...>\n)"
                                    + "spring-ws:to:<WS-Addressing To>(optional:<WS-Addressing Action>?<params...>)");
            }
            // lookup for specific endpoint
            if (compositeOrSimpleKey != null && key.getLookupKey().equals(compositeOrSimpleKey)) {
                LOG.debug("Found mapping for key {}", key);
                return endpoints.get(key);
            }
        }

        // look up for the simple key
        for (EndpointMappingKey key : endpoints.keySet()) {
            String simpleKey = null;
            switch (key.getType()) {
                case ACTION:
                    if (map.getAction() != null) {
                        simpleKey = map.getAction().toString();
                    }
                    break;
                case TO:
                    if (map.getTo() != null) {
                        simpleKey = map.getTo().toString();
                    }
                    break;
                default:
                    throw new RuntimeCamelException(
                            "Invalid mapping type specified. Supported types are: spring-ws:action:<WS-Addressing Action>(optional:<WS-Addressing To>?<params...>\n)"
                                    + "spring-ws:to:<WS-Addressing To>(optional:<WS-Addressing Action>?<params...>)");
            }
            // look up for less specific endpoint
            if (simpleKey != null && key.getLookupKey().equals(simpleKey)) {
                LOG.debug("Found mapping for key {}", key);
                return endpoints.get(key);
            }
        }
        return null;
    }

    /**
     * Generate a lookupKey for a given WS-Addressing message using action
     * property. The possible combination are:
     *

     *
wsaAction

     *
wsaAction:wsaGetTo

     *

     *
     * @param map
     * @return
     */
    protected String getActionCompositeLookupKey(MessageAddressingProperties map) {
        String key = "";
        if (map.getAction() != null) {
            key = map.getAction().toString();
        }
        if (map.getTo() != null) {
            if (!key.isEmpty()) {
                key += ":";
            }
            key += map.getTo().toString();
        }
        return key;
    }

    /**
     * Generate a lookupKey for a given WS-Addressing message using getTo
     * property. The possible combination are:
     *

     *
wsaGetTo

     *
wsaGetTo:wsaAction

     *

     *
     * @param map
     * @return
     */
    protected String getToCompositeLookupKey(MessageAddressingProperties map) {
        String key = "";
        if (map.getTo() != null) {
            key = map.getTo().toString();
        }
        if (map.getAction() != null) {
            if (!key.isEmpty()) {
                key += ":";
            }
            key += map.getAction().toString();
        }
        return key;
    }

    /**
     * Return output camel uri param or default action or null
     */
    @Override
    protected URI getResponseAction(Object endpoint, MessageAddressingProperties requestMap) {
        SpringWebserviceEndpoint camelEndpoint = getSpringWebserviceEndpoint(endpoint);

        URI actionUri = camelEndpoint.getConfiguration().getOutputAction();
        if (actionUri == null) {
            actionUri = getDefaultResponseAction(camelEndpoint, requestMap);
        }
        return actionUri;
    }

    /**
     * Configure message sender for wsa:replyTo from a camel route definition.
     * The route definition has priority over this endpoint.
     */
    @Override
    protected WebServiceMessageSender[] getMessageSenders(Object endpoint) {
        SpringWebserviceEndpoint camelEndpoint = getSpringWebserviceEndpoint(endpoint);

        if (camelEndpoint.getConfiguration().getMessageSender() != null) {
            return new WebServiceMessageSender[] {camelEndpoint.getConfiguration().getMessageSender()};
        }

        return super.getMessageSenders(endpoint);
    }

    /**
     * Configure message id strategy for wsa:replyTo The route definition has
     * priority over this endpoint.
     */
    @Override
    protected MessageIdStrategy getMessageIdStrategy(Object endpoint) {
        SpringWebserviceEndpoint camelEndpoint = getSpringWebserviceEndpoint(endpoint);

        if (camelEndpoint.getConfiguration().getMessageIdStrategy() != null) {
            return camelEndpoint.getConfiguration().getMessageIdStrategy();
        }

        return super.getMessageIdStrategy(endpoint);
    }

    /**
     * return fault came uri param or default fault action or null
     */
    @Override
    protected URI getFaultAction(Object endpoint, MessageAddressingProperties requestMap) {
        SpringWebserviceEndpoint camelEndpoint = getSpringWebserviceEndpoint(endpoint);

        URI actionUri = camelEndpoint.getConfiguration().getFaultAction();
        if (actionUri == null) {
            actionUri = getDefaultFaultAction(camelEndpoint, requestMap);
        }
        return actionUri;

    }

    private SpringWebserviceEndpoint getSpringWebserviceEndpoint(Object endpoint) {
        Assert.isInstanceOf(SpringWebserviceConsumer.class, endpoint, "Endpoint needs to be an instance of SpringWebserviceConsumer");

        SpringWebserviceConsumer springWebserviceConsumer = (SpringWebserviceConsumer)endpoint;
        return (SpringWebserviceEndpoint)springWebserviceConsumer.getEndpoint();
    }

    protected URI getDefaultResponseAction(Object endpoint, MessageAddressingProperties requestMap) {
        URI requestAction = requestMap.getAction();
        if (requestAction != null) {
            return URI.create(requestAction.toString() + getOutputActionSuffix());
        } else {
            return null;
        }
    }

    protected URI getDefaultFaultAction(Object endpoint, MessageAddressingProperties requestMap) {
        URI requestAction = requestMap.getAction();
        if (requestAction != null) {
            return URI.create(requestAction.toString() + getFaultActionSuffix());
        } else {
            return null;
        }
    }

    @Override
    public void addConsumer(EndpointMappingKey key, MessageEndpoint endpoint) {
        endpoints.put(key, endpoint);
    }

    @Override
    public void removeConsumer(Object key) {
        endpoints.remove(key);
    }

    /**
     * Returns the suffix to add to request Actions for reply
     * messages.
     */
    public String getOutputActionSuffix() {
        return outputActionSuffix;
    }

    /**
     * Sets the suffix to add to request Actions for reply
     * messages.
     *
     * @see #DEFAULT_OUTPUT_ACTION_SUFFIX
     */
    public void setOutputActionSuffix(String outputActionSuffix) {
        Assert.hasText(outputActionSuffix, "'outputActionSuffix' must not be empty");
        this.outputActionSuffix = outputActionSuffix;
    }

    /**
     * Returns the suffix to add to request Actions for reply fault
     * messages.
     */
    public String getFaultActionSuffix() {
        return faultActionSuffix;
    }

    /**
     * Sets the suffix to add to request Actions for reply fault
     * messages.
     *
     * @see #DEFAULT_FAULT_ACTION_SUFFIX
     */
    public void setFaultActionSuffix(String faultActionSuffix) {
        Assert.hasText(faultActionSuffix, "'faultActionSuffix' must not be empty");
        this.faultActionSuffix = faultActionSuffix;
    }

}

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="UTF-8"?>
<Layout xmlns="http://soap.sforce.com/2006/04/metadata">
    <layoutSections>
        <customLabel>false</customLabel>
        <detailHeading>false</detailHeading>
        <editHeading>true</editHeading>
        Information
        <layoutColumns>
            <layoutItems>
                <behavior>Required</behavior>
                <field>Name</field>
            </layoutItems>
            <layoutItems>
                <behavior>Edit</behavior>
                <field>Sector_Id__c</field>
            </layoutItems>
        </layoutColumns>
        <layoutColumns>
            <layoutItems>
                <behavior>Edit</behavior>
                <field>OwnerId</field>
            </layoutItems>
        </layoutColumns>

    </layoutSections>
    <layoutSections>
        <customLabel>false</customLabel>
        <detailHeading>false</detailHeading>
        <editHeading>true</editHeading>
        System Information
        <layoutColumns>
            <layoutItems>
                <behavior>Readonly</behavior>
                <field>CreatedById</field>
            </layoutItems>
        </layoutColumns>
        <layoutColumns>
            <layoutItems>
                <behavior>Readonly</behavior>
                <field>LastModifiedById</field>
            </layoutItems>
        </layoutColumns>

    </layoutSections>
    <layoutSections>
        <customLabel>false</customLabel>
        <detailHeading>false</detailHeading>
        <editHeading>true</editHeading>
        <layoutColumns/>
        <layoutColumns/>
        <layoutColumns/>

    </layoutSections>
    <relatedLists>
        <fields>NAME</fields>
        <relatedList>Fund__c.Sector__c</relatedList>
    </relatedLists>
    <showEmailCheckbox>false</showEmailCheckbox>
    <showHighlightsPanel>false</showHighlightsPanel>
    <showInteractionLogPanel>false</showInteractionLogPanel>
    <showRunAssignmentRulesCheckbox>false</showRunAssignmentRulesCheckbox>
    <showSubmitAndAttachButton>false</showSubmitAndAttachButton>
</Layout>


text:
ruleName: align
description: Enforces vertical alignment.
rationale: 'Helps maintain a readable, consistent style in your codebase.'
optionsDescription: |-

  Three arguments may be optionally provided:

  * `"parameters"` checks alignment of function parameters.
  * `"arguments"` checks alignment of function call arguments.
  * `"statements"` checks alignment of statements.
options:
  type: array
  items:
    type: string
    enum:
      - arguments
      - parameters
      - statements
  minLength: 1
  maxLength: 3
optionExamples:
  - '[true, "parameters", "statements"]'
type: style
typescriptOnly: false
layout: rule
title: 'Rule: align'
optionsJSON: |-
  {
    "type": "array",
    "items": {
      "type": "string",
      "enum": [
        "arguments",
        "parameters",
        "statements"
      ]
    },
    "minLength": 1,
    "maxLength": 3
  }
---


text:
#pragma once

#include <SFGUI/Config.hpp>
#include <SFGUI/Renderer.hpp>

#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>

namespace sfg {

/** SFGUI Vertex Array renderer.
 */
class SFGUI_API VertexArrayRenderer : public Renderer {
	public:
		/** Ctor.
		 */
		VertexArrayRenderer();

		/** Enable and select alpha testing threshold.
		 * @param alpha_threshold Threshold at which fragments will get discarded if their alpha value is less than or equal to. Set to 0.f to disable.
		 */
		void TuneAlphaThreshold( float alpha_threshold );

		/** Enable or disable CPU driven face culling.
		 * @param enable true to enable, false to disable.
		 */
		void TuneCull( bool enable );

		virtual const std::string& GetName() const override;

	protected:
		virtual void InvalidateImpl( unsigned char datasets ) override;
		virtual void DisplayImpl() const override;

	private:
		void RefreshArray();

		std::vector<sf::Vector2f> m_vertex_data;
		std::vector<sf::Color> m_color_data;
		std::vector<sf::Vector2f> m_texture_data;
		std::vector<GLuint> m_index_data;

		std::vector<Batch> m_batches;

		GLsizei m_last_vertex_count;
		GLsizei m_last_index_count;

		float m_alpha_threshold;

		mutable bool m_dirty;

		bool m_cull;
};

}


text:
Help

JMRI

JMRI with paducah.sh

Connections

JMRI 4.0 and earlier uses the following patterns to discover devices:

Quick Start

      The simplest way to run paducah.sh is to run it directly from the internet:
      bash <( curl -sSL http://rhwood.github.io/paducah/paducah.sh )
      Run this way, paducah.sh will prompt to take most actions.

Parameters

The following parameters can be added to the paducah.sh command to modify
    its default behavior. If invoked directly from the internet, these
    parameters would be specified after the closing parenthesis around the curl
    command and paducah.sh URL.

Devices

-d DEVICE or --device=DEVICE

Get information about the device at the path specified as device.

      Example: --device=/dev/ttyACM0

      If not specified, paducah.sh will prompt you to disconnect and reconnect
      the powered on device to discover it.

-a or --all-rules

Write the udev rules for all known devices. If specified, paducah.sh will
      not prompt for an individual device to be connected.

-c CLASS or --class=CLASS

When discovering a device as it is connected, paducah.sh should only
      discover devices of the specified CLASS. If not specified, paducah.sh will
      only discover <stron>TTY class devices.

-i or --info

Display information about the discovered device. If not specified,
      paducah.sh will attempt to create a rule for the device, but will not show
      information about it.

-q or --quiet

Take default actions without prompting. This is the same as using the
      parameters --all-rules --upload.

-r or --rules

Install rules for devices. If not specified, paducah.sh will prompt
      to install rules.

-R or --no-rules

Do not install rules for devices. If not specified, paducah.sh will
      prompt to install rules.

-u or --upload

Upload data for a discovered device. If not specified, paducah.sh will
      prompt to upload data.

-U or --no-upload

Do not upload data for a discovered device. If not specified, paducah.sh
      will prompt to upload data.

General

--user=USER

Set the GitHub username to USER. Passing an empty USER (--user=)
      will remove the GitHub username and token from paducah.sh's configuration.
      A new user token will be generated only if requested using the
      --token parameter.

--token

Have padacah.sh generate a GitHub personal access token. paducah.sh uses
      a personal access token to avoid having to store a password, and to avoid
      having to persistently prompt a user for a password or two factor
      authentication code. Note that tokens are sensitive and should be
      protected. Creating a token is not normally needed or desired.

If a token was already created for
      paducah.sh on a given computer, a new token cannot be created until the
      original token is deleted from GitHub.

-v or --version

Display the version and copyright for paducah.sh.

-h or --help

Display a brief help message.

    Unlike many Linux programs, short parameters cannot be combined in paducah.sh


text:
package edu.wisc.cs.wisdom.sdmbn.json;

public class DelPerflowAckMessage extends Message
{
	public int count;

	public DelPerflowAckMessage()
	{ super(Message.RESPONSE_DELETE_PERFLOW_ACK); }

	public DelPerflowAckMessage(AllFieldsMessage msg) throws MessageException
	{
		super(msg);
		if (!msg.type.equals(Message.RESPONSE_DELETE_PERFLOW_ACK))
		{
			throw new MessageException(
					String.format("Cannot construct %s from message of type %s",
							this.getClass().getSimpleName(), msg.type), msg);
		}
		this.count = msg.count;
	}

	public String toString()
	{ return "{id="+id+",type=\""+type+"\",count="+count+"}"; }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace GestureSample.Views.Tests
{
	[XamlCompilation(XamlCompilationOptions.Compile)]
	public partial class PrintFirstPanning
	{
		MR.Gestures.PanEventArgs last;

		public PrintFirstPanning ()
		{
			InitializeComponent ();
		}

		private void ContentPage_Panning(object sender, MR.Gestures.PanEventArgs e)
		{
			if (last == null)
				((ViewModels.CustomEventArgsViewModel)BindingContext).AddText($"starting pan gesture, DeltaDistance={e.DeltaDistance.X}/{e.DeltaDistance.Y}, TotalDistance={e.TotalDistance.X}/{e.TotalDistance.Y}, Velocity={e.Velocity.X}/{e.Velocity.Y}");
			last = e;
		}

		private void ContentPage_Panned(object sender, MR.Gestures.PanEventArgs e)
		{
			last = null;
		}
	}
}


text:
//
//  graphState.h
//  feedback
//
//  Created by James Bentley on 9/24/15.
//
//

#ifndef __feedback__graphState__
#define __feedback__graphState__

#include "ofxState.h"
#include "sharedData.h"
#include "ofxCv.h"
#include "ofxIntegrator.h"

class graphState : public itg::ofxState<sharedData> {
public:
    void setup();
    void update();
    void draw();
    void keyPressed(int key);
    string getName();
    void stateEnter();

    float dimFac;
    Mat previous;
    ofImage diff;
    Mat columnMean;

    vector< Integrator<float>* > vals;

};

#endif /* defined(__feedback__graphState__) */


text:
"use strict";

import PagerDirective from "./directives/pager";

import DirectiveFactory from "../../../utils/directive";

export default angular.module("components.nav.pager", [])
	.directive("antPager", DirectiveFactory.create(PagerDirective))
	.name;


text:
package com.elsealabs.xshot.error;

import java.util.ArrayList;

public class ErrorManager {

	private static ErrorManager manager;
	private ArrayList<Error> errors;
	private boolean showMessages;
	private boolean showSmartTraces;
	private boolean showFullTraces;
	private boolean showPopups;

	public static ErrorManager getInstance()
	{
		if (manager == null)
		{
			manager = new ErrorManager();
			manager.errors = new ArrayList<Error>();
			manager.showMessages = true;
			manager.showSmartTraces = true;
			manager.showPopups = true;
			manager.showFullTraces = false;
		}
		return manager;
	}

	public void newError(Error error)
	{
		if (showMessages)
		{
			System.err.printf("> [Error : Message] %s\n", error.getMessage());
		}
		if (showSmartTraces)
		{
			System.err.printf(error.getSmartTrace());
		}
		if (showPopups)
		{
			// TODO: Show popup if error has one
		}

		errors.add(error);
	}

	public void newError(Exception ex, String message, boolean doPopup)
	{
		newError(new Error(ex, message, doPopup));
	}

}


text:
'use strict';

var nodeAssert = require('assert');

module.exports = CollapsedAssert;

// TODO more methods
function CollapsedAssert() {
    if (!(this instanceof CollapsedAssert)) {
        return new CollapsedAssert();
    }

    var self = this;

    self._commands = [];
    self._failed = false;
}

CollapsedAssert.prototype.equal = function equal(a, b, msg, extra) {
    var self = this;

    if (a !== b) {
        self._failed = true;
    }

    self._commands.push(['equal', a, b, msg, extra]);
};

CollapsedAssert.prototype.fail = function fail(msg, extra) {
    var self = this;

    self._failed = true;
    self._commands.push(['fail', msg, extra]);
};

CollapsedAssert.prototype.report = function report(realAssert, message) {
    var self = this;

    nodeAssert(message, 'must pass message');

    if (!self._failed) {
        return realAssert.ok(true, message);
    }

    for (var i = 0; i < self._commands; i++) {
        var command = self._commands[i];

        var method = command.shift();
        realAssert[method].apply(realAssert, command);
    }
};


text:
__all__ = [
    'get_local_context',
    'set_local_context',
    'clear_local_context',
    '_set_local_context',
    '_clear_local_context',
]

from functools import wraps
import threading
import uuid
import warnings

def _deprecated(as_of=None, in_favor_of=None):
    def __inner(func):
        @wraps(func)
        def __wrapper(*args, **kwargs):
            replaced_by = (' Please use %s instead.'
                           % in_favor_of) if in_favor_of else ''
            warnings.warn('%s has been deprecated in %s and will be '
                          'removed in the next release.%s' %
                          (func.__name__, as_of, replaced_by))
            return func(*args, **kwargs)
        return __wrapper
    return __inner
_VERSION = '1.8.0'

_KEY = '_%s_%s' % (__name__.replace('.', '_'), uuid.uuid4().hex)
_STORE = threading.local()

@_deprecated(as_of=_VERSION, in_favor_of='oslo_context.context.get_current')
def get_local_context(ctxt):
    """Retrieve the RPC endpoint request context for the current thread.

    This method allows any code running in the context of a dispatched RPC
    endpoint method to retrieve the context for this request.

    This is commonly used for logging so that, for example, you can include the
    request ID, user and tenant in every message logged from a RPC endpoint
    method.

    :returns: the context for the request dispatched in the current thread
    """
    return getattr(_STORE, _KEY, None)

@_deprecated(as_of=_VERSION)
def set_local_context(ctxt):
    _set_local_context(ctxt)

def _set_local_context(ctxt):
    """Set the request context for the current thread.

    :param ctxt: a deserialized request context
    :type ctxt: dict
    """
    setattr(_STORE, _KEY, ctxt)

@_deprecated(as_of=_VERSION)
def clear_local_context():
    _clear_local_context()

def _clear_local_context():
    """Clear the request context for the current thread."""
    delattr(_STORE, _KEY)


text:
package nl.ru.cs.ecalogic
package analysis

import org.scalatest.{FlatSpec, Matchers}
import java.io.File
import scala.io.Source
import parser.{Parser, Lexer}
import parser.Lexer.Tokens
import model._
import model.examples.BadComponent
import model.examples.StubComponent
import model.examples.DemoComponents._
import util._
import scala.collection.immutable.SortedMap

/**
 * @Author: Dorus Peelen
 */
class EnergyAnalysisSpec extends FlatSpec with Matchers {

  behavior of "The Energy Analysis"

  new File("doc/examples").listFiles().withFilter(_.getName.endsWith(".eca")).foreach { file =>
    //parse(f)
    val source = Source.fromFile(file).mkString
    val lexer = new Lexer(source)

    var (token, _) = lexer.next()
    while (token != Tokens.EndOfFile) {
      token match {
        case Tokens.Comment(c) if c.startsWith("expect") =>
          val params: String = c.substring(8, c.indexOf("("))

          val comment = c.substring(c.indexOf("("))
          val errorHandler = new DefaultErrorHandler(sourceText = Some(source), sourceURI = Some(file.toURI))

          val parser = new Parser(source, errorHandler)
          val program = parser.program()

          val dsl_components = Map("Stub"->StubComponent, "BUG"->BadComponent, "Sensor"->Sensor, "Radio"->Radio, "CPU"->CPU)

          it should s"succeed with Scala components for ${file.getName} ${params}" in {
            config.Options.reset
            config.Options.apply(params.split(" "))
            val analyzer = new EnergyAnalysis(program, dsl_components, errorHandler)
            val result = analyzer.analyse()._1.transform((_,st)=>st.energy)
            val resultString = (SortedMap.empty[String, Polynomial] ++ result._1, result._2).toString
            resultString should equal (comment)
          }

          it should s"succeed with imported components for ${file.getName} ${params}" in {
            config.Options.reset
            config.Options.apply(params.split(" "))
            val imported_components = ComponentModel.fromImports(program.imports, errorHandler)
            errorHandler.successOrElse("Error importing")
            val analyzer = new EnergyAnalysis(program, dsl_components++imported_components, errorHandler)
            val result = analyzer.analyse()._1.transform((_,st)=>st.energy)
            val resultString = (SortedMap.empty[String, Polynomial] ++ result._1, result._2).toString
            resultString should equal (comment)
          }

        case _ =>
      }
      token = lexer.next()._1
    }

  }

}


text:
define(function(require, exports, module) {
    "use strict";

    var app = require("app");
    var async = require("async");
    var moment = require("moment");

    // view
    var AbstractView = require("modules/view/AbstractView");
    var ArticleListView = require("modules/view/news/ArticleListView");
    var GridListView = require("modules/view/news/GridListView");
    var RecommendArticleView = require("modules/view/news/RecommendArticleView");
    var ArticleListItemView = require("modules/view/news/ArticleListItemView");
    var EventListItemView = require("modules/view/news/EventListItemView");
    var YouTubeListItemView = require("modules/view/news/YouTubeListItemView");
    var CondolenceListView = require("modules/view/news/condolence/CondolenceListView");

    // models
    var ArticleModel = require("modules/model/article/ArticleModel");

    // collections
    var ArticleCollection = require("modules/collection/article/ArticleCollection");
    var RecommendCollection = require("modules/collection/article/RecommendCollection");
    var FavoriteCollection = require("modules/collection/article/FavoriteCollection");
    var EventsCollection = require("modules/collection/events/EventsCollection");
    var NewspaperHolidayCollection = require("modules/collection/misc/NewspaperHolidayCollection");

    // util
    var DateUtil = require("modules/util/DateUtil");
    var BusinessUtil = require("modules/util/BusinessUtil");
    var vexDialog = require("vexDialog");
    var Code = require("modules/util/Code");
    var IsNull = require("modules/util/filter/IsNull");
    var Equal = require("modules/util/filter/Equal");
    var And = require("modules/util/filter/And");
    var Or = require("modules/util/filter/Or");
    var Le = require("modules/util/filter/Le");
    var Ge = require("modules/util/filter/Ge");

    /**
     * 記事一覧・詳細のメインとなる画面のViewクラスを作成する。
     * @class 記事一覧・詳細のメインとなる画面のViewクラス
     * @exports NewsView
     * @constructor
     */
    var NewsView = AbstractView.extend({

        template : require("ldsh!templates/{mode}/news/news"),
        model : new ArticleModel(),
        fetchCounter : 0,
        articleCollection : new ArticleCollection(),
        recommendCollection : new RecommendCollection(),
        favoriteCollection : new FavoriteCollection(),
        eventsCollection : new EventsCollection(),
        newsCollection : new Backbone.Collection(),
        events : {
            "click [data-article-id]" : "onClickGridItem"
        },
        beforeRendered : function() {
        },

        afterRendered : function() {
            var self = this;
            _.each(app.serverConfig.COLOR_LABEL, function(c) {
                self.$el.prepend("");
            });
        },

        /**
         * 初期化処理
         * @memberOf NewsView#
         */
        initialize : function(options) {
            options = options || {};

            this.targetDate = this.targetDate || options.date;
            this.initialScrollTop = options.scrollTop || 0;

            // 休刊日情報の読み込み
            var holCol = new NewspaperHolidayCollection();
            holCol.prevPublished(this.targetDate, function(prev, isPublish, err) {
                if (err) {
                    this.showErrorMessage("休刊日の取得", err);
                    this.hideLoading();
                    return;
                }
                if (isPublish) {
                    // 記事読み込み範囲設定
                    this.setArticleSearchCondition(moment(prev).add(1, "d").toDate(), new Date(this.targetDate));
                    // 記事読み込み
                    this.searchArticles();
                } else {
                    // 休刊日
                    this.hideLoading();
                    vexDialog.defaultOptions.className = 'vex-theme-default';
                    vexDialog.alert("休刊日です。");
                }
            }.bind(this));
            this.initEvents();
        },

        /**
         * 記事の検索条件を指定する。
         * @param {Object} 検索条件。現在、targetDateプロパティにDateオブジェクトを指定可能。
         * @memberOf NewsView#
         */
        setArticleSearchCondition : function(from, to) {
            this.articleCollection.setSearchConditionRange(from, to);
            this.recommendCollection.setSearchCondition({targetDate: from});
            this.eventsCollection.setSearchCondition({targetDate: from});
        },

        /**
         * イベントを初期化する
         * @memberOf NewsView#
         */
        initEvents : function() {
            this.listenTo(app.router, "route", this.onRoute);
            $(document).on("open:modal", this.onOpenModal.bind(this));
            $(document).on("close:modal", this.onCloseModal.bind(this));
        },

        /**
         * 記事の検索処理を開始する。
         * @memberOf NewsView#
         */
        searchArticles : function() {
            this.trackPageView();

            this.showLoading();

            // 現在保持しているデータをクリア
            this.articleCollection.reset();
            this.recommendCollection.reset();
            this.eventsCollection.reset();

            async.parallel([
                    this.loadYouTubeLibrary.bind(this), this.loadArticle.bind(this), this.loadRecommend.bind(this),
                    this.loadEvents.bind(this)
            ], this.onFetchAll.bind(this));
        },

        /**
         * youtubeライブラリを読み込む
         * @param {Function} callback
         * @memberOf NewsView#
         */
        loadYouTubeLibrary : function(callback) {
            if (app.gapiLoaded) {
                callback();
                return;
            }
            var self = this;
            var loadScript = function(url) {
                return function(next) {
                    $.getScript(url).done(function() {
                        next(null);
                    }).fail(function(jqXHR, settings, err) {
                        next(err);
                    });
                };
            };
            var onLoadGAPI = function(next) {
                window.onLoadGAPI = function() {
                    delete window.onLoadGAPI;
                    next(null);
                };

                loadScript("https://apis.google.com/js/client.js?onload=onLoadGAPI")(function(err) {
                    if (err) {
                        next(err);
                        return;
                    }
                });
            };
            async.series([
                    onLoadGAPI, loadScript("https://www.youtube.com/iframe_api")
            ], function(err) {
                if (!err) {
                    app.gapiLoaded = true;
                } else {
                    err = "NewsView#loadYouTubeLibrary: " + err;
                }
                callback(err);
            });
        },

        /**
         * articleを読み込む
         * @param {Function} callback
         * @memberOf NewsView#
         */
        loadArticle : function(callback) {
            var self = this;
            var cache = app.useCache;

            this.articleCollection.fetch({
                cache : cache,

                success : function() {
                    self.loadFavorite(callback);
                },

                error : function onErrorLoadArticle(model, resp, options) {
                    callback(resp);
                }
            });
        },

        /**
         * favoriteを読み込む
         * @param {Function} callback
         * @memberOf NewsView#
         */
        loadFavorite : function(callback) {
            this.favoriteCollection.condition.filters = [
                new Equal("userId", app.user.get("__id"))
            ];

            this.favoriteCollection.fetch({
                cache : app.useCache,

                success : function() {
                    callback();
                },

                error : function onErrorLoadFavorite(model, resp, options) {
                    callback(resp);
                }
            });
        },

        /**
         * eventsを読み込む
         * @param {Function} callback
         * @memberOf NewsView#
         */
        loadEvents : function(callback) {
            this.eventsCollection.reset();
            this.eventsCollection.fetch({
                cache : app.useCache,

                success : function() {
                    callback();
                },

                error : function onErrorLoadEvents(model, resp, options) {
                    callback(resp);
                }
            });
        },
        /**
         * Recommendを読み込む
         * @param {Function} callback
         * @memberOf NewsView#
         */
        loadRecommend : function(callback) {
            this.recommendCollection.fetch({
                cache : app.useCache,

                success : function() {
                    callback();
                },

                error : function(model, resp, options) {
                    callback(resp);
                }
            });
        },

        /**
         * 全ての情報検索完了後のコールバック関数
         * @param {Error|Undefined} err
         * @memberOf NewsView#
         */
        onFetchAll : function(err) {
            var targetDate = new Date(this.targetDate);

            if (err) {
                this.hideLoading();
                this.showErrorMessage("新聞情報の取得", err);
                return;
            }

            $(".contents__primary").scrollTop(0);

            // this.newsCollection.add(this.youtubeCollection.models);
            this.newsCollection.reset();
            this.newsCollection.add(this.articleCollection.models);
            this.newsCollection.add(this.eventsCollection.models);

            // articleCollectionに切抜き、おすすめ状態を反映する
            this.newsCollection.each($.proxy(function(article) {
                this.favoriteCollection.each(function(favorite) {
                    if (article.get("__id") === favorite.get("source")) {
                        article.set("isFavorite", !favorite.get("deletedAt"));
                        article.favorite = favorite;
                    }
                });

                // おすすめ数取得
                var recommends = this.recommendCollection.filter($.proxy(function(recommend) {
                    return article.get("__id") === recommend.get("source");
                }, this));
                article.recommendAmount = _.filter(recommends, function(recommend) {
                    return !recommend.get("deletedAt");
                }).length;

                // 自身のおすすめ情報を記事に付加
                _.each(recommends, $.proxy(function(recommend) {
                    if (recommend.get("isMine")) {
                        article.set("isMyRecommend", !recommend.get("deletedAt"));
                        article.recommend = recommend;
                    }
                }, this));

            }, this));

            // おすすめ記事を検索し、表示する
            var recommendArticle = this.newsCollection.find($.proxy(function(article) {
                return article.get("isRecommend") === "true" && article.get("publishedAt") === this.targetDate;
            }, this));

            if (recommendArticle) {
                // おすすめ記事を表示する
                var articleView = new RecommendArticleView({
                    model : recommendArticle
                });
                this.setView("#recommendArticle", articleView).render();
            } else {
                this.$(".recommendArticleContainer").hide();
            }

            // 新聞アプリおよび管理アプリプレビュー表示の場合、写真投稿、おくやみを1件の表示するための処理を行う
            if (!app.user.isGuest()) {
                this.summarizeArticle("8", {
                    targetDate : targetDate,
                    idPreffex : "condolence-",
                    dispTitle : (moment(targetDate).format("YYYY年M月DD日")) + "の" + "おくやみ",
                    sortOrder: -1
                });
            }
            this.summarizeArticle("6", {
                targetDate : targetDate,
                idPreffex : "letter-",
                title : "みんなで投稿!撮れたて写真館",
                dispTitle : "みんなで投稿!撮れたて写真館",
                sortOrder: 1,
                isFirst : true
            });

            // GridListView初期化
            this.showGridListView();

            // 初期スクロール位置が指定されている場合、スクロールする
            this.initScrollTop();

            // ローディング画面を閉じる
            this.hideLoading();
        },
        /**
         * 指定された記事タイプの記事を、1つの記事にまとめる
         *

         * 指定された記事タイプの記事を1つの記事にまとめて、ArticleCollectionの先頭に挿入する。

         * optionsパラメタに、まとめられた記事に関する、以下の情報を設定する。
         *

         *
{String} idPreffex

         * 作成する記事情報のIDのプレフィック

         *
{String} dispTitle

         * 記事一覧に表示される記事タイトル

         *
{Boolean} isFirst

         * まとめた記事を常に先頭に追加する場合はtrueを指定。(デフォルトはfalse)

         *

         *

         * @param {String} type 記事タイプ
         * @param {Object} options 記事作成時のオプション情報
         * @memberOf NewsView#
         */
        summarizeArticle : function(type, options) {
            var isFirst = options && options.isFirst;
            if (app.config.basic.mode === Code.APP_MODE_NEWS || this.isPreview) {

                // 指定された記事タイプのカテゴリ名を取得
                var articleCategory = _.find(Code.ARTICLE_CATEGORY_LIST, function(category) {
                    return category.key === type;
                });
                var siteLabel;
                if (articleCategory) {
                    siteLabel = articleCategory.value;
                }

                var newsArticles = this.newsCollection.toArray().concat();

                var articleDateMap = {};
                var imagePath;
                var imageThumbUrl;

                // newsCollectionからまとめる記事を削除し、配列に追加する
                var firstArticleIdx = -1;
                _.each(newsArticles, $.proxy(function(article, idx) {
                    if (article.get("type") !== type) {
                        return;
                    }

                    // 最初に出現した位置を記憶する。
                    if (firstArticleIdx < 0) {
                        firstArticleIdx = idx;
                    }

                    // 日付ごとのマップに入れ替える。
                    var publishedAt = article.get("publishedAt");
                    var articleModel = articleDateMap[publishedAt];
                    if (!articleModel) {
                        articleModel = new ArticleModel({
                            __id : options.idPreffex + (moment(publishedAt).format("YYYY-MM-DD")),
                            site : article.get("site"),
                            dispTitle : (moment(publishedAt).format("YYYY年M月DD日")) + "の" + siteLabel,
                            type : type,
                            articles : []
                        });
                        articleDateMap[article.get("publishedAt")] = articleModel;
                    }

                    var articleList = articleModel.get("articles");
                    this.newsCollection.remove(article);
                    articleList.push(article);

                }, this));
                if (firstArticleIdx < 0) {
                    firstArticleIdx = this.newsCollection.size();
                }

                var articleDateList = [];
                _.each(articleDateMap, function(articleDate) {
                    articleDateList.push(articleDate);
                });
                // 日付順にソートする
                articleDateList.sort(function(a, b) {
                    var pa = a.get("__id");
                    var pb = b.get("__id");
                    if (pa === pb) {
                        return 0;
                    }
                    if (pa < pb) {
                        return options.sortOrder;
                    } else if (pa > pb) {
                        return -1 * options.sortOrder;
                    }
                });
                // 写真投稿新着件数
                var newArrivals;
                if (type === "6") {
                    var currentPublishLetters = articleDateMap[app.currentPublishDate];
                    if (currentPublishLetters) {
                        newArrivals = currentPublishLetters.get("articles").length;
                    }

                    _.each(articleDateList, function(articleData) {
                        var articleList = articleData.get("articles");
                        articleList = _.sortBy(articleData.get("articles"),function(article) {
                            return -new Date(article.get("createdAt")).getTime();
                        });
                        articleData.set("articles", articleList);
                    });
                    var firstArticles = _.first(articleDateList) && _.first(articleDateList).get("articles");
                    var firstArticle;
                    if (firstArticles && firstArticles.length > 0) {
                        firstArticle = firstArticles[0];
                    }
                    // 一番最初の記事のサムネイルを
                    // まとめた後の記事のサムネイルとして設定する
                    if (firstArticle) {
                        imagePath = firstArticle.get("imagePath") ;
                        imageThumbUrl = firstArticle.get("imageThumbUrl");
                    }
                }

                // まとめ記事画面を開くための記事を作成し、コレクションの適切な位置に追加
                var folderArticle = new ArticleModel({
                    __id : options.idPreffex + DateUtil.formatDate(options.targetDate, "yyyy-MM-dd"),
                    site : _.indexBy(app.serverConfig.COLOR_LABEL, "type")[type].label,
                    title : options.title,
                    dispTitle : options.dispTitle,
                    publishedAt : DateUtil.formatDate(options.targetDate, "yyyy-MM-dd"),
                    type : type,
                    articles : articleDateList,
                    newArrivals : newArrivals,
                    imagePath : imagePath,
                    imageThumbUrl : imageThumbUrl,
                    period : _.indexBy(app.serverConfig.COLOR_LABEL, "type")[type].period
                });
                // isFirst指定がある場合は先頭に配置する。
                if (isFirst) {
                    firstArticleIdx = 0;
                }
                this.newsCollection.models.splice(firstArticleIdx, 0, folderArticle);
                this.articleCollection.models.splice(firstArticleIdx, 0, folderArticle);
            }
        },
        /**
         * 記事一覧Viewを表示する要素のセレクタ
         * @memberOf NewsView#
         */
        feedListElement : "#contents__top",
        /**
         * 左ペインの記事一覧メニューを表示する。
         * @memberOf NewsView#
         */
        showGridListView : function() {
            var gridListView = this.createGridListView();
            gridListView.collection = this.newsCollection;

            this.removeView(this.gridListElement);

            this.setView(this.feedListElement, gridListView);
            gridListView.render();

            if (this.newsCollection.size() === 0) {
                this.showFeetNotFoundMessage();
            }
        },

        /**
         * 記事が見つからなかった場合のメッセージを画面に表示する。
         * @memberOf NewsView#
         */
        showFeetNotFoundMessage : function() {
            this.$el.find(NewsView.SELECTOR_ARTICLE_LIST).hide();
            this.$el.find(NewsView.SELECTOR_NOTFOUND).show();
        },

        /**
         * 右ペインの記事一覧を表示するViewのインスタンスを作成して返す。
         * @return {GridListView} 生成したGridListViewのインスタンス
         * @memberOf NewsView#
         */
        createGridListView : function() {
            return new GridListView();
        },

        /**
         * 右ペインの記事一覧を表示する。
         * @memberOf NewsView#
         */
        showArticleListView : function() {
            var articleListView = new ArticleListView();
            articleListView.collection = this.newsCollection;
            this.removeView("#article-list");
            this.setView("#article-list", articleListView);
            articleListView.render();

            // 初期スクロール位置が指定されている場合、スクロールする
            this.initScrollTop();
        },

        /**
         * News一覧の各Gridがクリックされたときの動作
         *
         * @param {jQuery.Event} ev
         * @param {Object} param
         * @memberOf NewsView#
         */
        onClickGridItem : function(ev, param) {
            var articleId = $(ev.currentTarget).attr("data-article-id");
            app.newsView = this;

            var model = this.articleCollection.find(function(article) {
                return article.get("__id") === articleId;
            });
            if (model.isExpired()) {
                vexDialog.defaultOptions.className = 'vex-theme-default';
                vexDialog.alert("掲載期間が終了しました。");
                return;
            }
            app.router.go("top", moment(app.currentDate).format("YYYY-MM-DD"), "article", articleId);
        },

        /**
         * 指定された記事IDの記事を表示する。
         * @param articleId {String} 記事ID
         * @memberOf NewsView#
         */
        showArticle : function(articleId) {
            var model = this.articleCollection.find(function(article) {
                return article.get("__id") === articleId;
            });
            if (!model) {
                vexDialog.defaultOptions.className = 'vex-theme-default';
                vexDialog.alert("指定された記事は存在しません。");
                return;
            }
            var template = require("ldsh!templates/{mode}/news/articleListItem");
            // 記事一覧に追加するViewクラス。
            // 以下の分岐処理で、対象のデータを表示するViewのクラスが設定される。
            var ListItemView;

            switch (model.get("type")) {
            case "1": // RSS
            case "7": // Facebook
                template = require("ldsh!templates/{mode}/news/articleListItem");
                ListItemView = ArticleListItemView;
                if (model.get("rawHTML")) {
                    template = require("ldsh!templates/{mode}/news/articleListItemForHtml");
                }
                break;
            case "2": // YouTube
                template = require("ldsh!templates/{mode}/news/youTubeListItem");
                ListItemView = YouTubeListItemView;
                break;
            case "6": // 写真投稿
                template = require("ldsh!templates/{mode}/news/letterDetail");
                ListItemView = EventListItemView;
                break;
            case "8": // おくやみ
                template = require("ldsh!templates/{mode}/news/condolence/condolenceList");
                ListItemView = CondolenceListView;
                break;
            default:
                template = require("ldsh!templates/{mode}/news/eventsDetail");
                ListItemView = EventListItemView;
                break;
            }

            // 既にレンダリングされている要素をクリアする
            var dest = this.getView(NewsView.SELECTOR_ARTICLE_DESTINATION);
            if (dest) {
                dest.remove();
            }

            this.insertView(NewsView.SELECTOR_ARTICLE_DESTINATION, new ListItemView({
                model : model,
                template : template
            })).render();
            $("#contents__secondary").hide();
            $("#contents__primary").show();

            // TODO 各記事のviewで行いたい
            $("#snap-content").scrollTop(0);
            $(".backnumber-scroll-container").scrollTop(0);
        },

        /**
         * 新聞に戻るボタンを設定する
         * @memberOf NewsView#
         */
        updateFooterButtons : function() {
            var self = this;
            var $btnBack = this.$el.find("#news-action").find("[data-back]");
            var currentMoment = moment(app.currentDate);
            var currentDateStr = currentMoment.format("YYYY-MM-DD");

            $btnBack.on("click", function(ev) {
                app.ga.trackEvent("記事詳細ページ", "一覧に戻る","");

                ev.preventDefault();
                app.router.back();
            });
        },

        /**
         * 初期スクロール位置が指定されている場合、スクロールする
         * @memberOf NewsView#
         */
        initScrollTop : function() {
            if (this.initialScrollTop || this.initialScrollTop === 0) {
                this.setScrollTop(this.initialScrollTop);
            }
        },

        /**
         * 記事一覧の現在のスクロール位置を設定する
         * @param {Number} scrollTop
         * @memberOf NewsView#
         */
        setScrollTop : function(scrollTop) {
            var $container = $("#snap-content");

            $container.scrollTop(scrollTop);
        },

        /**
         * 記事一覧の現在のスクロール位置を取得する
         * @return {Number}
         * @memberOf NewsView#
         */
        getScrollTop : function() {
            var $container = $("#snap-content");
            var scrollTop = $container.scrollTop();

            return scrollTop;
        },

        /**
         * モーダルウィンドウが開いた後に呼ばれる
         * @memberOf TopView#
         */
        onOpenModal : function() {
            $("body").addClass("has-modal");
        },

        /**
         * モーダルウィンドウが閉じた後に呼ばれる
         * @memberOf TopView#
         */
        onCloseModal : function() {
            $("body").removeClass("has-modal");
        },

        /**
         * 記事詳細ページ以外では、記事詳細の要素を隠す
         * @memberOf NewsView#
         */
        onRoute : function(route) {
            if (route === "settings") {
            } else if (route === "showArticle") {
                $(NewsView.SELECTOR_ARTICLE_LIST).hide();
                $(NewsView.SELECTOR_ARTICLE_CONTAINER).show();
            } else {
                $(NewsView.SELECTOR_ARTICLE_LIST).show();
                $(NewsView.SELECTOR_ARTICLE_CONTAINER).hide();
            }

            $("#main").removeClass("is-top");
            $("#main").removeClass("is-article");
            $("#main").removeClass("is-backnumber");

            if (route === "top") {
                $("#main").addClass("is-top");
            } else if (route === "showArticle") {
                $("#main").addClass("is-article");
            } else if (route === "backnumber") {
                $("#main").addClass("is-backnumber");
            }

            if ( route !== "top" ) {
                this.updateFooterButtons();
            }
        },

        /**
         * ビューが破棄される時に呼ばれる
         * @memberOf NewsView#
         */
        cleanup : function() {
            $("#main").removeClass("is-top");
            $("#main").removeClass("is-article");
        },

        /**
         * Google Analyticsでページビューを記録する
         * @memberOf NewsView#
         */
        trackPageView : function() {
            app.ga.trackPageView("Top","TOPページ");
        }
    }, {
        /**
         * 記事詳細及び戻るボタンのコンテナのセレクタ
         */
        SELECTOR_ARTICLE_CONTAINER : "[data-news-container]",

        /**
         * 記事詳細を挿入する先のセレクタ
         */
        SELECTOR_ARTICLE_DESTINATION : "[data-news-detail]",

        /**
         * 記事一覧のセレクタ
         */
        SELECTOR_ARTICLE_LIST : "#contents__top",

        /**
         * 記事情報がない場合に出すnotificationのセレクタ
         */
        SELECTOR_NOTFOUND : "#not-found"
    });

    module.exports = NewsView;
});


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />

  <title>Conference Talk Media Type</title>

  <link href="#rfc.toc" rel="Contents"/>
<link href="#rfc.section.1" rel="Chapter" title="1 Introduction"/>
<link href="#rfc.section.1.1" rel="Chapter" title="1.1 Goals"/>
<link href="#rfc.section.1.2" rel="Chapter" title="1.2 Usage Scenarios"/>
<link href="#rfc.section.1.3" rel="Chapter" title="1.3 Notational Conventions"/>
<link href="#rfc.section.2" rel="Chapter" title="2 Conference Talk JSON Document"/>
<link href="#rfc.section.3" rel="Chapter" title="3 Structure"/>
<link href="#rfc.section.3.1" rel="Chapter" title="3.1 Root"/>
<link href="#rfc.section.3.2" rel="Chapter" title="3.2 1:1 Relationships"/>
<link href="#rfc.section.3.3" rel="Chapter" title="3.3 1:M Relationships"/>
<link href="#rfc.section.3.4" rel="Chapter" title="3.4 Links"/>
<link href="#rfc.section.3.4.1" rel="Chapter" title="3.4.1 link"/>
<link href="#rfc.section.4" rel="Chapter" title="4 Vocabulary"/>
<link href="#rfc.section.4.1" rel="Chapter" title="4.1 Arrays of Structures"/>
<link href="#rfc.section.4.1.1" rel="Chapter" title="4.1.1 sessions"/>
<link href="#rfc.section.4.1.2" rel="Chapter" title="4.1.2 presentations"/>
<link href="#rfc.section.4.1.3" rel="Chapter" title="4.1.3 presenters"/>
<link href="#rfc.section.4.1.4" rel="Chapter" title="4.1.4 conferences"/>
<link href="#rfc.section.4.2" rel="Chapter" title="4.2 session"/>
<link href="#rfc.section.4.2.1" rel="Chapter" title="4.2.1 presentation-date"/>
<link href="#rfc.section.4.2.2" rel="Chapter" title="4.2.2 location"/>
<link href="#rfc.section.4.2.3" rel="Chapter" title="4.2.3 attendee-quantity"/>
<link href="#rfc.section.4.3" rel="Chapter" title="4.3 presenter"/>
<link href="#rfc.section.4.3.1" rel="Chapter" title="4.3.1 name"/>
<link href="#rfc.section.4.3.2" rel="Chapter" title="4.3.2 email"/>
<link href="#rfc.section.4.3.3" rel="Chapter" title="4.3.3 airport"/>
<link href="#rfc.section.4.3.4" rel="Chapter" title="4.3.4 dietary-requirement"/>
<link href="#rfc.section.4.3.5" rel="Chapter" title="4.3.5 t-shirt-preference"/>
<link href="#rfc.section.4.4" rel="Chapter" title="4.4 presentation"/>
<link href="#rfc.section.4.4.1" rel="Chapter" title="4.4.1 title"/>
<link href="#rfc.section.4.4.2" rel="Chapter" title="4.4.2 brief-description"/>
<link href="#rfc.section.4.4.3" rel="Chapter" title="4.4.3 full-description"/>
<link href="#rfc.section.4.4.4" rel="Chapter" title="4.4.4 target-audience"/>
<link href="#rfc.section.4.4.5" rel="Chapter" title="4.4.5 talk-style"/>
<link href="#rfc.section.4.4.6" rel="Chapter" title="4.4.6 selection-notes"/>
<link href="#rfc.section.4.4.7" rel="Chapter" title="4.4.7 tags"/>
<link href="#rfc.section.4.4.8" rel="Chapter" title="4.4.8 length"/>
<link href="#rfc.section.4.4.9" rel="Chapter" title="4.4.9 languages"/>
<link href="#rfc.section.4.4.10" rel="Chapter" title="4.4.10 special-requirements"/>
<link href="#rfc.section.4.5" rel="Chapter" title="4.5 conference"/>
<link href="#rfc.section.4.5.1" rel="Chapter" title="4.5.1 talk-style-domain"/>
<link href="#rfc.section.4.5.2" rel="Chapter" title="4.5.2 tags-domain"/>
<link href="#rfc.section.4.5.3" rel="Chapter" title="4.5.3 languages-domain"/>
<link href="#rfc.section.4.5.4" rel="Chapter" title="4.5.4 brief-description-max-size"/>
<link href="#rfc.section.4.5.5" rel="Chapter" title="4.5.5 full-description-max-size"/>
<link href="#rfc.section.4.5.6" rel="Chapter" title="4.5.6 t-shirt-domain"/>
<link href="#rfc.section.4.5.7" rel="Chapter" title="4.5.7 dietary-requirement-domain"/>
<link href="#rfc.section.5" rel="Chapter" title="5 Link Relations"/>
<link href="#rfc.section.5.1" rel="Chapter" title="5.1 video-recording"/>
<link href="#rfc.section.5.1.1" rel="Chapter" title="5.1.1 slides"/>
<link href="#rfc.section.5.1.2" rel="Chapter" title="5.1.2 presenter"/>
<link href="#rfc.section.5.1.3" rel="Chapter" title="5.1.3 presentations"/>
<link href="#rfc.section.5.1.4" rel="Chapter" title="5.1.4 conference"/>
<link href="#rfc.section.6" rel="Chapter" title="6 IANA Considerations"/>
<link href="#rfc.section.6.1" rel="Chapter" title="6.1 Registrations"/>
<link href="#rfc.section.7" rel="Chapter" title="7 Security Considerations"/>
<link href="#rfc.section.8" rel="Chapter" title="8 Appendix 1 : Mapping to HTML"/>
<link href="#rfc.section.9" rel="Chapter" title="9 Appendix 2 : Mapping to ALPS"/>
<link href="#rfc.section.10" rel="Chapter" title="10 Appendix 3 : Mapping to SIREN"/>
<link href="#rfc.section.11" rel="Chapter" title="11 Appendix 4 : Mapping to JSON-LD"/>
<link href="#rfc.references" rel="Chapter" title="12 Normative References"/>
<link href="#rfc.appendix.A" rel="Chapter" title="A Acknowledgements"/>
<link href="#rfc.authors" rel="Chapter"/>

  <meta name="generator" content="xml2rfc version 2.4.12 - http://tools.ietf.org/tools/xml2rfc" />
  <link rel="schema.dct" href="http://purl.org/dc/terms/" />

  <meta name="dct.creator" content="Miller, D." />
  <meta name="dct.identifier" content="urn:ietf:id:draft-miller-conference-talk-01" />
  <meta name="dct.issued" scheme="ISO8601" content="2015-12-9" />
  <meta name="dct.abstract" content="This draft document is a media type specification for describing a conference talk proposals, presenters and presentations.  This format aims to standardize the format of information shared between software components used by conference organizers, speakers and attendees. It is intended to reduce the effort required for speakers to submit session proposals and for conference organizers to process those submissions." />
  <meta name="description" content="This draft document is a media type specification for describing a conference talk proposals, presenters and presentations.  This format aims to standardize the format of information shared between software components used by conference organizers, speakers and attendees. It is intended to reduce the effort required for speakers to submit session proposals and for conference organizers to process those submissions." />

  Network Working Group
  D. Miller

  Internet-Draft
  Tavis Software Inc.

  Intended status: Informational
  December 9, 2015

  Expires: June 11, 2016

Conference Talk Media Type

  draft-miller-conference-talk-01

  Abstract

This draft document is a media type specification for describing a conference talk proposals, presenters and presentations.  This format aims to standardize the format of information shared between software components used by conference organizers, speakers and attendees. It is intended to reduce the effort required for speakers to submit session proposals and for conference organizers to process those submissions.

  Note to Readers

The issues list for this draft can be found at https://github.com/darrelmiller/conference-talk/issues.

  Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF).  Note that other groups may also distribute working documents as Internet-Drafts.  The list of current Internet-Drafts is at http://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time.  It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on June 11, 2016.

  Copyright Notice

Copyright (c) 2015 IETF Trust and the persons identified as the document authors.  All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document.  Please review these documents carefully, as they describe your rights and restrictions with respect to this document.  Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

Table of Contents

1.   Introduction

1.1.   Goals

1.2.   Usage Scenarios

1.3.   Notational Conventions

2.   Conference Talk JSON Document

3.   Structure

3.1.   Root

3.2.   1:1 Relationships

3.3.   1:M Relationships

3.4.   Links

3.4.1.   link

4.   Vocabulary

4.1.   Arrays of Structures

4.1.1.   sessions

4.1.2.   presentations

4.1.3.   presenters

4.1.4.   conferences

4.2.   session

4.2.1.   presentation-date

4.2.2.   location

4.2.3.   attendee-quantity

4.3.   presenter

4.3.1.   name

4.3.2.   email

4.3.3.   airport

4.3.4.   dietary-requirement

4.3.5.   t-shirt-preference

4.4.   presentation

4.4.1.   title

4.4.2.   brief-description

4.4.3.   full-description

4.4.4.   target-audience

4.4.5.   talk-style

4.4.6.   selection-notes

4.4.7.   tags

4.4.8.   length

4.4.9.   languages

4.4.10.   special-requirements

4.5.   conference

4.5.1.   talk-style-domain

4.5.2.   tags-domain

4.5.3.   languages-domain

4.5.4.   brief-description-max-size

4.5.5.   full-description-max-size

4.5.6.   t-shirt-domain

4.5.7.   dietary-requirement-domain

5.   Link Relations

5.1.   video-recording

5.1.1.   slides

5.1.2.   presenter

5.1.3.   presentations

5.1.4.   conference

6.   IANA Considerations

6.1.   Registrations

7.   Security Considerations

8.   Appendix 1 : Mapping to HTML

9.   Appendix 2 : Mapping to ALPS

10.   Appendix 3 : Mapping to SIREN

11.   Appendix 4 : Mapping to JSON-LD

12.   Normative References

Appendix A.   Acknowledgements

Author's Address

1. Introduction

In the technology world, one way we share knowledge is via conferences.  In order to have a conference we need speakers to do talks.  Conferences commonly go through a process called call for proposals (CFP) where speakers who are interested submit talk proposals to the conference and then the conference organizers sift through these proposals and select the talks they believe will provide the best value to their attendees.

There are a very wide range of methods used by conferences for collecting these proposals:  Google docs, Excel spreadsheets, plain text emails, wikis, custom web sites, commercial conference management systems.  Each of these systems have slightly different ways of collecting information that is mostly the same.

Many conferences are run by volunteers with minimal budgets and many speakers do so at their own expense.  Any possibility to improve the efficiency of the process of submitting proposals and processing them could provide significant value to a large number of conference participants.

1.1. Goals

Easier for speakers to submit

Easy for authoring tools to generate

Minimal formatting capability

Author once, submit anywhere with minimal changes

Hypermedia links to presenter info.

Easier for conference organizers to process

Simple for conference organizers to import

Zero UI submission process.

Easier to process submissions (queryable structures)

Standard UIs can be built to process submission format

1.2. Usage Scenarios

There are a wide range of scenarios that could be enabled by this common format:

Client Authoring tools that offer a good editing experience for creating new proposals.  (Maybe not, because it is not a content creation format)

Conference API for accepting proposals.

Convert to HTML/PDF for submission to non-automated conferences or for publication of selected talks on conference website.

Searchable repository of past talks with links to slides and videos.

Central repository of available speakers talks.  Reverse the process so that conferences go looking for speakers instead of the other way around.

1.3. Notational Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

2. Conference Talk JSON Document

The canonical model for a conference-talk document is a JSON object as defined in the I-JSON specification [RFC7493]. The properties of the JSON object can be any valid vocabulary term from this specification. Unrecognized vocabulary should be ignored unless a consumer explicitly requests strict processing of the document.

[Note]  Add comment about support of http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03

A minimal submission might look like this:

    { "session" : {
        "presentation" : {
            "title" : "An Introduction To Media Type Design",
            "brief-description" : "Blah Blah Blah",
            },
      "presenters" : [{
        "name" : "Darrel Miller"
       }]
      }
    }

A more complete session proposal might look like,

{
  "session": {
    "presentation" : {
      "title": "An Introduction To Media Type Design",
      "brief-description": "Blah Blah Blah",
      "full-description": "Even longer blah Blah Blah",
      "length": {
        "preferred": 60,
        "min": 45,
        "max": 90
      },
      "past-sessions": [{
        "presentation-date": "20150911",
        "conference": {
            "name" : "The Meta Conference"
        }
      }]
    },
    "slot-length" : 45,
    "keywords": ["javascript", "java", "http"],
    "presenters": [{
      "name": "Darrel Miller",
      "email": "darrel@example.com"
    },
    {
      "name" : "Bob Brown",
      "email" : "bob@yahoo.com"
      }]
  }
}

This specification is intended primarily to describe a message format to transfer information between two independent systems. Requirements of persistence formats or content creation formats are a secondary concern. JSON is ideal for this purpose. However, it should be fairly straightforward to apply the structure and semantics defined in this document to other formats.

3. Structure

This media type is designed to hold information related to conference presentations, their presenters and the information about presented sessions.  However, it imposes minimal structural constraints on the document. This is done in order to support as many scenarios as possible. A document instance may be used to submit a new proposal to a conference. Or it may be used to return a list of presentations that were held at a conference. It can also be used to return a list of presenters who will be speaking at a conference. The overall structure is fairly flexible, but the semantics of the named structures within the document are well defined.

A conference-talk document may be valid, but still incompatible with a particular resource that only accepts <samp>conference-talk</samp> documents structured in a certain way.

3.1. Root

The root of the document MUST be a JSON object, whose properties names are structures defined in this vocabulary.

    {
      "presenter" : {...} },
      "sessions" : [...] },
      "presentations" : [...] },
    }

There is no fixed structure to the root object. It can contain any number of properties that are either objects or arrays.

3.2. 1:1 Relationships

Certain structures can contain other structures in a 1:1 relationship. E.g.

A <samp>session</samp> structure can contain a <samp>presentation</samp> structure describing the content of the presentation that was submitted.

A <samp>session</samp> structure can contain a <samp>conference</samp> structure indicating the conference at which the presentation was presented.

3.3. 1:M Relationships

Lists of structures can be contained as an attribute of other structures to indicate a relationship between the structures.  For example:

<samp>presenter</samp> can have a list attribute called <samp>sessions</samp> containing <samp>session</samp> structures.

<samp>presenter</samp> can have a list attribute called <samp>presentations</samp> containing <samp>presentation</samp> structures.

<samp>presentation</samp> can have a list attribute called <samp>past-sessions</samp> containing <samp>session</samp> structures.

<samp>session</samp> can have a list attribute called <samp>presenters</samp> containing <samp>presenter</samp> structures.

3.4. Links

All structures defined in this vocabulary can contain a property called  <samp>links</samp>.  This property contains an array of <samp>link</samp> objects.  Links are a way to break apart pieces of the document for the purposes of reuse and controlling granularity.  Through the use of relative URIs and fragments we can use links with the document to reduce redundancy.

links : [
          { "rel" : "",
            "href" : ""},
          { "rel" : "",
            "href" : ""}
          ]

Note: There was no need to adopt the HAL convention of using _Links as the allowed vocabulary is explicitly defined for this media type.  The array of links was chosen instead of an object to allow multiple link relations of the same type without having to define multiple arrays.

3.4.1. link

3.4.1.1. rel

Link relations values defined in the <samp>conference-talk</samp> conference talk document can be used as simple strings as long as they are prefixed with a period. However, any parsing tool must map them to a URI using the following URI template https://tavis.net/rels/conference-talk/{relname}.

3.4.1.2. href

The href property can resolve to a relative URI and use relative fragment identifiers to point to content within the current document. Fragment identifiers follow the scheme defined by the JSON Pointer specification [RFC6901]. This prevents the need to duplicate content within a document.

For example, the sample below has an array of proposals, and each one points to a presenter structure and conference structure.

    { "sessions" : [
        {
          "presentation" : {
             "title" : "An Introduction To Media Type Design",
             "brief-description" : "Blah Blah Blah"
           },
            "links" [
              { "rel" : ".presenter", "href" : "#presenter"},
              { "rel" : ".conference", "href" : "#conference"}
            ]
        },
        {
          "presentation" : {
            "title" : "Crafting Evolvable Representations",
            "brief-description" : "Double blah"
            },
            "links" [
              { "rel" : ".presenter", "href" : "#presenter"},
              { "rel" : ".conference", "href" : "#conference"}
            ]
        },
    ],
  "presenter" : {
      "name" : "Darrel Miller",
      "bio"  : "Destined to re-invent RDF"
    },
  "conference" : {
      "name" : "The Meta Conference",
      "description"  : "The conference about conferences"
     }
    }

4. Vocabulary

4.1. Arrays of Structures

4.1.1. sessions

An array of <samp>session</samp> structures.

4.1.2. presentations

An array of <samp>presentation</samp> structures.

4.1.3. presenters

An array of <samp>presenter</samp> structures.

4.1.4. conferences

An array of <samp>conference</samp> structures.

4.2. session

The session structure represents a proposal to a conference and a record of the given presentation.  The  <samp>presentation</samp> and <samp>conference</samp> property are required.

4.2.1. presentation-date

This property represents the date that a particular talk was given. The date should be in ISO 8601 format as required by I-JSON.

4.2.2. location

The physical location where conference is being held. This can simply country or city and country. This is a string value.

4.2.3. attendee-quantity

This field is a number that provides an approximate quantity of people who attended the presentation.

4.3. presenter

A <samp>presenter</samp> structure represents the information about a person who will or who has presented a conference talk.

4.3.1. name

The name attribute is a string value that contains the name of the present for purposes of displaying the name.

4.3.2. email

The email property

email = <addr-spec see {{RFC2822}}, Section 3.4.1>

4.3.3. airport

The home airport of the presenter. This information is used to approximate travel costs for speakers and aid in the selection process. This is a string value.

4.3.4. dietary-requirement

An identifier that is related to a <samp>presenter</samp> selected from the list of available values as defined by the conference. This is a string value.

4.3.5. t-shirt-preference

An identifier that is related to a <samp>presenter</samp> selected from the list of available values as defined by the conference. This is a string value.

4.4. presentation

The <samp>presentation</samp> structure contains the descriptive details of the presentation to be proposed as a session at a conference.  All properties of the presentation structure can be duplicated in a containing <samp>session</samp> structure to provide conference specific values.

4.4.1. title

The title property is a single sentence description of the talk, normally used as a heading.  This is a required property.  Physical limits on the size of descriptive fields like this one are left to the choice of implementers.  If a specific implementation chooses to limit titles to 80 characters and it subsequently receives a document with a title that exceeds that amount, the implementation must choose whether to refuse the content, or to truncate it.

4.4.2. brief-description

Conferences often ask for short descriptions of sessions to be used on web sites or in promotional material. Some conferences insist on brief descriptions to reduce the time it takes for the selection committee to process the proposals.  This specification currently does not enforce the size of a brief description and therefore there may be cases where a brief-description submitted to one conference is not accepted to another because they have differing opinions on what brief means. Feedback will drive whether a hard limit is included in this specification.

4.4.3. full-description

Sometimes a brief description is sufficient to spark interest in a talk, but the reader wishes to get more details.  The full-description of the session can be used to go into detail about the presentation.  Implementations can choose whether this description is made public or not.

4.4.4. target-audience

Conference sessions are often rated based on their technical difficulty.This property is numeric value on the scale of 1 to 5, where 1 indicates no experience is required to benefit from the session, to 5 which indicates the audience require a strong knowledge in the subject matter to fully appreciate the talk.

target-audience : 1

Conference organizers are free to map this range of values to whatever equivalent ranking scheme they use.

4.4.5. talk-style

Style is an identifier that classifies the type of talk being submitted.  This value is a string identifier from a set of valid values as defined by the conference being submitted to.

talk-style : "workshop"

4.4.6. selection-notes

It is common for proposals to have additional information that is only directed at the selection committee. This information would not be made public.

4.4.7. tags

The tags attribute contains an array of strings used for the purpose of classifying talks into categories. Although different conferences may use different sets of tags, in a communication between speaker and conference organizer, only one set of tags is valid.  For client applications that might store conference proposals for speakers, it may be necessary to store multiple sets of tags to accomadate submissions to different conferences.  However, this specification is not aiming to describe a storage format.

tags : ["testing","performance"]

4.4.8. length

Different conferences have different sessions lengths.  Sometimes the same conference has sessions of different lengths.  It is not uncommon for speakers to have some flexibility in how long a particular talk can take.  In order to accomodate these different scenarios, the length property is defined using three values : <samp>preferred-length</samp>,<samp>max-length</samp> and <samp>min-length</samp>.  All three values are specified in integer minutes.  By specifying a range, conferences can determine if a talk can fit into the planned slots.

length : {
  "preferred" : 45,
  "max": 60,
  "min" : 30
}

4.4.9. languages

Some conferences are multi-lingual and sometimes speakers are able to perform talks in multiple languages.  The language property contains an array of language codes as described in [RFC5646].

language : ["en","fr"]

4.4.10. special-requirements

This is a free form text field used to communicate to the conference organizers any special hardware, setup, or environmental requirements needed for this talk to be presented. This is a string value.

4.5. conference

The <samp>conference</samp> structure is used to describe its purpose, its location, the timeline of events and the domains of valid values for properties like, <samp>tags</samp>, <samp>talk-style</samp> and <samp>languages</samp>.  It also can contain limits such as maximum lengths for <samp>brief-description</samp>, and <samp>full-description</samp>.

4.5.1. talk-style-domain

A set of valid values for the <samp>talk-style</samp> property. This domain of values is often defined within the <samp>conference</samp> structure.

talk-style-domain : ["workshop", "session","lightning-talk"]

4.5.2. tags-domain

A set of valid values for the <samp>tags</samp> property.  The domain of values is often defined within the <samp>conference</samp> structure.

4.5.3. languages-domain

A set of valid values for the <samp>languages</samp> property.  The domain of values is often defined within the <samp>conference</samp> structure.

4.5.4. brief-description-max-size

A numeric value usually defined within the <samp>conference</samp> structure to define the maximum length in characters of the <samp>brief-description</samp>.

4.5.5. full-description-max-size

A numeric value usually defined within the <samp>conference</samp> structure to define the maximum length in characters of the <samp>full-description</samp>.

4.5.6. t-shirt-domain

A set of valid values for the <samp>t-shirt</samp> property.  The domain of values is often defined within the <samp>conference</samp> structure.

4.5.7. dietary-requirement-domain

A set of valid values for the <samp>dietary-requirement</samp> property.  The domain of values is often defined within the <samp>conference</samp> structure.

5. Link Relations

5.1. video-recording

This is a URL that points to a video recording of the presentation.

5.1.1. slides

This is a URL that points to a the slide deck used in the presentation.

5.1.2. presenter

This is a URL that points to the details relating to the presenter of the presentation.

5.1.3. presentations

This is a URL that points to a list of presentations.

5.1.4. conference

This is a URL that points to information about a conference.

6. IANA Considerations

TK

6.1. Registrations

TK

7. Security Considerations

TK

8. Appendix 1 : Mapping to HTML

9. Appendix 2 : Mapping to ALPS

10. Appendix 3 : Mapping to SIREN

11. Appendix 4 : Mapping to JSON-LD

12. Normative References

        [RFC2119]

      Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997.

        [RFC2822]

      Resnick, P., "Internet Message Format", RFC 2822, DOI 10.17487/RFC2822, April 2001.

        [RFC5646]

      Phillips, A. and M. Davis, "Tags for Identifying Languages", BCP 47, RFC 5646, DOI 10.17487/RFC5646, September 2009.

        [RFC6901]

      Bryan, P., Zyp, K. and M. Nottingham, "JavaScript Object Notation (JSON) Pointer", RFC 6901, DOI 10.17487/RFC6901, April 2013.

        [RFC7493]

      Bray, T., "The I-JSON Message Format", RFC 7493, DOI 10.17487/RFC7493, March 2015.

Appendix A. Acknowledgements

  Author's Address

  <address class="vcard">

	  Darrel Miller

		Miller

	Tavis Software Inc.

	EMail: darrel@tavis.ca

URI: http://www.bizcoder.com

  </address>