This sample app demonstrates an advanced example of activation. It shows how to
register for "activated", "suspending", and "resuming" events and how to use these
to save state to a file and retrieve it during re-activation. Separately, in addition
to the launch activation, it also demonstrates the protocol activation as well as
how to identify the various other types of activations.
To simulate suspending this sample app from within Microsoft Visual Studio Express,
first launch it using Start Debugging, and then use the "Suspend" button.
To simulate resuming this sample app after suspension from within Microsoft Visual Studio Express,
click on the "Resume" button.
Fill in the text box below and simulate suspending this application by clicking on the "Suspend" button in Visual Studio Express. Upon suspension, the filled in text is saved.  On re-launch, the text boxes will contain the text previously entered when the application was suspended.


We collected the first 100 Google.com results (in incognito mode) harvesting their URLs for each of the following queries: "Not having babies"; "Family size"; "Birth spacing"; "Fertility control"; "Fertility regulation"; "Birth control methods"; "Planned parenthood"; "Birth control"; "Preventing pregnancy"; "Rhythm methods"; "Pregnancy prevention"; "family planning"; "IUD "family planning""; "pill+"family planning""; "condoms "family planning""; "condoms contraception"; "pill contraception"; "hormonal cotraceptive"; "contraception".
Rogers, Richard. "The Googlization Question, and the Inculpable Engine."We qualified and tagged all the webpages accordingly to their contents and excluding from the corpus pages not concerned with Family Planning (i.e. PDF, Videos, etc.). The resulting taxonomy is composed by three main groups of categories, with a special focus on controversial issues.
Controversies, relates to sites that are more likely to show debate/controversy:
We have isolated other 2 subcategories within the controversial webpages:
Risk and Benefits:Natural Family Planning related to site that present information on natural family planning, they are worthwhile exploring as they often highlights the risk of artificial methods and might have religious affiliations.
We aggregated the web pages at the domain name level in order to have a better and quicker overview of the corpus contents and by using a visual faceted search we explored which queries produced more valid contents, which domain name is more relevant (i.e. .org or .gov; .com or .co.uk).


The Defect Detection & Defect Classification Models (for our demo) have been trained using Transfer Learning, with VGG16 as the base model.
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing import image
import numpy as np
from termcolor import colored
The Defect Detection model has been trained on the Submersible Pump Impeller Defect Dataset.
Class to wrap around the VGG16-based model & offer the functionality of defect detection.
class DefectDetection:
Load the model & set the image width, height & prediction labels.
def __init__(self, model_file_path="./models/defect_detection_vgg16.hdf5"):
print(colored("INFO", "green"), ": \tLoading Defect Detection Model...")
self.model = load_model(model_file_path)
self.WIDTH = 224
self.HEIGHT = 224
self.labels = {
0: "Defective",
1: "OK"
}
Load & preprocess the image.
def predict(self, img_file):
Run the image through the defect detection model to obtain its predictions.
img = image.load_img(img_file, target_size=(self.WIDTH, self.HEIGHT))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
conf = self.model.predict(x)
prediction = np.argmax(conf[0])
print(self.labels[prediction])
return {"prediction": self.labels[prediction]}
The Defect Classification model has been trained on the Metal Surface Defect Dataset.
Class to wrap around the VGG16-based model & offer the functionality of defect classification.
class DefectClassification:
Load the model & set the image width, height & prediction labels (6 types of defects here according to the dataset)
def __init__(self, model_file_path="./models/defect_classification_vgg16.hdf5", labels=None):
print(colored("INFO", "green"), ": \tLoading Defect Classification Model...")
self.model = load_model(model_file_path)
self.WIDTH = 224
self.HEIGHT = 224
if labels == None:
self.labels = {
0: 'Crazing',
1: 'Inclusion',
2: 'Patches',
3: 'Pitted',
4: 'Rolled',
5: 'Scratches'
}
else:
self.labels = labels
Load & preprocess the image.
def predict(self, img_file):
Run the image through the defect classification model to obtain its predictions.
img = image.load_img(img_file, target_size=(self.WIDTH, self.HEIGHT))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
conf = self.model.predict(x)
prediction = np.argmax(conf[0])
return {"prediction": self.labels[prediction]}


Preparation time
less than 30 mins
Cooking time
30 mins to 1 hour
Serves
Makes 12
Dietary
If you like Bakewell tarts, you’ll love these cute cupcakes.
Preheat the oven to 180C/350F/Gas 4. Line a 12-hole muffin tin with paper cases.
For the cupcakes, cream the margarine in a bowl until light and fluffy. Add the remaining ingredients, except the raspberry jam, and mix until well combined.
Spoon the mixture into the cases and bake for 15-20 minutes, or until risen and golden-brown and a skewer inserted into the middle comes out clean. Remove from the oven and set aside to cool for 10 minutes.
For the icing, mix the icing sugar and lemon juice together in a bowl until smooth.
Using an apple corer, carefully remove the middle of the cupcakes. Fill the holes with the raspberry jam.
Carefully spoon the icing onto the top of each cake until the icing reaches the sides of the cake case and top with a cherry.


{% extends "base.html" %} {% block title %}
Medieval catalogues > AUGUSTINIAN CANONS > Leicester > Leland, c. 1536-40
{% endif %}5 identified entries found.
All data was derived from the List of Identifications by Professor Richard Sharpe.
{% if not printing %}
A key to codes used in the List is available (opens in new tab).{% endif %}


BirdWatch
About
Project Introduction
Blog
Project on GitHub
Legal stuff
Settings
Previous Tweets:
5000
10000
20000
50000
100000
Page Size:
5
10
25
50
100
0
1
2
3
4
5
Tweet count:
Sort by
latest
followers
retweets
word frequency


— Courtesy of Ricky Ho’s Pragmatic Programmer blog.
Hadoop is a complex piece of software with a variegation of components including a distributed file system, a distributed computing framework with job trackers, data nodes, and numerous simultaneously running JVM instances. With any complex software environment, there are tunings that can be employed to ensure both efficient use of space (network bandwidth, hard drive, memory, etc.) and time (object creation, combiners, in-memory combiners, etc.). This section presents various tricks to Hadoop/Faunus that can be used to tune Faunus job sequences and developed Faunus MapReduce extensions.
Faunus Specific Tunings
- Use SequenceFiles for repeated analyses: The Hadoop SequenceFile is the most optimal file format for Faunus. If repeated analysis is going to be done on a graph, then it is beneficial to first generate a SequenceFile representation of that graph in HDFS. This file can then serve as the input for repeated analyses. Generating a SequenceFile is as simple as running the identity step
g._
with the following Faunus properties.
faunus.graph.output.format=org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat
- Avoid text-based representations of graphs: The GraphSON representation of a graph is easy to read/write, but inefficient. DBpedia as a GraphSON file is 23gigs and 11gigs as a SequenceFile. If possible, avoid using verbose text-based formats.
- Reduce the size of the graph early in a job chain: A Faunus graph is typically multi-relational in that there are numerous types of edges in the graph. In many situations, all that information is not necessary for the graph derivation or statistic. As such, use filtering steps early on in the expression to reduce the graph down to the requisite information needed for the computation. Below, because only battled and father edges are used for the traversal, all other edges are filtered out prior to doing the traversal.
g.E.has('label','battled','father').keep.V.as('x').in('battled').in('father').linkOut('x','enemy-father')
- Make use of repeated map steps: When a chain of map-steps are issued, Faunus will process that chain in-memory and thus, there is no I/O within the chain. As such, it is best to organize the traversal (if possible) with all the maps front-loading the traversal/query.
- A vertex must be storable in main memory: The atomic unit of Faunus is a vertex. A
FaunusVertex
is composed of the vertex’s properties, its incoming edges, its outgoing edges, the properties of those edges, and the path information of the traversal up to the elements. A vertex (and any working data structure) must be able to fit in main memory. As such, this is the limit of what can be processed by Faunus. Be sure to make use of mapred.child.java.opts
if more memory is required for the largest vertex being processed (e.g. -Xmx512m
).
- Avoid long, non-filtering path-enabled traversals: When the history of a traversal is not needed, then the only information propagated between elements is the number of counter at the current element (as a long). When history is required, then an array of an array of element ids is propagated. With complex graph structures and with the breadth-first nature of Gremlin/Faunus, this can lead to a combinatorial explosion.
- If no graph output needed, use
NoOpOutputFormat
: If a graph derivation is not required, but instead some sideeffect computation, then set the final output format of the graph to be NoOpOutputFormat
. If no output is needed at all, used Hadoop’s native NullOutputFormat
.
faunus.graph.output.format=com.thinkaurelius.faunus.formats.noop.NoOpOutputFormat
Hadoop Specific Tunings
There are numerous Hadoop specific tunings. Below is a collection of blog posts that discuss tips and tricks for Hadoop.


{{profile.followers}} Followers Following {{profile.following}} {{profile.public_gists}} Public gists {{profile.public_repos}} Public Repos
View Profile on Github
Created: {{repo.created_at | dateAgo}}
{{repo.description}}


Lyrics of Sunshine and Shadow
by Paul Laurence Dunbar
A Love Letter
Additional Information
- Year Published: 1913
- Language: English
- Country of Origin: United States of America
- Source: Dunbar, P.L. (1913). The Complete Poems of Paul Laurence Dunbar. New York: Dodd, Mead, and Company.
-
Readability:
- Flesch–Kincaid Level: 6.5
- Word Count: 281
- Genre: Poetry
- Keywords: longing, love
- ✎ Cite This
Downloads
Oh, I des received a letter f’om de sweetest little gal;
Oh, my; oh, my.

I got a man to read it an’ he read it fine;
Oh, my; oh, my.
Dey ain’ no use denying dat her love is mine;
Oh, my; oh, my.
But hyeah’s de t’ing dat’s puttin’ me in such a awful plight,
I t’ink of huh at mornin’ an’ I dream of huh at night;
But how’s I gwine to cou’t huh w’en I do’ know how to write?
Oh, my; oh, my.
My heaht is bubblin’ ovah wid de t’ings I want to say;
Oh, my; oh, my.
An’ dey’s lots of folks to copy what I tell ‘em fu’ de pay;
Oh, my; oh, my.
But dey’s t’ings dat I’s a–t’inkin’ dat is only fu’ huh ears,
An’ I couldn’t lu’n to write ‘em ef I took a dozen years;
So to go down daih an’ tell huh is de only way, it ‘pears;
Oh, my; oh, my.


| I l@ve RuBoard |
The print statement simply prints objects. Technically, it writes the textual representation of objects to the standard output stream. The standard output stream happens to be the same as the C stdout stream and usually maps to the window where you started your Python program (unless you've redirected it to a file in your system's shell).
In Chapter 2, we also saw file methods that write text. The print statement is similar, but more focused: print writes objects to the stdout stream (with some default formatting), but file write methods write strings to files. Since the standard output stream is available in Python as the stdout object in the built-in sys module (aka sys.stdout), it's possible to emulate print with file writes (see below), but print is easier to use.
Table 3.4 lists the print statement's forms.
|
Operation |
Interpretation |
|---|---|
print spam, ham |
Print objects to sys.stdout, add a space between |
print spam, ham, |
Same, but don't add newline at end |
By default, print adds a space between items separated by commas and adds a linefeed at the end of the current output line. To suppress the linefeed (so you can add more text on the same line later), end your print statement with a comma, as shown in the second line of the table. To suppress the space between items, you can instead build up an output string using the string concatenation and formatting tools in Chapter 2:
>>> print "a", "b" a b >>> print "a" + "b" ab >>> print "%s...%s" % ("a", "b") a...b
And now, without further delay, here's the script you've all been waiting for (drum roll please)—the hello world program in Python. Alas, it's more than a little anticlimactic. To print a hello world message in Python, you simply print it:
>>> print 'hello world' # print a string object hello world >>> 'hello world' # interactive prints 'hello world' >>> import sys # printing the hard way >>> sys.stdout.write('hello world\n') hello world
Printing is as simple as it should be in Python; although you can achieve the same effect by calling the write method of the sys.stdout file object, the print statement is provided as a simpler tool for simple printing jobs. Since expression results are echoed in the interactive command line, you often don't even need to use a print statement there; simply type expressions you'd like to have printed.
Why You Will Care: print and stdoutThe equivalence between the print statement and writing to sys.stdout is important to notice. It's possible to reassign sys.stdout to a user-defined object that provides the same methods as files (e.g., write). Since the print statement just sends text to the sys.stdout.write method, you can capture printed text in your programs by assigning sys.stdout to an object whose write method saves the text. For instance, you can send printed text to a GUI window by defining an object with a write method that does the routing. We'll see an example of this trick later in the book, but abstractly, it looks like this: class FileFaker: def write(self, string): # do something with the string import sys sys.stdout = FileFaker() print someObjects # sends to the write method of the class Python's built-in raw_input() function reads from the sys.stdin file, so you can intercept read requests in a similar way (using classes that implement file-like read methods). Notice that since print text goes to the stdout stream, it's the way to print HTML in CGI scripts (see Chapter 9). It also means you can redirect Python script input and output at the operating system's command line, as usual: python script.py < inputfile > outputfile python script.py | filter |
| I l@ve RuBoard |


In a new HTML file, read in data.json file using D3. This file contains an array of 10 objects that have the following properties: size and color.
In the bottom half of the screen, create 10 circles (one for each object in the data) with fill colors equal to the `color` property on the corresponding data object. Now picture the screen as an Cartesian plane with (0, 0) at the upper-left corner of the screen. Position each circle such that the coordinates of its center are (`size`, -2*`size`).


BDD in JavaScript: CucumberJS
2014 January 19th by todd anderson
I have previously written about TDD in JavaScript, most notably using the BDD-style library Jasmine in a series on building a Test-Driven Grocery List Application. In that posts series I went through thinking of User Stories for Features and Scenarios as actual development tasks, and - reading back on it - it's all very green (no pun intended) in my finding a way to deliver test-driven code. Nothing wrong with that and I will most likely look upon this and subsequent posts in the same manner. That said, I still hold true that TDD is the best way to deliver concise, tested and well thought-out code.
Since that time, however, I have incorporated a different tool into my TDD workflow for JavaScript-based projects that affords me the integration of Feature specs more closely to my development and truly encompasses my current ideal of Behaviour Driven Development: CucumberJS. Essentially, it allows me to truly adhere to TDD while developing from the outside in - running automated tests that fail until I have written code that supports a feature.
> assumptions and notes
For the examples in this post, it is assumed that you are familiar with NodeJS, npm, developing node modules and common unit testing practices as these topics too large to discuss in this post.
Supported files related to this and any subsequent posts on this topic will be available at:
https://github.com/bustardcelly/cucumberjs-examples
CucumberJS
CucumberJS is a JavaScript port of the popular BDD tool Cucumber (which itself was a rewrite of RSpec). It allows you to define Feature Specs in a Domain-Specific-Language (DSL) - called Gherkin - and run your specs using a command line tool which will report the passing and/or failing of scenarios and the steps they are comprised of.
It is important to note that Cucumber itself does not provide a default assertion library. It is a testing framework providing a command line tool that consumes defined Features and validates Scenarios by running Steps that are written in JavaScript. It is the developers choice to include the desired assertion library used in order to make those steps pass or fail. It is my intent to clarify the process by example through a single Feature with multiple Scenarios in this post.
Installation
You can install CucumberJS in your project using npm:
$ npm install cucumber --save-dev
Gherkin
If you had followed along in the previous TDD Series, you will find the specs defined in that series similar to Gherkin. In fact, I will be re-hashing a feature spec from that series to demonstrate working through your first cuke (aka, passing feature spec).
If we were to remake the Grocery List application under TDD/BDD using Cucumber, we would first start with a feature using the Gherkin syntax:
/features/add-item.feature
Feature: Shopper can add an item to their Grocery List
As a grocery shopper
I want to add an item to my grocery list
So that I can remember to buy that item at the grocery store
Scenario: Item added to grocery list
Given I have an empty grocery list
When I add an item to the list
Then The grocery list contains a single item
Scenario: Item accessible from grocery list
Given I have an empty grocery list
When I add an item to the list
Then I can access that item from the grocery list
The Feature defines a business value, while the Scenarios define the steps that provides that value. Most often, in the software development world, it is from these Scenarios that development tasks are taken on and QA tests are defined.
I stopped at two Scenarios, but we could very easily add more scenarios to this feature; immediately what comes to mind are item insertion rules and validation of properties that allow for an item to be added or rejected. In hindsight, it could make more sense in creating seperate feature specs for such details. We could spend a whole post on such topics, though... let's get back to the feature already defined.
Within each Scenario is a list of sequential Steps: Given, When and Then. It is these steps that CucumberJS will execute after having consume this feature spec. After each of those, you can optionally have And and But, however - though necessary and unavoidable at times - I try to stay away from such additional step clauses.
Running it
Having saved that down to a file in a /features direcory, we can then run it under Cucumber:
$ node_modules/.bin/cucumber-js
By default, CucumberJS will consume all feature specs found in the relative /features directory.
The current console output will look something like the following which essentially means that all the steps have not been located or defined:
UUUUUU
2 scenarios (2 undefined)
6 steps (6 undefined)
You can implement step definitions for undefined steps with these snippets:
this.Given(/^I have an empty grocery list$/, function(callback) {
// express the regexp above with the code you wish you had
callback.pending();
});
this.When(/^I add an item to the list$/, function(callback) {
// express the regexp above with the code you wish you had
callback.pending();
});
this.Then(/^The grocery list contains a single item$/, function(callback) {
// express the regexp above with the code you wish you had
callback.pending();
});
this.Then(/^I can access that item from the grocery list$/, function(callback) {
// express the regexp above with the code you wish you had
callback.pending();
});
So we have 6 undefined Steps that make up 2 Scenarios and the CucumberJS ci tool even provides examples of defining them!
An important part of that snippet to understand is that there are only 4 steps to implement. In our Feature we have 2 Scenerios each with 3 Steps. There are a total of 6 steps, but we only need to define 4. The reason being that each Scenario shares the same Given and When step; these only need to be defined once and will be run separately for each Scenario. Essentially, if you define similar Steps using the same context, it will reuse the "setup" for a single Step within each Scenario.
I use "setup" in quotes because I mean it more in a role of defining context for When and Then steps.
I don't want to get it confused with the setup/teardown methods of other unit testing practices - which are known as Before/After support tasks in CucumberJS - and carry more of a context of setting up an environment in which tests are then executed (such as filling a DB of users) and then tearing down that set up.
Step Definitions
In the previous section, we saw that running CucumberJS against our Add Item Feature alerted us that we have undefined (and, though not printed in red, failing) scenarios to support the feature. By default CucumberJS reads in all features from the /features directory relative to where the command was run, but it could not locate the supported step files in which these methods are defined.
As mentioned previously, CucumberJS does not provide an assertion library. The only assumption at this point - since the CucumberJS tool is run under NodeJS - is that the supported steps will be loaded as node modules with an exported function to be executed. As we start implementing the steps, we will need to decide on the assertion library to use in validating our logic. We'll put that decision on the shelf at the moment and get the barebones setup to fail :)
To start, let's take those step definitions provided by the CucumberJS ci tool and drop them into a node module:
_/features/stepdefinitions/add-item.steps.js
'use strict';
module.exports = function() {
this.Given(/^I have an empty grocery list$/, function(callback) {
callback.pending();
});
this.When(/^I add an item to the list$/, function(callback) {
callback.pending();
});
this.Then(/^The grocery list contains a single item$/, function(callback) {
callback.pending();
});
this.Then(/^I can access that item from the grocery list$/, function(callback) {
callback.pending();
});
};
By default, CucumberJS will look for steps to be loaded within a folder titled step_definitions
under the /features directory relative to where you issue the command. You can optionally use the -r
option to have CucumberJS load steps from another location. Running the default is the same as setting the following step definition directory option:
./node_modules/.bin/cucumber-js -r features/step_definitions
The console output will now look like the following:
P--P--
2 scenarios (2 pending)
6 steps (2 pending, 4 skipped)
Not too suprising seeing as we notify the callback of a pending
state. CucumberJS enters the first step (Given) and is immediately returned with a pending notification. As such, it doesn't bother with entering any subsequent steps and marks them as skipped.
Note: It is too much to get into a discussion about client-side modules and AMD vs CommonJS. For the purposes of this example I will be using CommonJS, as I my current interests lie in utilizing Browserify for client-side development. For a long time, I was a proponent of RequireJS and AMD. Again, a whole other discussion :)
Given
To get closer to green, we'll tackle the Given step first:
_/features/stepdefinitions/add-item.step.js
'use strict';
var GroceryList = require(process.cwd() + '/script/model/grocery-list');
module.exports = function() {
var myList;
this.Given(/^I have an empty grocery list$/, function(callback) {
myList = GroceryList.create();
callback();
});
...
};
If we were to run that again, we'd get an exception right away:
$ ./node_modules/.bin/cucumber-js
module.js:340
throw err;
^
Error: Cannot find module './script/model/grocery-list'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/Users/toddanderson/Documents/workspace/custardbelly/cucumberjs-example/features/step_definitions/add-item.steps.js:3:19)
Which is understandable, we haven't any other code but this step definition module and are trying to require a module that doesn't exist. In sticking with TDD, this is a good thing - we know why it's failing and we expect it; I would be pulling my hair out if it didn't throw an exception!
In order to get this to pass, we'll create a node module in the specified directory and which exports an object with a create
method:
/script/model/grocery-list.js
'use strict';
module.exports = {
create: function() {
return Object.create(null);
}
};
We have provided the minimal requirement to get our Given step to pass. We'll worry about the details as we approach the latter steps.
Run that again, and CucumberJS enters in to the When step of each Scenario and aborts due to pending return.
$ ./node_modules/.bin/cucumber-js
.P-.P-
2 scenarios (2 pending)
6 steps (2 pending, 2 skipped, 2 passed)
When
In the previous section, to make the Given step pass on each Scenario we implemented the beginnings of a Grocery List model generated from a factory method,
create
, from the grocery-list
module. I don't want to get into a debate of object creation, the new operator, classes and prototypes - at least not in this post - and will assume that you are familiar and comfortable (at least in reading code) with Object.create defined for ECMAScript 5.
In reviewing the When step for the Scenarios:
When I add an item to the list
we need to provide a way in which to add an item to the Grocery List instance created in the Given - and do so in as little code to make the step pass...
First, we'll define our expectation of the make up and add
signature of the Grocery List in the step definitions:
_/features/stepdefinitions/add-item.step.js
...
module.exports = function() {
var myList,
listItem = 'apple';
this.Given(/^I have an empty grocery list$/, function(callback) {
myList = GroceryList.create();
callback();
});
this.When(/^I add an item to the list$/, function(callback) {
myList.add(listItem);
callback();
});
...
};
If we run that again:
$ ./node_modules/.bin/cucumber-js
.F-.F-
(::) failed steps (::)
TypeError: Object object has no method 'add'
Oooo-weee! Now we're talking. Big, bright red F's. :)
To make that get back to passing, we'll modify grocery-list
with as little code as possible:
/script/model/grocery-list.js
'use strict';
var groceryList = {
add: function(item) {
//
}
};
module.exports = {
create: function() {
return Object.create(groceryList);
}
};
Run again, and CucumberJS has progressed to the Then steps which are reporting a pending
state.
$ ./node_modules/.bin/cucumber-js
..P..P
2 scenarios (2 pending)
6 steps (2 pending, 4 passed)
Then
We progressed through our step implementations and have reached the step(s) at which we assert operations and properties that prove that our scenario provides its intended value. As mentioned previously, CucumberJS does not provide an assertion library. My preference in assertion libraries is a combination of Chai, Sinon and Sinon-Chai, but for the examples in this post, I am just going to use the
assert
module that comes with NodeJS. I encourage you to check out other assertion libraries and leave a note if you have a favorite; perhaps one of these posts will address how I use Chai and Sinon.
Note: This section will be a little example heavy as we quickly switch from modifying our code and run the spec runner frequently.
First Scenario
In reviewing the first Scenario's Then step:
Then The grocery list contains a single item
we will need to prove that the Grocery List instance grows by a factor of 1 for each new item added.
Update the step to define how we expect that specification to be validated:
_/feature/stepdefinitions/add-item.step.js
...
var assert = require('assert');
...
module.exports = function() {
...
this.Then(/^The grocery list contains a single item$/, function(callback) {
assert.equal(myList.getAll().length, 1, 'Grocery List should grow by one item.');
callback();
});
...
};
...
We've pulled in the assert
module and attempt to validate that the length of the Grocery List has grown by a value of 1 after having run the previous step - When - in adding the item.
Run that and we'll get an exception:
$ ./node_modules/.bin/cucumber-js
..F..P
(::) failed steps (::)
TypeError: Object #<Object> has no method 'getAll'
Let's add that method to our Grocery List model:
/script/model/grocery-list.js
'use strict';
var groceryList = {
add: function(item) {
//
},
getAll: function() {
//
}
};
module.exports = {
create: function() {
return Object.create(groceryList);
}
};
And back to running our specs:
$ ./node_modules/.bin/cucumber-js
..F..P
(::) failed steps (::)
TypeError: Cannot read property 'length' of undefined
Seeing as the code is not returning anything from getAll()
, we can't access a length
property for our assertion test.
If we modify the code to return an Array:
_/feature/stepdefinitions/add-item.step.js
...
getAll: function() {
return [];
}
...
And run the specs again, we'll get the assertion error message we provided:
$ ./node_modules/.bin/cucumber-js
..F..P
(::) failed steps (::)
AssertionError: Grocery List should grow by one item.
Now, we have a proper Fail being reported to us from an assertion that causes the step to not pass. Hooray!
-- take a breather --
Let's pause here for a second before adding more code to get this step to pass. The issue at hand is not actually adding an item to the array being returned, it is more about ensuring that an item is added through the add
method and the result from getAll
being a list extended with that item.
Implementation details that are involved in making this test pass is where your team uses their architecture experience, but care is required that only the most essential code is added and not to go overboard in thinking about the internals of the Grocery List collection model. It's a slippery tight-rope that could easily fall down a rabbit hole - just like that poorly-worded metaphor :)
-- get back to work! --
For the purposes of this examples, we'll use the propertiesObject
argument of Object.create
to define a list
getter that will serve as a mutable array for our grocery list items:
/script/model/grocery-list.js
'use strict';
var groceryList = {
add: function(item) {
this.list.push(item);
},
getAll: function() {
return this.list;
}
};
module.exports = {
create: function() {
return Object.create(groceryList, {
'list': {
value: [],
writable: false,
enumerable: true
}
});
}
};
If we run that, we'll find that the first Scenario is now passing!
$ ./node_modules/.bin/cucumber-js
.....P
2 scenarios (1 pending, 1 passed)
6 steps (1 pending, 5 passed)
Second Scenario
In reviewing the final step of our 2nd Scenario, the pending implementation is accessing the added item:
Then I can access that item from the grocery list
To make this step pass we need to verify that we can access the item appended to the Grocery List by invoking add()
with an item.
As with the implementation of accessing the length of the Grocery List, there are several ways in which we could make this test pass in the code. Again, I feel this is where software development experience and taste comes into play with regards to architecture, but I also do prefer trying to produce the least amount of code possible; and I will be the first to admit that sometimes I go a little absent-minded and create more code than is necessary... hence, trying :)
That said, we also have to take into account language and environment specifications in how we address making the assertion pass - and the browser, with its history, has many to consider. That is not a slight, it is just a forethought in setting expectations for requirements.
Specifically: suppose we were to say that the step can be verified using the Array.indexOf()
method on the collection returned from 'getAll()' on the Grocery List object? Without a polyfill, then we are limiting ourselves to passing assertions on IE 9 and older. Such considerations are just the tip of the iceberg when deciding about what to introduce into your codebase in order to have your tests pass, and really should be left up to a team discussion on what is considered necessary to get the product to production.
I could go on and on, but let's just assume we want to cover all bases when it comes to browsers (IE 6 and up, shudder). In my opinion, to make this second Scenario turn green, we will add a getItemIndex()
method with the following signature:
+ getItemIndex(itemValue):int
We'll first modify the step to fail:
_/feature/stepdefinitions/add-item.step.js
this.Then(/^I can access that item from the grocery list$/, function(callback) {
assert.notEqual(myList.getItemIndex(listItem), -1, 'Added item should be found at non-negative index.');
callback();
});
The acceptance in order for this test to pass is that the index at which the added item resides in the collection is non-negative. For this scenariom we are not trying to validate a specification as to where new item is added in a list (eg, prepended or appended), but simply that it is accessible.
Running that will produce an exception:
$ ./node_modules/.bin/cucumber-js
.....F
(::) failed steps (::)
TypeError: Object #<Object> has no method 'getItemIndex'
Let's modify our Grocery List object to support the getItemIndex
method:
/script/model/grocery-list.js
'use strict';
var groceryList = {
add: function(item) {
this.list.push(item);
},
getAll: function() {
return this.list;
},
getItemIndex: function(value) {
var index = this.list.length;
while(--index > -1) {
if(this.list[index] === value) {
return index;
}
}
return -1;
}
};
module.exports = {
create: function() {
return Object.create(groceryList, {
'list': {
value: [],
writable: false,
enumerable: true
}
});
}
};
In our implementation of getItemIndex
, the list is traversed and, if item is found, the index is returned. Otherwise, a value of -1 is returned. Essentially, how the Array.indexOf
method works of ECMAScript 5.
Note: I know it seems silly to use Object.create from ECMAScript 5, but not Array.indexOf. The reason - mostly - being that I normally always include a polyfill for Object.create and not for Array.indexOf. I suppose habit.
Now if we run the specs again under CucumberJS:
$ ./node_modules/.bin/cucumber-js
......
2 scenarios (2 passed)
6 steps (6 passed)
Our cukes are GREEN!
Conclusion
In this post, I introduce how I use the BDD tool CucumberJS in order to adhere to Test Driven Development in JavaScript. I went through using an example of a single Feature with two Scenarios and turning failing Steps to green cukes. If you are unfamiliar with the process with making tests fail first only to produce code to make the test pass, I hope you followed along; I may be wordy and the process could appear to take a lot of time, but development under such practices does start to move smoothly once you get in the groove. Additionally, I think there is a huge reward in having your code under a test harness when it comes to refactoring and bug fixing - both in developer health and business.
The Future
I was going to cover the following topics in this post but have decided to exclude with the hopes of re-addressing in a later post:
- The World support utility
- Build integration (Grunt and Gulp) and automation
- Report generation for Continuous Integration
Additionally, in a following post I want to address how I use CucumberJS to run tests that rely on browser integration - ie, window and document access.
In the past I have used ZombieJS to much success, but Omar Gonzalez has tipped me to him Karma solution that I am excited to test-drive.


Man stole £13,600 from 'kind' woman, 76, then threatened her with naked video
A thief who stole £13,600 from a pensioner and threatened to show a ‘video of her naked’ has been jailed.
Benjamin Watts, 41, was jailed for preying on the widowed pensioner, after the kind-hearted 76-year-old took pity on him and lent him some money.
Watts pleaded guilty to the theft at Warwick Crown Court on the basis that he had permission to use her card, and had repaid £4,400 of the money.
But following a ‘trial of issue’, his account was rejected by Judge Andrew Lockhart QC who sentenced Watts, of Kettering, Northamptonshire, for two-and-a-half years.
The unnamed victim told the court she had met Watts in around October 2015, when he had done some work for her at her home in Kettering and they had become ‘very close’.
But after challenging him about more missing money, she says Watts claimed to have videos of her.
Advertisement Advertisement
Judge Lockhart explained: ‘The victim had lent £7,800 to him in order that he might buy a van.
‘She then discovered several transactions without her knowledge. She says “he never gave me £4,400 back.”
‘I can only make a finding against Mr Watts if I am sure she is right.
‘There is no doubt he took (some) of the funds, the issue is whether it is as much as the Crown allege.
‘I find I am absolutely sure the Crown are right, that her evidence is truthful and reliable, and that he never had her permission to use this card.
‘I reject the basis of plea. I am sure that the amount he stole was £13,600, and that there were veiled threats.’
The victim claimed that after lending Watts money to buy a new van, her bank told her she had exceeded her approved overdraft – which she could not understand.
Her bank statements revealed 28 cash withdrawals – which she said had been made without her knowledge and mostly late at night or in the early hours of the morning – totalling £13,600.
She said she had not given anyone permission to make those withdrawals and that he had only repaid £150, as far as she could remember.
It was then that he made the threats about videos, she added.
Advertisement Advertisement
‘I took that to be some form of blackmail. He said that he would show the court a video of me naked.’
Asked if she was aware of any such video being made, the pensioner replied firmly: ‘Absolutely not.’
During evidence, Watts had claimed: ‘She told me to use that money whenever I wanted for equipment and so-on.
‘She let me use her card. Every time I used the bank card I told her about it.’
He said the jobs he was doing would be paid for in cash, and that he would then pay back the pensioner in cash.
But the victim disputed that he ever had permission to withdraw money from her account when he wanted and that he had repaid £4,400.
Got a story for Metro.co.uk?
Get in touch with our news team by emailing us at<EMAIL_ADDRESS>For more stories like this, check our news page.


  DIARY_PRIV 4,367 forman-diary-e2-p2 1602?  LETTERS_PRIV 174 proud-1630-e2-p1 1636 LETTERS_PRIV 470 raleigh-e2-h 1600 PROCEEDINGS_TRIAL 8,301 raleigh-e2-p1 1600 PROCEEDINGS_TRIAL 8,669 rcecil-e2-h 1594-1598 LETTERS_NON-PRIV 998 rcecil-e2-p1 1594-1598 LETTERS_NON-PRIV 1,390 rcecil-e2-p2 1594-1598 LETTERS_NON-PRIV 1,169 record-e1-h 1551 SCIENCE_OTHER 6,967 record-e1-p1 1551 SCIENCE_OTHER 7,175 record-e1-p2 1551 SCIENCE_OTHER 6,772 rferrar-e2-h 1633?
A few examples:
In tripling the size of the samples from the Helsinki Corpus, we
have sometimes had to include texts by new authors (either because the
Helsinki Corpus sample for an author was itself already exhaustive, or
because we ran out of text in the course of tripling the sample size).
In what follows, we describe the conventions that we have followed in
assigning filenames to these new authors. Our general rule has been
to leave Helsinki Corpus filenames unchanged, but we have sometimes
slightly modified the original Helsinki
filenames for clarity and consistency. These modifications as well as
which PPCEME files supplement which Helsinki Corpus files are set out in
In the correspondence of important families (such as that of the
Barringtons, the Hattons, or the Plumptons), the Helsinki Corpus tends
to identify women by their birthname, and we retain those filenames.
So Anne Finch, countess of Nottingham, nee Hatton, is identified as
anhatton (not finch).
Where the Helsinki Corpus distinguishes individuals with the same
name by means of "jr" and "sr", we retain that usage. However, in
texts added at Penn, we do not specially distinguish the father-son
relationship. We follow this convention in order to avoid having to
change Helsinki filenames. So the Valentine Pettit of the Helsinki
Corpus is identified as pettit, and his son of the same name, who is
not represented in the Helsinki Corpus, is identified as pettit2.
For clarity and consistency, we have adopted the convention that
Arabic numbers immediately following an author's name always indicate
distinct authors. This forces us to modify Helsinki filenames
of the type mentioned in the preceding paragraph. hooker1 and
hooker2 become hooker-a and hooker-b. In the case of the wplumpt
and stat files, we distinguish the individual files by decade, as
described directly below.
Similarly, the wplumpt files mentioned earlier are identified as
wplumpt-1500, wplumpt-1510, and wplumpt-1530, and the statute files
appear as stat-1500, stat-1510, and so on.
In one or two cases, material by a single author spans more than
a decade, but we identify the samples in some other way than by
decade in order to avoid changing a Helsinki filename. For instance,
Brilliana Harley's letters to her husband (all but one of which are
part of the Helsinki Corpus) are identified as harley, and her
later letters to her son, which are not included in the Helsinki
Corpus, are identified as harleyedw. Thomas More's one personal
letter from the 1620s (included in the Helsinki Corpus) is
identified as morelet1, and his personal letters from the 1630s
(some from the Helsinki Corpus, and some added by us) are identified
as morelet2.
Name vs. title
Following the conventions of the Helsinki Corpus, authors are identified
by name rather than by title. Sovereigns of England are identified by
their given name. For instance, Charles II is identified as charles.
Other members of the nobility, including members of the royal family,
are identified by their surname. For instance, Thomas Howard, earl of
Surrey, 2nd duke of Norfolk, is identified as thoward (not norfolk), and
Mary Tudor (Henry VIII's sister, not to be confused with his daughter,
Mary I, who is not represented in the corpus) as mtudor.
In one or two cases, the Helsinki Corpus uses a title
rather than a surname as the basis for a filename. For instance,
Eleanor Clifford, countess of Cumberland, is identified as ecumberl
(not clifford). In such cases, we retain the Helsinki filename in
order to minimize confusion.
Women's names
As a general rule, women are identified by their surname at the time of
writing. Generally (though not always), this is a married name. In
order to minimize confusion, we do not change filenames to reflect a
later marriage. Two examples:
In one or two cases, a woman appears in the Helsinki
Corpus under her married name despite belonging to one of the
important correspondence families. For instance, Joan Everard and
Elizabeth Masham, both n&ecutee;e Barrington, are identified as
everard (not jobarring) and masham (not ebarring). In such cases,
we use the Helsinki filenames in order to minimize confusion.
Modifications of Helsinki Corpus filenames
Under certain circumstances, we have modified the filenames in the
Helsinki Corpus for clarity and consistency. The conventions governing
these modifications are given here, and the correspondence between the
old and new filenames are set out in
In one or two cases, it is not clear whether a
Helsinki Corpus file contains material spanning more than a decade
or not. In such cases, we have divided the file into the two
identifiable time chunks, but not identified them by decade.
For instance, tillots is divided into tillots-a (from before 1671)
and tillots-b (from 1679).
| Table 4: Summary of filename modifications and PPCEME-Helsinki correspondences | ||
|---|---|---|
| Helsinki filename | PPCEME filename (if different from Helsinki) | Supplemented by |
| alhatton | --- | alhatton2, ehatton2 |
| bedyll | --- | friar, russell |
| boyle | --- | boylecol |
| clowes | --- | clowesobs |
| conway | --- | rich |
| counc | --- | dell |
| ebeaum | --- | mtudor-1510, mtudor-1520 |
| ecumberl | --- | manners, delapole |
| ehatton | --- | mhatton, montague |
| eliz1, eliz2 | included in eliz-1590 | eliz-1560, eliz-1570, eliz-1580 |
| eoxinden | included in eoxinden-1660 | dering, eoxinden-1650, eoxinden-1680, jackson, zouch |
| essex | --- | essexstate |
| everard | --- | jubarring |
| fhatton | --- | mhatton |
| harley | --- | harleyedw |
| henry1, henry2 | included in henry-1520 | henry-1530 |
| hooker1 | included in hooker-a | --- |
| hooker2 | included in hooker-b | --- |
| hoxinden | hoxinden-1660 | hoxinden-1640, hoxinden-1650 |
| jetaylor | --- | jetaylormeas |
| jpinney | --- | southard, part of jopinney |
| knyvett | included in knyvett-1620 | knyvett-1630 |
| kscrope | kscrope-1530 | grey, kscrope-1580, mhoward |
| lords | --- | interview, marches, surety |
| morelet1, morelet2 | --- | part of mroper (see Remarks therein) |
| mowntayne | --- | underhill |
| nhadd | included in nhadd-1700 | nhadd-1710 |
| osborne | --- | conway2 |
| pettit | --- | pettit2 |
| peyton | --- | moxinden |
| Plumpton correspondence | --- | abott, apoole, epoole, gascoigne, gpoole, nevill, rplumpt2, savill |
| proud | proud-1620 | proud-1630 |
| raleigh | --- | judall |
| rferrar | --- | part of nferrar |
| rhaddsr | included in rhaddsr-1670 and rhaddsr-1700 | rhaddsr-1650, rhaddsr-1710 |
| roxinden | included in roxinden-1620 | roxinden-1600, roxinden2 |
| somers | --- | drummond |
| stat3 | stat-1500, included in stat-1540; see info for stat-period1.e1 | stat-1510, stat-1530, stat-1550, stat-1560 |
| stat4 | stat-1590, included in stat-1600; see info for stat-period2.e2 | stat-1570, stat-1580, stat-1620, stat-1640 |
| stat7 | included in stat-1690; see info for stat-period3.e3 | stat-1660 |
| stevenso | --- | part of udall |
| strype | --- | joxinden |
| thoward | --- | dacre |
| throckm | --- | thoward2 |
| tillots | divided into tillots-a, tillots-b | tillots-c |
| torkingt | --- | chaplain |
| trincoll | --- | hatcher, talbot |
| tunstall | --- | ambass |
| turner | --- | turnerherb |
| wcecil | included in wcecil-1580 | wcecil-1560 |
| wpaston2 | --- | joxinden |
| wplumpt1 | wplumpt-1500 | --- |
| wplumpt2 | wplumpt-1510 | --- |
| wplumpt3 | wplumpt-1530 | --- |


My name is Xavier Frankline, I am a passionate, ambitious and driven person.
I am a graduate of Telecommunications and Information Engineering fom JKUAT.My professional experience include stints at Huawei Technologies Kenya Ltd. and Standard Media Group Ltd. as an Intern and a role as a Field Support Engineer at Jamii Telecommunications Ltd (Faiba).
Earlier this year, I decided that I needed to learn the art of programming since this would have enabled me apply technology as a solution to most of the challenges we face as a society. I belive my calling is to make chage in society and I believe I will be able to do that.


GODS AND MONSTERS A film review by Steve Rhodes Copyright 1998 Steve Rhodes RATING (0 TO ****): *** 1/2
James "Jimmy" Whale, once appropriately given the sobriquet of "the father of horror," launched the monster movie craze in the early 1930s with FRANKENSTEIN, THE BRIDE OF FRANKENSTEIN, and THE INVISIBLE MAN. GOD AND MONSTERS, set in the 1950s, tells the story of the last period of his life.
Alternatively witty, poignant, insightful and surprising, the film relates the story of a man's life by focusing on its ending, while keeping the flashbacks to a minimum. Whale, played with an Oscar caliber performance by Ian McKellen, was an eccentric and a loner. An avowed homosexual, at a time when few admitted it publicly, Whale dropped out of the active Hollywood scene. Living in an uncommonly modest house by Hollywood standards, he kept himself busy painting amazingly accurate copies of great masterpieces.
Cast opposite McKellen, who was last seen in APT PUPIL as a retired Nazi, is Brendan Fraser, last seen crashing into trees in GEORGE OF THE JUNGLE. Although the choice of Fraser to go opposite Sir Ian may seem a bit odd, it works. Comedic actor Fraser, who has played serious parts before, as in SCHOOL TIES, makes us expect much less than we get. He gives his character charisma and a subtle complexity.
Fraser plays Clayton Boone, Jimmy's big oaf of a gardener. Clayton, who has the rippling muscles of a Greek god, lives in an old trailer and drives a beat-up truck. He's an ex-marine who has a big, patriotic tattoo to remind himself of his time in the service.
An avowed heterosexual, Clayton feels uneasy but yet drawn to Jimmy, who tells him fascinating inside stories about the making of movies. He says, for example, that Boris Karloff was a proper English actor but was dreadfully dull. And he tells much more controversial stories too, like the inside scoop on George Cukor and his sex-with-young-boys scandal.
Even with his reservations, Clayton becomes both Jimmy's friend and artist model. The natural chemistry between them doesn't follow conventional patterns. Besides the obvious physical attraction, Jimmy is also drawn to Clayton because of their similar childhood economic status.
Jimmy grew up in a large family where they lived four to a bed and with a privy out back. They used "drippings," i.e., congealed beef juices that they kept in a jar, to put on toast instead of butter. His father, whom he loathed, made him work in the factories at hard labor from an early age. "Hatred was the only thing that kept my soul alive," Jimmy says of his father, who treated him badly.
Jimmy served in the foxholes in World War I, and he was as scarred emotionally by this as much as his childhood. Both of these parts of his life keep flashing into in his mind.
The movie contains old film footage of Jimmy's classic movies as well as reconstructions of their shootings. Although these form the heart of GOD AND MONSTERS, there are many wonderfully little odd ball incidents as well. Typical of these is the obviously gay reporter who doesn't have much respect for Jimmy's talents but has come for a pro forma interview of him. Jimmy, who finds his trivial questions boring, decides to make a game of the interview. Jimmy tells him that he will answer any questions whatsoever that the reporter poses so long as the reporter takes off a piece of clothing for every question.
As a character out of left field, Lynn Redgrave, with a thick Eastern European accent, plays Jimmy's disapproving maid. Although she loves Jimmy, she is full of "tsk, tsk, tsk" for his behavior.
Based on Christopher Bram's novel, written and lovingly directed by Bill Condon, the film touches us with its honest and poignant portrayal of a fascinating individual.
"Alone, bad; friend, good" Frankenstein says at the end of his movie. Jimmy, a loner, didn't have many friends, but he certainly cherished the few he did have. And Clayton was glad to be counted among them.
GODS AND MONSTERS runs 1:45. It is not rated but would be an R for sex, profanity and mature subject matter and would be fine for older and mature teenagers.
Email<EMAIL_ADDRESS>Web: www.InternetReviews.com
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


This is one of the best curry goat recipes I've tried. What makes it unique from others is the lime juice that gets rubbed on the meat. The taste remains on the meat throughout the simmering and adds just the right zing. I think the best recipes are those that don't need much modification and this one was great as written. It produces a stew with a good consistency...not too thick or thin, and with tons of flavor.
YIELD: 3 People
Ingredients
2 pounds goat meat (or lamb) without bones1 lime, juiced
1 tablespoon salt
1 teaspoon freshly ground black pepper
1 Scotch bonnet pepper (any color), seeded and minced
1/2 teaspoon dried thyme
1/2 teaspoon ground allspice (dry pimento berries)
3 tablespoons curry powder
2 whole scallions, sliced
1 onion, sliced
3 cloves garlic, minced
1/4 cup vegetable oil
3 tomatoes, diced
1/2 cup coconut milk (optional)
3 cups water
Preparation
Rinse goat meat well, rub lime juice over it (from 1/2 whole lime), place meat in a bowl, then add salt, black pepper, Scotch bonnet, thyme, allspice, curry powder, scallions, onion and garlic. Leave to marinate for at least 2 hours in the refrigerator, longer would be ideal. Heat the oil in a skillet until it is very hot, and saute the meat until golden brown. Then add the marinade, tomatoes and coconut milk, if using, and simmer for approximately 3 more minutes. Add water, reduce heat and allow to simmer for 2 to 3 hours stirring occasionally until meat is tender.Instead of simmering for 2-3 hours you can cook goat in a a Pressure Cooker for ~40-45 minutes


---
layout: post
title: links for 2007-06-07
date: 2007-06-07 00:00:00
---
-
-
-
-
Oops :)
-
"the availability of samurai swords makes them the weapon of choice for growing numbers of young men with criminal intentions"
-
-
Serge posts up a video taken from footage of us watching Most Haunted from the office during the broadcast.


The Windows agent will run on any 64bit Windows host such as Windows 7, 8, 10, Server 2008, 2012 and 2016. Simply extract the package on the host itself or an accessible network location. The Microsoft .NET 4.5 Framework is required. The agent can be installed by running the following command from an Administrator command line:
install.bat http://<IP_ADDRESS>/healthstone default
The first argument is the URL of this dashboard. The second argument is the template you want to use. Templates are stored in the templates folder on this dashboard server. The agent will fetch the template at every poll. The installer will copy the binary to %PROGRAMFILES%/healthstone, add the proper entries to the Registry under HKLM/Software/Healthstone and start the service.
The Linux agent will run on any modern Linux host. The only requirement is to have Python 3.x installed and available as python3 on the system. Simply extract the package on the host itself or an accessible network location. The agent can be installed by running the following command:
sudo ./install.sh http://<IP_ADDRESS>/healthstone default
The first argument is the URL of this dashboard. The second argument is the template you want to use. Templates are stored in the templates folder on this dashboard server. The agent will fetch the template at every poll. The installer will copy the Python script and add an entry to your rc.local startup file.
Templates are flat files stored on the dashboard server which provides configuration information to agents. You can make as many templates as you want. Each template lists a number of modules that you wish the agents to process. Only the [General] section is mandatory, but each section kept must have all its keys listed. Do not use quotes or multiple lines for key values. Templates are not saved on hosts, each agent will fetch its specific template on every poll. Template filenames must contain only alphanumeric characters and end with .template. The same template can be used for Windows and Linux agents, although you may want to create multiple templates and divide them according to your network needs, such as a template for Windows servers, one for workstations, one for Linux, etc.


One of my favorite puzzles and first projects that I've ever coded.
A small project for my graphics class. Renders various primitives with variables.
Another project that I made for my graphics class! This one's a short little fps. This was just a bit of exploratory work with FPS mechanics using webGL, so not much has been implemented. That said, I'm probably still updating this and implementing whatever I'm learning. You can view all the progress on my github!
(It can be wonky on chrome, so I would suggest using Firefox to view this.)
Hello! I'm Dylan Miyashiro. I'm a recent graduate from Willamette University with a BA in Computer Science and Mathematics. Feel free to check out a few of small projects I've done for class and fun, or to contact me at my email below.


| TOC |
|
This extension to the OpenID Authentication protocol provides a mechanism by which a Relying Party can request that particular authentication policies be applied by the OpenID Provider when authenticating an End User. This extension also provides a mechanism by which an OpenID Provider may inform a Relying Party which authentication policies were used. Thus a Relying Party can request that the End User authenticate, for example, using a phishing-resistant or multi-factor authentication method.
This extension also provides a mechanism by which a Relying Party can request that the OpenID Provider communicate the levels of authentication used, as defined within one or more sets of requested custom Assurance Levels, and for the OpenID Provider to communicate the levels used.
This extension is not intended to provide all information regarding the quality of an OpenID Authentication assertion. Rather, it is designed to be balanced with information the Relying Party already has with regard to the OpenID Provider and the level of trust it places in it. If additional information is needed about processes such as new End User enrollment on the OpenID Provider, such information should either be transmitted out-of-band or in other extensions such as OpenID Attribute Exchange. Other aspects (e.g. security characteristics, credential provisioning, etc) could be dealt with in the future.
This extension is optional, though its use is certainly recommended. This extension can be used with OpenID Authentication versions 1.1 and 2.0.
While none of the information transmitted using this extension can be verified by the Relying Party using technology alone, this does not limit the utility of this extension. Because there is no trust model specified by OpenID, Relying Parties must decide for themselves which Providers are trustworthy; likewise, RPs can decide whether to trust authentication policy claims from such OpenID Providers as well. As with other OpenID extensions, it is the Relying Party's responsibility to implement policy relative to the OpenID Provider's response.
1.
Definitions
1.1.
Requirements Notation
1.2.
Conventions
1.3.
Terminology
2.
Extension Overview
3.
Advertising Supported Authentication Policies
4.
Defined Authentication Policies
4.1.
Custom Assurance Level Name Spaces
5.
Authentication Protocol
5.1.
Request Parameters
5.2.
Response Parameters
6.
Security Considerations
6.1.
NIST Assurance Levels
Appendix A.
Examples
Appendix A.1.
Authentication Method Classifications
Appendix B.
Acknowledgements
7.
Normative References
§
Authors' Addresses
| TOC |
| TOC |
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] (Bradner, B., “Key words for use in RFCs to Indicate Requirement Levels,” 1997.) .
| TOC |
Throughout this document, values are quoted to indicate that they are to be taken literally. When using these values in protocol messages, the quotes MUST NOT be used as part of the value.
All OpenID 2.0 messages that contain a Provider Authentication Policy Extension (PAPE) element MUST contain the following extension namespace declaration, as specified in the Extensions section of [OpenIDAuthentication2.0]<EMAIL_ADDRESS>“OpenID Authentication 2.0,” 2007.) .
openid.ns.<alias>=http://specs.openid.net/extensions/pape/1.0
The actual extension namespace alias should be determined on a per-message basis by the party composing the messages, in such a manner as to avoid conflicts between multiple extensions. For the purposes of this document and when constructing OpenID 1.1 messages, the extension namespace alias SHALL be "pape".
Additionally, this specification uses name spaces for the custom authentication level identification. It is in the form of
openid.pape.auth_level.ns.<cust>=http://some.authlevel.uri
The actual extension namespace alias should be determined on a per-message basis by the party composing the messages, in such a manner as to avoid conflicts between multiple extensions. For the purposes of this document and when constructing OpenID 1.1 messages, the one custom authentication level identification extension namespace defined by this specification is "nist". Others may also be defined and used by implementations, for example, "jisa".
| TOC |
The following terms are defined in [OpenIDAuthentication2.0]<EMAIL_ADDRESS>“OpenID Authentication 2.0,” 2007.) :
- Authentication Method:
- An Authentication Method is a single mechanism by which the End User authenticated to their OpenID Provider, for example, a password or a hardware credential.
- Authentication Policy:
- An Authentication Policy is a plain-text description of requirements that dictate which Authentication Methods can be used by an End User when authenticating to their OpenID Provider. An Authentication Policy is defined by a URI which must be previously agreed upon by one or more OPs and RPs.
| TOC |
| TOC |
Via the use of [Yadis] (Miller, J., Ed., “Yadis Specification 1.0,” 2005.) within OpenID, Relying Parties are able to discover OpenID Provider service information in an automated fashion. This is used within OpenID Authentication for a RP to discover what version of the protocol each OP listed supports as well as any extensions, such as this one, that are supported. To aide in the process of a Relying Party selecting which OP they wish to interact with, it is STRONGLY RECOMMENDED that the following information be added to the End User's XRDS document. An OP may choose to advertise both custom levels and supported polices in the same <xrd:Service>. An OP should only advertise the authentication policies and custom assurance level namespaces that it supports.
When advertising supported policies, each policy URI MUST be added as the value of an <xrd:Type> element of an OpenID <xrd:Service> element in an XRDS document.
Example:
<xrd> <Service> <Type>http://specs.openid.net/auth/2.0/signon</Type> <Type> http://schemas.openid.net/pape/policies/2007/06/phishing-resistant </Type> <URI>https://example.com/server</URI> </Service> </xrd>
When advertising supported custom Assurance Level name spaces, each name space URI MUST be added as the value of an <xrd:Type> element of an OpenID <xrd:Service> element in an XRDS document.
Example:
<xrd> <Service> <Type>http://specs.openid.net/auth/2.0/signon</Type> <Type> http://csrc.nist.gov/publications/nistpubs/800-63/SP800-63V1_0_2.pdf </Type> <URI>https://example.com/server</URI> </Service> </xrd>
| TOC |
The following are defined policies and policy identifiers describing how the End User may authenticate to an OP. Additional policies can be specified elsewhere and used without making changes to this document. The policies described below are designed to be a starting point to cover the most common use-cases. Additional polices can be found at http://schemas.openid.net/pape/policies/.
When multiple policies are listed in the Relying Party's request, the OpenID Provider SHOULD satisfy as many of the requested policies as possible. This may require, for instance, that a user who has already been authenticated using one authentication method be re-authenticated with different or additional methods that satisfy the request made by the Relying Party. It is always the responsibility of the RP to determine whether the particular authentication performed by the OP satisfied its requirements; this determination may involve information contained in the PAPE response, specific knowledge that the RP has about the OP, and additional information that it may possess or obtain about the particular authentication performed.
http://schemas.openid.net/pape/policies/2007/06/phishing-resistant
An authentication mechanism where a party potentially under the control of the Relying Party can not gain sufficient information to be able to successfully authenticate to the End User's OpenID Provider as if that party were the End User. (Note that the potentially malicious Relying Party controls where the User-Agent is redirected to and thus may not send it to the End User's actual OpenID Provider).
http://schemas.openid.net/pape/policies/2007/06/multi-factor
An authentication mechanism where the End User authenticates to the OpenID Provider by providing more than one authentication factor.  An example would be authentication using a password and a software token or digital certificate.
http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical
An authentication mechanism where the End User authenticates to the OpenID Provider by providing more than one authentication factor where at least one of the factors is a physical factor such as a hardware device or biometric.  This policy also implies the Multi-Factor Authentication policy (http://schemas.openid.net/pape/policies/2007/06/multi-factor) and both policies MAY BE specified in conjunction without conflict. An example would be authentication using a password and a hardware token.
Of the policies defined above, two are not independent. All authentications satisfying the Multi-Factor Physical policy also satisfy the Multi-Factor policy. Therefore, whenever the OP returns a result saying that Multi-Factor Physical authentication was performed it MUST also indicate that Multi-Factor authentication was performed.
| TOC |
Custom Assurance Levels are optional. The namespaces may be defined by various parties, such as country or industry specific standards bodies, or other groups or individuals.
The namespace URI should be chosen with care to be unambiguous when used as a <xrd:Type> element to advertise the namespaces supported by the OP.
The custom Assurance Level namespace should define the meaning of the strings that are returned by the OP in the openid.pape.auth_level.<cust> element.
| TOC |
| TOC |
The following parameters MUST be included during an OpenID Authentication request<EMAIL_ADDRESS>“OpenID Authentication 2.0,” 2007.) [OpenIDAuthentication2.0] by the Relying Party that uses this extension unless marked as optional.
Value:
http://specs.openid.net/extensions/pape/1.0
(Optional) If the End User has not actively authenticated to the OP within the number of seconds specified in a manner fitting the requested policies, the OP SHOULD authenticate the End User for this request using the requested policies. The OP MUST actively authenticate the user and not rely on a browser cookie from a previous authentication.
Value: Integer value greater than or equal to zero in seconds.
If an OP does not satisfy a request for timely authentication, the RP may decide not to grant the End User access to the services provided by the RP. If this parameter is absent from the request, the OP should authenticate the user at its own discretion.
Zero or more authentication policy URIs representing authentication policies that the OP SHOULD satisfy when authenticating the user. If multiple policies are requested, the OP SHOULD satisfy as many of them as it can.
Value: Space separated list of authentication policy URIs.
If no policies are requested, the RP may be interested in other information such as the authentication age.
Example:
openid.pape.preferred_auth_policies= http://schemas.openid.net/pape/policies/2007/06/phishing-resistant http://schemas.openid.net/pape/policies/2007/06/multi-factor
(Optional) The name space for the custom Assurance Level. Assurance levels and their name spaces are defined by various parties, such as country or industry specific standards bodies, or other groups or individuals.
Value: URL that represents this Assurance Level.
Example:
openid.pape.auth_level.ns.nist= http://csrc.nist.gov/publications/nistpubs/800-63/SP800-63V1_0_2.pdf openid.pape.auth_level.ns.jisa= http://www.jisa.or.jp/spec/auth_level.html
(Optional) A list of the name space aliases for the custom Assurance Level name spaces that the RP requests be present in the response, in the order of its preference.
Value: Space separated list of the name space aliases, in the order of the RP's preference.
Example:
openid.pape.preferred_auth_levels=jisa nist
| TOC |
In response to a Relying Party's request, the following parameters MUST be included in the OpenID Authentication Response. All response parameters MUST be included in the signature of the Authentication Response. It is RECOMMENDED that an OP supporting this extension include the following parameters even if not requested by the Relying Party.
All response parameters MUST describe the End User's current session with the OpenID Provider.
Value:
http://specs.openid.net/extensions/pape/1.0
One or more authentication policy URIs representing policies that the OP satisfied when authenticating the End User.
Value: Space separated list of authentication policy URIs.
Note: If no policies were met though the OP wishes to convey other information in the response, this parameter MUST be included with the value of http://schemas.openid.net/pape/policies/2007/06/none.
Example:
openid.pape.auth_policies= http://schemas.openid.net/pape/policies/2007/06/multi-factor http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical
(Optional) The most recent timestamp when the End User has actively authenticated to the OP in a manner fitting the asserted policies.
Value: The timestamp MUST be formatted as specified in section 5.6 of [RFC3339] (Klyne, G. and C. Newman, “Date and Time on the Internet: Timestamps,” .) , with the following restrictions:
- All times must be in the UTC time zone, indicated with a "Z".
- No fractional seconds are allowed
Example:
2005-05-15T17:11:51Z
Note: If the RP's request included the "openid.pape.max_auth_age" parameter then the OP MUST include "openid.pape.auth_time" in its response. If "openid.pape.max_auth_age" was not requested, the OP MAY choose to include "openid.pape.auth_time" in its response.
(Optional) The name space for the custom Assurance Level defined by various parties, such as a country or industry specific standards body, or other groups or individuals.
Value: URL that represents this Assurance Level.
Example:
openid.pape.auth_level.ns.nist= http://csrc.nist.gov/publications/nistpubs/800-63/SP800-63V1_0_2.pdf openid.pape.auth_level.ns.jisa= http://www.jisa.or.jp/spec/auth_level.html
(Optional) The Assurance Level as defined by the above standards body, group, or individual that corresponds to the authentication method and policies employed by the OP when authenticating the End User. A custom Assurance Level definition MAY define additional subparameter values that are expressed within its namespace, although for reasons of simplicity, this SHOULD be avoided if possible.
Value: Strings defined according to this Assurance Level.
Example:
openid.pape.auth_level.nist=1 openid.pape.auth_level.jisa=2
| TOC |
Per commonly accepted security practices, it should be noted that the overall strength of any authentication is only as strong as its weakest step. It is thus recommended that provisioning of phishing-resistant and other credentials stronger than shared secrets should be accomplished using methods that are at least as strong as the credential being provisioned. By counter-example, allowing people to retrieve a phishing-resistant credential using only a phishable shared secret negates much of the value provided by the phishing-resistant credential itself. Similarly, sometimes using a phishing-resistant method when a phishable method continues to also sometimes be employed may still enable phishing attacks to compromise the OpenID.
OPs SHOULD attempt to satisfy the authentication policies requested by the RP and the reply SHOULD minimally contain at least the subset of the requested policies that the authentication performed satisfied. The OP MAY also choose to return additional policies that the authentication performed satisfied, even if not requested.
If the RP requested that an authentication level or levels be returned and the OP supports some or all of those level types, then the OP SHOULD return the actual level value for each of the supported types requested, if available.
| TOC |
National Institute of Standards and Technology (NIST) in Special Publication 800-63 (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) [NIST_SP800‑63] defines a set of Assurance Levels from 1 to 4. These may be returned by the OP to the RP to communicate which NIST level the identity proofing, authentication method, and policies employed by the OP when authenticating the End User corresponds to.
Value: Integer value between 0 and 4 inclusive.
Note: Level 0 is not an assurance level defined by NIST, but rather SHOULD be used to signify that the OP recognizes the parameter and the End User authentication did not meet the requirements of Level 1. See Appendix A.1.2 (NIST Authentication Mechanism Levels) for high-level example classifications of authentication methods within the defined levels. Authentication using a long-lived browser cookie, for instance, is one example where the use of "level 0" is appropriate. Authentications with level 0 should never be used to authorize access to any resource of any monetary value whatsoever. The previous sentence should not be construed as implying that any of the other levels are recommended or appropriate for accessing resources with monetary value either without the Relying Party doing an appropriate risk assessment of the particular OpenID provider asserting them and their issuance and authentication procedures as they apply to the particular online interaction in question.
Depending on the particular use case being satisfied by the authentication response and PAPE information, the OpenID Provider will have to make a decision, ideally with the consent of the End User, as if it will include the "openid.pape.auth_level.nist" parameter. This information is designed to give Relying Parties more information around the strength of credentials used without actually disclosing the specific credential type. Disclosing the specific credential type can be considered a potential privacy or security risk.
It is RECOMMENDED that this parameter always be included in the response from the OP. This holds true even in cases where the End User authentication does not meet one of the defined Authentication Policies. For example, if the End User is authenticating using a password via HTTPS there is still value to the RP in knowing if the strength of the Password corresponds to the entropy requirements laid out by Level 1 or 2 or that it does not even meet the minimum requirement for the lowest level. With that said, discretion needs to be used by OP's as conveying that one of their End User's has a weak password to an "un-trustworthy" RP would not generally be considered a good idea.
| TOC |
| TOC |
This non-normative section illustrates classification of various common authentication methods and their respective conformance within the defined policies and levels.
| TOC |
This table provides examples of common authentication technologies and their mapping to the Authentication Policies defined in Section 4 (Defined Authentication Policies) .
| Method | Phishing-Resistant | Multi-Factor | Physical Multi-Factor |
|---|---|---|---|
| Password via HTTPS | |||
| Visual secret via HTTPS | |||
| PIN and digital certificate via HTTPS | X | X | |
| PIN and "soft" OTP token via HTTPS | X | ||
| PIN and "hard" OTP token via HTTPS | X | X | |
| PIN and "hard" crypto token via HTTPS | X | X | X |
| Information Card via HTTPS | X | X |
| TOC |
This section is designed to highlight the Authentication Mechanism Levels described in [NIST_SP800‑63] (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) . All normative and authoritative text can be found in [NIST_SP800‑63] (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) . Note that assurance level is not only comprised of Authentication Mechanism employed but also the nature of the identity proofing performed. The overall assurance level is determined as a combination of these factors.
This table is republished from page 39 of [NIST_SP800‑63] (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) .
| Token Type | Level 1 | Level 2 | Level 3 | Level 4 |
|---|---|---|---|---|
| Hard crypto token | X | X | X | X |
| One-time password device | X | X | X | |
| Soft crypto token | X | X | X | |
| Passwords & PINs | X | X |
This table is republished from page 39 of [NIST_SP800‑63] (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) .
| Protect Against | Level 1 | Level 2 | Level 3 | Level 4 |
|---|---|---|---|---|
| On-line guessing | X | X | X | X |
| Replay | X | X | X | X |
| Eavesdropper | X | X | X | |
| Verifier impersonation | X | X | ||
| Man-in-the-middle | X | X | ||
| Session hijacking | X |
The following table illustrates the minimum number of factors required at each Authentication Mechanism Level.
| Level | Factors |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
In all cases, implementing a commonly accepted nonce and cross-site scripting protection when entering authentication credentials is required to satisfy all four Authentication Mechanism Levels. All examples below assume this requirement is met.
It should be noted that NIST Authentication Mechanism Levels 1 and 2 have differing password entropy requirements. When working with passwords, you should refer to the [NIST_SP800‑63] (Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006.) specification for more details. All examples below assume the password meets these requirements.
This table provides examples of common authentication technologies and their mapping to NIST Authentication Mechanism Levels, please be aware that there are details not represented in these examples that may bear on the resulting Authentication Mechanism Level.
| Method | Level 1 | Level 2 | Level 3 | Level 4 |
|---|---|---|---|---|
| Password via HTTP | Yes, if challenge-response | |||
| Password via HTTPS | Yes | Yes | ||
| PIN and Digital Certificate via HTTPS | Yes | Yes | Yes | |
| PIN and "soft" OTP token via HTTPS | Yes | Yes | Yes | |
| PIN and "hard" OTP token via HTTPS | Yes | Yes | Yes | |
| PIN and "hard" crypto token via HTTPS | Yes | Yes | Yes | Yes, if FIPS 140-2 Level 2 crypto and Level 3 physical |
| TOC |
The authors would like to thank Andrew Arnott, John Bradley, Kim Cameron, Barry Ferg, George Fletcher, Dick Hardt, Nate Klingstein, Gary Krall, Ben Laurie, Arun Nanda, Drummond Reed, Tatsuki Sakushima, and Allen Tom for their feedback when drafting this specification. David Recordon would also like to acknowledge VeriSign who employed him during the original authoring of this specification.
| TOC |
| [NIST_SP800-63] | Burr, W., Dodson, D., and W. Polk, Ed., “Electronic Authentication Guideline,” April 2006. |
| [OpenIDAuthentication2.0] |<EMAIL_ADDRESS>“OpenID Authentication 2.0,” 2007 (TXT, HTML). |
| [RFC2119] | Bradner, B., “Key words for use in RFCs to Indicate Requirement Levels,” RFC 2119, 1997. |
| [RFC3339] | Klyne, G. and C. Newman, “Date and Time on the Internet: Timestamps,” RFC 3339. |
| [Yadis] | Miller, J., Ed., “Yadis Specification 1.0,” 2005 (PDF, ODT). |
| TOC |
| David Recordon | |
| Six Apart, Ltd. | |
| 548 4th Street | |
| San Francisco, CA 94107 | |
| USA | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://www.sixapart.com/ |
| Michael B. Jones | |
| Microsoft Corporation | |
| One Microsoft Way, Building 40/5138 | |
| Redmond, WA 98052 | |
| USA | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://www.microsoft.com/ |
| Johnny Bufu (editor) | |
| Independent | |
| Email: |<EMAIL_ADDRESS>|
| URI: | |
| Jonathan Daugherty (editor) | |
| JanRain | |
| 5331 SW Macadam Ave. #375 | |
| Portland, OR 97239 | |
| USA | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://janrain.com/ |
| Nat Sakimura | |
| Nomura Research Institute, Ltd. | |
| Marunouchi Kitaguchi Building, 1-6-5 Marunouchi | |
| Chiyoda-ku, Tokyo 100-0005 | |
| Japan | |
| Email: |<EMAIL_ADDRESS>|
| URI: | http://www.nri.co.jp/ |


Although .ksy files are treated as YAML files, and YAML syntax allows quite a few representations of the same content, it is recommended to maintain a certain style in .ksy files to aid collaboration. This document serves as official .ksy style guide. In particular, we strive to make sure that all formats in our formats repository are using this style.
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 RFC 2119.
This document is work in progress, not all sections are complete yet.
1. General formatting
MUST use:
-
Single implicit YAML document per file (i.e. no
---
header). -
No
%YAML x.y
version directives, no%TAG
directives. -
2-space indent.
-
UTF-8 encoding throughout the file.
-
LF (AKA "UNIX") line endings.
-
Trailing newline character in a .ksy file.
-
Block YAML style in most general cases, unless explicitly specified/allowed otherwise.
Formatting of sequences MUST include an indent, i.e.:
Good
|
Bad
|
Formatting of maps-inside-sequences MUST have -
delimiter and first
map element on the same first line, i.e.:
Good
|
Bad
|
All identifiers, docstrings, comments and generally all human-readable text SHOULD be kept in English, unless there’s a very good reason not to do so.
2. Order of sections in a type spec
Use the following order of sections:
-
meta
, if present, MUST go first -
doc
-
doc-ref
-
seq
-
instances
,types
,enums
— use one’s best judgement to order these 3 to maximize readability
3. Meta section (meta
)
Meta section is mostly used to specify additional ("meta") information for a particular file format, so 99% of time it is only present for top-level type. In some cases, meta section might be specified in intermediate types as well, for example, to switch default endianness or encoding. Thus, style recommendations for "top-level" meta sections and "intermediate" meta sections are different, as they serve slightly different purposes.
For top-level meta section, use the following order of keys:
-
id
— main identifier, MUST match the name of the.ksy
file -
Human-readable meta-information (in order of importance, at least one MUST be present):
-
title
-
application
— SHOULD name a particular application, if there’s any; if there are too many to list (for example, network packet formats or executables are used virtually everywhere), then one SHOULD omit this field. -
file-extension
— if there’s only one extension, MUST be a string; if there are several, MUST be an sequence in block form and SHOULD order extensions from most popular extension to least popular. -
xref
— keys inside MUST be in alphabetic order -
tags
— values inside MUST be in alphabetic order
-
-
Legal information —
license
— MUST be a valid SPDX license expression -
Processing instructions:
-
ks-version
— SHOULD list lowest possible KS compiler version that is able to compile this file. -
imports
-
-
Defaults (in alphabetic order):
-
encoding
-
endian
-
For intermediate-level meta sections, use the following order of keys:
-
Defaults (in alphabetic order):
-
encoding
-
endian
-
|
Note
|
KS syntax allows usage of some top-level elements deep inside
the hierarchy — this can be useful during development, for example,
for purpose of grafting one .ksy file into another quickly. However,
in production-quality .ksy files, one MUST NOT use keys like title ,
imports or ks-version (i.e. everything except explicitly listed in
a list above) on intermediate levels.
|
The following keys are reserved for internal use (i.e. debugging and test running) and MUST NOT be used in general-purpose .ksy files:
-
ks-debug
-
ks-opaque-types
4. Documentation
4.1. doc
Formatting:
-
Single-line documentation strings SHOULD BE formatted using raw unquoted string literals.
-
Multi-line SHOULD BE formatted using YAML literal style scalar, i.e. using
: |
syntax. An example:
doc: |
File index entry contains intricate details about file in the
archive: there are both meta-information attributes (such as file
names, locations, various timestamps, etc) and references to
inodes, which can be used to find file body in the container.
For networked locations, file index entry uses an optional
`remote_resource` type. Proper usage sequence is:
* check `code` to be one that requires network usage
* determine file name using `name_networked` instance and check if
it's really a file requested by the user
* proceed to query information from networked resource given by
`resource` attribute
Lines should be wrapped to be 80 columns long. If it doesn’t fit into single line after wrapping, then it’s a multi-line docstring, so use proper multi-line syntax.
There is no formal conversion of docstrings into language-specific docstrings now in KS, but generally we SHOULD keep it close to CommonMark formatting, i.e.:
-
paragraphs separated by an empty line
-
bullet lists created by an asterisk
*
and a space at the beginning of the line -
use backticks
`
to wrap identifiers and small pieces of code
TODO: documentation contents, what should and should no be included
4.2. doc-ref
TODO
5. Sequence attributes
When specifying an attribute, one MUST use the following order of keys:
-
Identifier(s)
-
id
-
-orig-id
— use to specify original ID spelling if transcribing a structure from existing software and/or official spec
-
-
size
-
size-eos
-
type
-
Type-related keys:
-
enum
-
contents
-
pad-right
-
terminator
-
include
-
consume
-
eos-error
-
encoding
-
-
process
-
Repetition-related keys:
-
repeat
-
repeat-eos
,repeat-expr
,repeat-until
-
-
if
-
doc
-
doc-ref
Every key is optional. Attributes SHOULD have at least id
and doc
— however, see below for notes about omitting id
, and doc
SHOULD
NOT be included if it’s trivial (i.e. if it is a copy of id
, and
there is really nothing more to say about that attribute).
5.1. Attribute identifiers (id
)
KS enforces specific identifier style in the language -
lower_underscore_case
(it is needed to be able to convert to other
styles of identifier spelling, like UpperCamelCase
or
lowerCamelCase
, which some target languages use).
KS allows omitting id
. One MUST omit id
to mark up attributes of
unknown/undetermined purpose, i.e. unfinished reverse engineering
work. One MUST NOT omit id
to mark up reserved/unused attributes and
padding, i.e. placeholder that are known to be empty and unused.
One SHOULD use the following rules to maintain consistency across various KSY files. Doing that would maintain the "principle of least surprise" and make life easier to end-users, reducing amount of guesswork.
-
For simple non-repeated fields, use a simple singular form — e.g.
width
,header
,transaction_id
,file
. -
For an array of objects (i.e. with
repeat: something
), use plural form — e.g.files
,transactions
. -
Don’t be overly verbose: use commonly understood abbreviations liberally, if it will improve readability — e.g.
src_mac
orsrc_mac_addr
instead ofsource_media_access_control_address
-
For fields that are designed to be used to detect file type (AKA "magic values"), use
magic
name, or, if there are several of them,magic1
,magic2
, etc. -
For reserved fields which are known to be unused, use
reserved
name (orreserved1
,reserved2
, etc, if there are many of them) -
For fields that designate number / count of something (in particular, number of repetitions of some other structure), use
num_
prefix and plural form — i.e.num_questions
,num_blocks
,num_nodes
-
For fields that designate offset to some particular data structure, use
ofs_
prefix and name of that data structure (as it would appear in the file) — i.e.ofs_block
,ofs_queries
,ofs_path
-
For fields that designate size of some particular data structure (in bytes or some other fixed units), use
len_
prefix and name of that data structure — i.e.len_block
(length of a singleblock
entry),len_blocks
(total length of wholeblocks
array, made ofblock
entries).
|
Note
|
See Transcribing existing specs for more info on preserving / renaming identifiers when transcribing existing spec into KSY. |
5.2. Trailing padding
If you’re using a size-limited substream for a structure, one MUST NOT specify manually calculated or auto-calculated extra padding to make structure consume whole substream. Just omit it — it will save memory and CPU time on parsing.
Good
|
Bad
|
Worst
|
6. Instance attributes
Instance attribute use the superset of keys which are allowed in
sequence attributes (except for id
), thus all ordering rules apply
here as well. Keys MUST appear in this order:
-
-orig-id
(optional) -
io
(optional) -
pos
orvalue
-
All other keys (except for
id
and-orig-id
), in order specified in Sequence attributes
7. Transcribing existing specs
When transcribing structures already described in some other existing
spec or software, note that it’s not necessary to copy existing
identifiers to id
keys (in verbatim or modified form) or even
maintain same structures as types.
The rationale of doing so is that a lot of existing specs rely on particular standards and approaches of some target language and/or platform. Sometimes, existing specs are burdened by some legacy (i.e. they are obliged to maintain names of fields, even when its true purpose was extended since its introduction for compatibility with older software). KS, on the other hand, is cross-platform and cross-language, thus it is not necessary (and in many cases, it’s just impossible) to stick to single platform’s style. And KS-provide API is to be used by new software anyway, so you don’t usually need to be concerned with legacy compatibility.
Use -orig-id
key to specify original names of fields for purposes of
maintaining a reference link to parts of original spec, but,
otherwise, feel free to use a more consistent and language-neutral
approach in naming attributes and types.
7.1. Windows struct
For example, consider this MMCKINFO Windows structure, as specified in MSDN:
typedef struct {
FOURCC ckid;
DWORD cksize;
FOURCC fccType;
DWORD dwDataOffset;
DWORD dwFlags;
} MMCKINFO;
It is pretty inconsistent:
-
Some fields use abbreviated lower case (
ckid
— as it stands for "chunk ID"), others use upper camel case (dwDataOffset
). -
Some fields use so-called "Hungarian notation", i.e. prepending type information before identifier (i.e.
fccType
= "type, four-CC",dwDataOffset
= "data offset, double word"), some don’t (ckid
,cksize
). -
Some abbreviations are very brief (
ckid
), some are pretty verbose (dwDataOffset
). -
Actually,
dwDataOffset
andcksize
specify offset and size of the same data structure (called "chunk’s data member" in human-readable annotation).
Also, this definition does not specify flag values (i.e. in a C struct union syntax), but instead relies of flag constant definitions elsewhere, which is also pretty inconvenient.
Recommended way to lay out that structure in KS would be something like that:
seq:
- id: chunk_id
-orig-id: ckid
type: u4
enum: four_cc
- id: len_data
-orig-id: cksize
type: u4
- id: type
-orig-id: fccType
type: u4
enum: four_cc
- id: ofs_data
-orig-id: dwDataOffset
type: u4
- id: flags
-orig-id: dwFlags
type: flags
size: 4
instances:
data:
pos: ofs_data
size: len_data
types:
flags:
# add a comprehensive type that describes flags here
Note that we’ve clearly separated names and types here, used standard
ofs_
and len_
prefixes for referencing offset and length of a
particular structure (named "data", short for "chunk’s data member",
in this case). Also, we’ve added data
instance to access that
structure directly.
7.2. Linux struct
Another example is ELF executable header, as specified in elf.h in Linux:
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
This one is less inconsistent, but still could be improved:
-
It uses its own convention for specifying "offset", "size" and "count" attributes.
-
It prepends
e_
prefix to every element, which would serve absolutely no purpose in KS -
It uses its own non-standard system of types (
Elf32_Half
,Elf32_Word
,Elf32_Addr
, etc) -
e_ident
actually is a complex 16-byte multi-member structure, which includes 4 bytes of magic number to identify a file format and 12 bytes worth of extra fields -
Abbreviations are way too short (i.e.
ph
for "program header",sh
for "section header",eh
for "ELF header") for a casual user to understand its meaning without a documentation lookup. This can be easily remedied by using slightly more verbose names.
Thus, the recommended way to represent it would be:
seq:
- id: magic
-orig-id: e_ident
contents:
- 0x7f
- "ELF"
doc: Magic number
# add extra members for these 12 bytes here
- id: file_type
-orig-id: e_type
type: u2
doc: Object file type
- id: machine
-orig-id: e_machine
type: u2
doc: Architecture
# ...
- id: ofs_program_headers
-orig-id: e_phoff
type: u4
doc: Program header table file offset
# ...
instances:
program_headers:
pos: ofs_program_headers
repeat: expr
repeat-expr: num_program_headers
size: len_program_header
type: program_header
7.3. C struct as "header"
Sometimes existing implementations use structures where they are actually not necessary. This is, again, frequently done to satisfy constraints of particular implementation, like C struct being of a fixed size. KS does not have these restrictions, so in some cases one can embed C struct "headers" right into the type and it would be totally ok.
For example, consider the following description:
Image file starts with a header, which consists of:
4 bytes - magic number, must be 0x11335577
4 bytes integer - width of image in pixels
4 bytes integer - height of image in pixels
Then raw image data follows, width * height bytes.
Naive C implementation of this format would likely split this format into a "header" structure and a "body", header being declared as:
typedef struct {
uint32_t magic;
uint32_t width;
uint32_t height;
} image_header_t;
Straightforward conversion of that structures would result in:
seq:
- id: header
type: image_header
- id: image_data
size: header.width * header.height
types:
image_header:
seq:
- id: magic
contents: [0x11, 0x33, 0x55, 0x77]
- id: width
type: u4
- id: height
type: u4
However, in KS, this is very redundant and unnecessarily complex. One can just put everything in one simple type — this is easier to read, understand and use (and it does not make up artificial "header" entity where we can avoid it):
seq:
- id: magic
contents: [0x11, 0x33, 0x55, 0x77]
- id: width
type: u4
- id: height
type: u4
- id: image_data
size: width * height


Made by Isabel Jenkins because I couldn't find an Initiative tracker I liked. You can use ENTER as a shortcut for adding a character, and the LEFT and RIGHT arrow keys for moving between turns and DELETE to remove a character whos turn it is. The code for this project can be found on Github.


The lean live stop
command supports the following options:
| Option | Description |
|---|---|
--lean-config <value> |
The Lean configuration file that should be used (defaults to the nearest lean.json). |
--verbose |
Enable debug logging. |
--help |
Display the help text of the lean live stop command and exit. |


Creates a new managed AJAX instance.
Base URL of the server.
Use 0 milliseconds to turn off all cache systems. Default is 1
hour.
Time in milliseconds to wait for a server response. Default are 60
seconds.
Base URL of the server
Set to 0 to turn off all cache systems
Time in milliseconds to wait for a server response
File extension of dictionary entries.
Character to separate a base file name from its page index.
Line character to separate sections.
Character to separate a category from its values.
Character to separate a category's values.
Checks for open requests.
Loads a dictionary entry from the server.
Base name of the translation file
Index of the entry page to load
Requests a server resource.
Base relative path to the requested server resource.
Converts a text into a dictionary entry.
Dictionary text
Converts a Markdown page into a dictionary text.
Markdown page
Generated using TypeDoc
Manages dictionary communication with a server.


--- title: Israel shot 119 date: 2004-04-29T00:00:00.000Z filepathOriginal: photos/IMG0122.jpg filepathThumbnail: photos/IMG0122.thumbnail.jpg filepathPreview: photos/IMG0122.preview.jpg ---
Getting in touch with my childish side at Shorashim