Generally, the craft of programming is the factoring of a set of requirements into a set of functions and data structures.
Complexity is the programmer’s enemy. Functions help hide complexity by creating an abstraction around an operation and giving it a name.
For example, suppose you want to color page elements blood-red on error, using jQuery:
$( 'input[name="first"]' ).css( { color: '#900' } );
$( '#message' ).css( { color: '#900' } );
// Show and make em bleed
$( '#message ul li' ).show( ).css( { color: '#900' } );
Instead, use a self-documenting function:
function color_for_error ( elements ) {
return $( elements ).css( { color: '#900' } );
}
We no longer need to think about what’s under the hood.
color_for_error( 'input[name="first"]' );
color_for_error( '#message' );
color_for_error( '#message ul li' ).show( );
If you can remember the function name, you are done.
It is also easy to guess what the function does by its name.
Don’t repeat yourself if you don’t have to. If you find that you are writing the same code in many places, consider using a function instead.
Now the customer wants the color to fade in on error.
Without the function, you need to change many lines like:
// requires jQuery UI
$( '#message ul li' ).animate( { color: '#900' }, 500 );
With the function, you can make the change in one place:
function color_for_error ( elements ) {
return $( elements ).animate( { color: '#900', 500 } );
}
Now all error coloration will animate. There is no duplicate code that describes the color used, the animation, and the duration.
Think about the previous example:
function color_for_error ( elements ) {
return $( elements ).animate( { color: '#900', 500 } );
}
function sum ( a, b ) {
var result = a + b;
return result;
}
function
—reserved word; begins a function definitionsum
—optional function namea
and b
—optional arguments; input{ }
return
—optional; ends execution, can set a return value; outputfunction
reserved word
function
You can’t use the special keyword function
as a variable name. It is reserved for declaring functions.
Sorry.
function sum
Functions can be declared with or without names.
function
If you declare a function without a name, you should probably save it in a variable, in a property, or pass it into another function.
var sum = function
Naming your function well is the best way to communicate with the person maintaining the code months or years from now.
Choose…
… but choose wisely.
function select_and_close_window ( user_group_id ) {
}
Versus…
// Believe it or not, this is still in some of our JS
function make_it_so ( user_group_id ) {
}
Moral: Quips is for the funny, code for the serious.
Functions can have no arguments:
function sum ( )
Or they can have many:
function sum ( a, b )
var sum = function ( a, b )
a
and b
will contain copies of the values passed in to the function.
function add_to ( target, amount ) {
target += amount;
return target;
}
var a = 1, b = 2;
add_to( a, b ); // → 3, the return value
a; // → 1, not changed inside add_to!
However…
Objects are different.
Variables never contain objects in JS, just references.
It’s like giving someone a post-it with your house’s address. It isn’t the house, it refers to it.
If you photocopied that post-it, both refer to the same physical object. So a copy of a variable referencing an object also references the same object.
var programmer = { times_fooled : 0 };
function fool ( someone ) {
// someone is a copy of programmer, referring to the same object
someone.times_fooled += 1;
}
fool( programmer );
programmer.times_fooled; // → 1
var fib = [ 1, 1, 2, 3, 5, 8 ];
function append_one_fib_number ( seq ) {
if ( seq.length < 2 ) {
throw "Sorry, I need at least two numbers.";
}
var a = seq[seq.length-1];
var b = seq[seq.length-2];
seq.push( a + b );
}
append_one_fib_number( fib );
fib; // → [1, 1, 2, 3, 5, 8, 13]
Arrays are really array-like objects in JavaScript.
var sum = function ( a, b ) {
console.log( arguments ); // → array of arguments
return a + b;
}
// You can call a function with more or less arguments
// than it specifies:
sum( 2, 3, 4 ); // → 5, arguments = [ 2, 3, 4 ]
sum( 2 ); // → NaN, arguments = [ 2 ]
sum = function ( ) {
var i = 0, total = 0;
for ( ; i < arguments.length; ++i ) {
total += arguments[i];
}
return total;
}
sum( ); // → 0
sum( 1, 2, 3, 4 ); // → 10
A function's body is its source code, within curly braces:
function sum ( a, b ) {
var result = a + b;
return result;
}
If the flow of control reaches the end of the function’s block denoted by { }
, execution ends.
Without a return
statement, the function will return an undefined
value.
function sum ( a, b ) {
var result = a + b;
}
sum( 1, 2 ); // → undefined
return
return
ends the function’s execution and optionally sets a return value for the function.
You can return
a value from anywhere:
function sum ( a, b ) {
if ( typeof a !== 'number' ||
typeof b !== 'number' ) {
return; // returns undefined
}
return a + b;
}
sum( 'one', 'two' ); // → undefined
JavaScript got functions almost exactly right.
Functions:
You can create functions, assign them to variables, store them in arrays, and use them like any other value.
// This function has no name, but is referenced by sum
var sum = function ( a, b ) {
return a + b;
};
// my_sum and sum now reference the same function
var my_sum = sum;
// An array of functions!
var my_functions = [ sum, my_sum ];
my_functions[0]( 1, 2 ); // === 3
Functions are special because you can invoke them. They have several interesting properties:
var sum = function ( a, b ) {
return a + b;
};
sum.name; // → "" since it was declared without a name
sum.length; // → 2, # of arguments it defines
sum.toString( ); // → Function’s source code!
There are four ways to invoke a function.
// I can call product before its definition
product( 1, 3 ); // === 3
// Function definitions are "hoisted" to the top
function product ( a, b ) {
return a * b;
}
// I cannot call sum before its assignment, though
sum( 1, 2 ); // fails, undefined function
var sum = function ( a, b ) {
return a + b;
};
sum( 1, 2 ); // === 3
// This is a self-executing function expression
(function ( a, b ) {
return a - b;
})( 4, 1 ); // === 3
var my_object = {
operation : sum
};
my_object.operation( 1, 2 ); // === 3
my_object.another_op = function ( a, b ) {
return a / b;
};
my_object.another_op;
// → the Function object itself created above
my_object.another_op( 10, 2 ); // === 5
// You can use square bracket notation, too
my_object['another_op']( 15, 5 ); // === 3
Functions can be used to create new objects when invoked with the reserved word, new
:
// This is a constructor
var Person = function ( animal ) {
this.power_animal = animal;
};
// This method will be available on all Person objects
Person.prototype.find_power_animal = function ( ) {
return this.power_animal;
}
// Constructor invocation; new is *very* important
var matt = new Person( 'unicorns' );
// And this is method invocation
matt.find_power_animal( ); // → 'unicorns'
new
important?Without new
, Person
is just a function that belongs to the global object, window
:
// Don’t do this! You forgot new!
var matt = Person( 'kitten' );
matt; // → undefined, Person( ) doesn’t have a return statement
// Even worse...
window.power_animal; // → 'kitten'
// Imagine if we had set 'location' instead...
new
apply
can invoke functions as methods on objects:
var matt = new Person( 'unicorns' );
var kevin = new Person( 'puppies' );
var deny_animal = function ( ) {
return ( 'I don’t like “' + this.power_animal + '”' );
}
deny_animal.apply( matt );
// → 'I don’t like “unicorns”'
deny_animal.apply( kevin );
// → 'I don’t like “puppies”'
matt.deny_animal( );
// → Fails, no deny_animal function as a property on matt
deny_animal( );
// → 'I don’t like “undefined”'
jQuery.each( )
?jQuery uses apply
under the hood to make this possible:
// Abbreviated from jQuery’s source, core.js:
jQuery.each = function( obj, callback, args ) {
var name,
i = 0,
length = obj.length;
for ( ; i < length; ) {
if ( callback.apply( obj[ i++ ], args ) === false ) {
break;
}
}
return obj;
}
// All paragraphs should be about unicorns anyway
$( 'p' ).each( function ( ) {
$( this ).html( 'Unicorns!' );
} );
(Not the mouthwash)
Scope is one of the most powerful aspects of functions in JavaScript.
So what the heck is this “scope” anyway?
Scope determines what variables are accessible from a line of code and when it is safe to discard them.
JavaScript has a global object, window
in a browser, and global
in NodeJS.
Every line of code can read and write to the global object.
Therefore, we can say that any property of the global object is always in scope for our functions.
This is both powerful and dangerous.
Notice how the function can see company
below:
// Variables declared outside any function belong
// to the global object
var company = 'Clockwork';
window.company; // → 'Clockwork'
// Functions declared outside other functions belong
// to the global object, too
function get_best_place_to_work ( ) {
return company;
}
window.get_best_place_to_work; // → Function object
console.log( get_best_place_to_work( ) ); // → 'Clockwork'
Function scope is like one-way glass: you can see out of a function, others cannot see in.
JavaScript doesn’t have it!
if ( condition ) {
var tmp = 5;
}
console.log( tmp ); // → 5, tmp is still in scope
var i = 0;
for ( i = 0; i < 10; ++i ) {
// Code here
}
console.log( i ); // → 10
for ( var i = 0; i < 10; ++i ) {
// Code here
}
console.log( i ); // → 10
If you forget to declare a variable with var
, it ends up in the global scope!
function format_location ( city, state ) {
// Don’t do this!! Missing var
location = city + ', ' + state;
return location;
}
console.log( format_location( 'Minneapolis', 'MN' ) );
// → 'Minneapolis, MN'
console.log( window.location );
// → 'Minneapolis, MN'
// OH NOES. You broke the entire browser window.
Always, always use var
!
Thank goodness JavaScript does have...
Only a function’s own code and other functions declared within have access to its scope and data:
function sum ( a, b ) {
var result = a + b;
console.log( 'unicorns = ' + n_unicorns ); // → 1
return result;
}
var n_narwhal = 2,
n_unicorns = 1;
sum( n_narwhal, n_unicorns ); // → 3
console.log( result );
// → undefined, result is only in sum’s scope
console.log( a );
// → undefined, the argument a only exists in sum’s scope
var
hoistingJavaScript will “hoist” any variable declarations with var
to the top of a function:
var result = 10;
function log_result ( ) {
result = 5;
console.log( result );
var result;
}
log_result( ); // → 5
result; // → 10 (because var was hoisted)
Hoisting rearranges the function to look like:
function log_result ( ) {
var result;
result = 5;
console.log( result );
}
var
is not hoisted
var result = 10;
function log_result ( ) {
console.log( result );
var result = 5;
}
log_result( ); // → undefined! "var result" hoists, not result = 5
result; // → 10
This is how the function looks after var
hoisting:
function log_result ( ) {
var result;
console.log( result );
result = 5;
}
Now it should be clear why log_result( )
returns undefined
.
var
hoistingInstead, always declare local variables at the top of a scope (i.e. at the beginning of the function’s body).
function sum_array ( input ) {
var i, len, output = 0;
len = input.length;
for ( i = 0; i < len; ++i ) {
output += input[i];
}
return output;
}
JSLint can help you catch lots of these problems, although it is picky. Try it with these options:
/*jslint plusplus: true, sloppy: true, white: true, browser: true,
devel: true */
You create a closure when defining a function in another:
function build_add_n ( n ) {
// I am a closure
var add_n = function ( a ) {
return a + n;
};
return add_n;
}
The inner function can see everything build_add_n
can, except the special variables arguments
and this
.
Most importantly, it can see n
, so the returned function knows the proper amount to add to its input parameter.
And yes, you can write a function that returns a function!
First, we call build_add_n
, which returns a Function
:
// Make a function that adds 4 to the input
var add_4 = build_add_n( 4 );
console.log( add_4 ); // → Function
// Now, we invoke it as a function
add_4( 2 ); // → 6
The function was able to remember that we passed in 4
for the n
parameter even after the original function call ended!
This was possible because the anonymous function within build_add_n
had access to everything in scope when it was created. This access persists after build_add_n
terminates.
jQuery
The scope-capturing behavior of closures can lead to unpleasant surprises.
function add_handlers ( result ) {
var i, len = result.size( );
for ( i = 0; i < len; ++i ) {
$( result[i] ).on( 'click', function ( ) {
alert( 'I am element number: ' + i +
' and my HTML is: ' + $( this ).html( ) );
} );
}
}
Looks legit, right?
Wrong. Let's look at an example.
jQuery
, cont’dCan anyone explain why this is happening?
Hint: it’s not jQuery
’s fault.
jQuery
, thrilling conclusion
function add_handlers ( result ) {
var i, len = result.size( );
for ( i = 0; i < len; ++i ) {
$( result[i] ).on( 'click', function ( ) {
alert( 'I am element number: ' + i +
' and my HTML is: ' + $( this ).html( ) );
} );
}
}
There is only one i
in the add_handlers
scope. It changes value, but there is only one.
All of the click handlers capture i
in a closure.
All return the current value of i
, 3
, because they all reference the same, single i
that was in scope.
Fibonacci sequence
var solver = function fib ( n ) {
if ( n === 1 ) {
return [ 1 ];
}
else if ( n === 2 ) {
return [ 1, 1 ];
}
// we use fib, not solver to refer to the function itself
// arguments.callee could work here, too
var seq = fib( n - 1 );
seq.push( seq[n - 1 - 1] + seq[ n - 1 - 2] );
return seq;
}
solver( 1 ); // → [1]
solver( 2 ); // → [1, 1]
solver( 10 ); // → [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
There isn’t enough time to fully cover this, but you can use a function’s scope to protect your code from other modules or rename global variables.
This example shows how to rename CWjQuery
to $
:
(function ( $, undefined ) { // self-executing function
// private_var is only visible inside the function
var private_var = '123';
// append to all paragraph tags’ contents
$( 'p' ).each( function ( ) { // executes in each <p>’s context
var element = $( this );
element.html( element.html( ) + private_var );
} );
})( CWjQuery ); // second parameter intentionally left blank
Yes, we’re almost done.
do_stuff
is not a good example; collapse_message
is better)Resist the urge to be too clever.
Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?

You’ve learned:
We can write and test code, too!


Tony Law (born 1969-09-20[ref]) has appeared in 11 episodes between 2011-2014. Tony Law on IMDB. Tony Law on Wikipedia. Tony Law on Chortle.


Total Downloads per Region
Top 10 iOS Downloads
per country
| Territory | Downloads | In-App Purchases |
|---|---|---|
| Mexico | 10,898 | 766 |
| Brazil | 5,943 | 95 |
| United States | 5,552 | 261 |
| Colombia | 3,982 | 40 |
| Guatemala | 1,413 | 22 |
| Peru | 1,378 | 29 |
| Germany | 1,335 | 118 |
| United Kingdom | 1,074 | 90 |
| France | 731 | 10 |
| Costa Rica | 717 | 16 |


This is an unquoted HTML entity. Replace with corresponding character.
foo && bar
foo && bar
There is an unquoted HTML entity, such as &
, >
or <
(instead of &
, >
and <
) in your code. This usually happens when copy-pasting from a web site that has mismanaged its code formatting.
You should go through the entire script and replace HTML entities with their corresponding characters.
Don't rely on ShellCheck to detect all of them. ShellCheck only warns about certain cases in certain contexts, while this issue tends to affect the entire script.
If you want to run a command called amp
after backgrounding another command, add a space: foo & amp;
.


Analyst | Developer | Visualization Designer
Rohan, tell me more..We live in a world where there is no dearth of information. My bachelors degree in Information Technology coupled with my experiences working on numerous projects taught me how to make best use of information while my masters degree in Information Management teaches me how to effectively manage this information. Deducing patterns and understanding behavior trends from seemingly innocuous data intrigues me. I deal with challenges posed by large data sets and devise analytical models to find the right solution.
Access to information provides you, me and everyone in this world an opportunity to make a difference. An opportunity to work on real problems. An opportunity to change the world.
Splunk, Tableau, QlikView, JS charting libraries (D3, Rickshaw, Highcharts and more), Bootstrap, AngularJS
Java, JavaScript, SQL, C, C++, R, HTML, XML, PHP
MySQL, SQL Server, Oracle, Round Robin Database
InDesign, Balsamiq


Persona
- Name:Robert Baca
- Age:32
- Lives:Albuquerque, New Mexico
- Job:Promoter of Special Events
- Technology Used:
- 2010 MacBool Pro 15
- macOS Mojave
- iPhone Xs
- Xfinity Internet
- Sprint Unlimited plan.
- Behaviors and Attitudes:
- In order to promote his events Robert is obligated to be outgoing and approachable He must not only
convince venue owners to host his events but also convince potential customers to attend them.
- He has a very salesman-like persona in order to meet these goals.
- He is very direct with his business ideas but can also be overly abrasive to try and accomplish them.
- Site Usage:
- Posting events he has planned
- Seeing what other venues are out there.
- Goals:
- Robert’s ultimate goal is to maximize profit by getting as many club-goers as he can to attend his shows.
- His intention is to find a reasonably sized venue at a reasonable price that can house the maximize
amount of people that he hopes to bring in.
- After securing a location he needs to promote his event to anyone and everyone that would remotely be
interested in attending.
- Frustrations:
- Robert needs as many potential patrons as possible to find out about his events in case they have an
interest in attending.
- Some web pages aren't easy to navigate and too busy.


I’m a developer working in HTML, CSS, JavaScript, and Ruby on Rails
I used to be in the health and wellness industry working in coaching,sports instruction, and business administration.
I’m taking my organizational and instructive skills to program web applications. Currently, I’m working on a party-planning app using node.js and React.
HTML | CSS | Javascript | Ruby | Python
jQuery | Rails | Node | Express | React | Django | Socket.io | Bootstrap | MaterializeCSS
PostgreSQL | MongoDB
A sketch app where you make a drawing/sketch based off a random prompt.
This app is designed to help you make parties and invite your friends. It includes a special feature where you live chat about the party using socket.io.
Ski Free was a 1991 Microsoft classic computer game that I used to love to play as kid growing up in Colorado's Rocky Mountains. In it, you try to avoid obstacles as you ski down the hill
This app is designed to help you discover, plan, and document activities that you complete in the city where you live. It was inspired by my friend who is hoping to complete a list of things in LA before she moves out of the city.


Delancey's planning application does not comply with planning policy and does not propose any social rented housing.
Its diverse economy of small retailers make the Elephant what it is. Delancey has made no provision for existing traders in its plans
The plans make little provison for the transport infrastructure required to support the development - even TFL has objected.
Delancey is developing the Elephant using a network of shell companies in tax havens including Bermuda, Panama and the British Virgin Islands. It hasn't paid a penny of corporation tax on its neighbouring 'Elephant One' development.


{% extends 'base.html' %} {% block title %}Detail{% endblock title %} {% block content %}
{% for topic in question.topics.all %} #{{ topic.topic_name}} {% endfor %}
Updated: {{ question.updated }} by @{{ question.owner.username }}
What's your judgment ?
Total Votes: {{total_votes}}
Commented by: '{{ comment.user.username }}'' on {{ comment.created}}


This website is designed for NJIT's course IS-601. We needed to research and develop one unique feature per team member and integrate it into the application.
Justin Nietzer worked on creating a login and registration process that includes email verification and Nikolett Muller worked on using the statistics project to create API endpoints and then consume those endpoints using a JavaScript chart.
This website was designed as the second project for NJIT's course IS-601. This class, Web System Development, is designed to experience in the development of Web based systems using an object-oriented programming language and SQL.
In this course, students will learn to develop a web-based system through an intensive hands-on project that requires students to apply real-world problem-solving skills to meet the challenge of developing a web-based information system.
Students will learn the basic principles of web-based applications, MVC application design, how to apply object-oriented design patterns, design a relational database, and write SQL queries to create, retrieve, update, and delete information in a database.


Projects:
Smarts, start:
Name:
Accounts:
Token generate:
Short name:
ISIN:
Amount:
Owner PubKey
Description:
Icon:
...
Category1:
Category2:
Category3:
Smart (JS):
State format:
UI (HTML):
Upload file to blockchain
Clear list file
Upload text to blockchain
Send as type:
html
javascript
css
text
Log from node:


78 The rules are full of details, but the basic idea is simple: Parents can change their children, but children can’t directly change their parents. That’s what you’d expect from the word “inherit”: the inﬂuence just goes in one direction. When a child changes some property, it’s declaring independence from its parent (with respect to that one property). What if you really want the child to be able to make a change in the parent (and therefore in itself and all its siblings)? Remember that in this system any object can tell any other object to do something: When a sprite gets a message for which it doesn’t have a corresponding block, the message is delegated to that sprite’s parent. When a sprite does have the corresponding block, then the message is not delegated. If the script that implements a delegated message refers to my (self), it means the child to which the message was originally sent, not the parent to which the message was delegated. G. List of attributes At the right is a picture of the dropdown menu of attributes in the my block. Several of these are not real attributes, but things related to attributes: ● self: this sprite ● neighbors: a list of nearby sprites 1 ● other sprites: a list of all sprites except myself ● stage: the stage, which is ﬁrst-class, like a sprite ● clones: a list of my temporary clones ● other clones: a list of my temporary siblings ● parts: a list of sprites whose anchor attribute is this sprite ● children: a list of all my clones, temporary and permanent The others are individual attributes: ● anchor: the sprite of which I am a (nested) part ● parent: the sprite of which I am a clone ● temporary?: am I a temporary clone? ● name: my name (same as parent’s name if I’m temporary) ● costumes: a list of the sprite’s costumes ● sounds: a list of the sprite’s sounds ● blocks: a list of the blocks visible in this sprite ● categories: a list of all the block category names ● dangling?: True if I am a part and not in synchronous orbit ● draggable?: True if the user can move me with the mouse ● width, height, left, right, top, boom: The width or height of my costume as seen right now, or the left, etc., edge of my bounding box, taking rotation into account. ● rotation x, rotation y: when reading with my, the same as x position, y position. When set, changes the sprite’s rotation center without moving the sprite, like dragging the rotation center in the paint editor. ● center x, center y: the x and y position of the center of my bounding box, rounded oﬀ–the geometric center of the costume. 1 Neighbors are all other sprites whose bounding boxes intersect the doubled dimensions of the requesting sprite's bounds.


{Rewriter, INVERSES} = require './rewriter'
The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt matches against the beginning of the source code. When a match is found, a token is produced, we consume the match, and start again. Tokens are in the form:
[tag, value, locationData]
where locationData is {first_line, first_column, last_line, last_column}, which is a
format that can be fed directly into Jison. These
are read by jison in the parser.lexer
function defined in coffee-script.coffee.
{Rewriter, INVERSES} = require './rewriter'
Import the helpers we need.
{count, starts, compact, last, repeat, invertLiterate,
locationDataToString, throwSyntaxError} = require './helpers'
The Lexer class reads a stream of CoffeeScript and divvies it up into tagged tokens. Some potential ambiguity in the grammar has been avoided by pushing some extra smarts into the Lexer.
exports.Lexer = class Lexer
tokenize is the Lexer’s main method. Scan by attempting to match tokens one at a time, using a regular expression anchored at the start of the remaining code, or a custom recursive token-matching method (for interpolations). When the next token has been recorded, we move forward within the code past the token, and begin again.
Each tokenizing method is responsible for returning the number of characters it has consumed.
Before returning the token stream, run it through the Rewriter unless explicitly asked not to.
tokenize: (code, opts = {}) ->
@literate = opts.literate # Are we lexing literate CoffeeScript?
@indent = 0 # The current indentation level.
@baseIndent = 0 # The overall minimum indentation level
@indebt = 0 # The over-indentation at the current level.
@outdebt = 0 # The under-outdentation at the current level.
@indents = [] # The stack of all current indentation levels.
@ends = [] # The stack for pairing up tokens.
@tokens = [] # Stream of parsed tokens in the form `['TYPE', value, location data]`.
@chunkLine =
opts.line or 0 # The start line for the current @chunk.
@chunkColumn =
opts.column or 0 # The start column of the current @chunk.
code = @clean code # The stripped, cleaned original source code.
At every position, run through this list of attempted matches,
short-circuiting if any of them succeed. Their order determines precedence:
@literalToken
is the fallback catch-all.
i = 0
while @chunk = code[i..]
consumed = \
@identifierToken() or
@commentToken() or
@whitespaceToken() or
@lineToken() or
@heredocToken() or
@stringToken() or
@numberToken() or
@regexToken() or
@jsToken() or
@literalToken()
Update position
[@chunkLine, @chunkColumn] = @getLineAndColumnFromChunk consumed
i += consumed
@closeIndentation()
@error "missing #{tag}" if tag = @ends.pop()
return @tokens if opts.rewrite is off
(new Rewriter).rewrite @tokens
Preprocess the code to remove leading and trailing whitespace, carriage returns, etc. If we’re lexing literate CoffeeScript, strip external Markdown by removing all lines that aren’t indented by at least four spaces or a tab.
clean: (code) ->
code = code.slice(1) if code.charCodeAt(0) is BOM
code = code.replace(/\r/g, '').replace TRAILING_SPACES, ''
if WHITESPACE.test code
code = "\n#{code}"
@chunkLine--
code = invertLiterate code if @literate
code
Matches identifying literals: variables, keywords, method names, etc.
Check to ensure that JavaScript reserved words aren’t being used as
identifiers. Because CoffeeScript reserves a handful of keywords that are
allowed in JavaScript, we’re careful not to tag them as keywords when
referenced as property names here, so you can still do jQuery.is()
even
though is
means ===
otherwise.
identifierToken: ->
return 0 unless match = IDENTIFIER.exec @chunk
[input, id, colon] = match
Preserve length of id for location data
idLength = id.length
poppedToken = undefined
if id is 'own' and @tag() is 'FOR'
@token 'OWN', id
return id.length
forcedIdentifier = colon or
(prev = last @tokens) and (prev[0] in ['.', '?.', '::', '?::'] or
not prev.spaced and prev[0] is '@')
tag = 'IDENTIFIER'
if not forcedIdentifier and (id in JS_KEYWORDS or id in COFFEE_KEYWORDS)
tag = id.toUpperCase()
if tag is 'WHEN' and @tag() in LINE_BREAK
tag = 'LEADING_WHEN'
else if tag is 'FOR'
@seenFor = yes
else if tag is 'UNLESS'
tag = 'IF'
else if tag in UNARY
tag = 'UNARY'
else if tag in RELATION
if tag isnt 'INSTANCEOF' and @seenFor
tag = 'FOR' + tag
@seenFor = no
else
tag = 'RELATION'
if @value() is '!'
poppedToken = @tokens.pop()
id = '!' + id
if id in JS_FORBIDDEN
if forcedIdentifier
tag = 'IDENTIFIER'
id = new String id
id.reserved = yes
else if id in RESERVED
@error "reserved word \"#{id}\""
unless forcedIdentifier
id = COFFEE_ALIAS_MAP[id] if id in COFFEE_ALIASES
tag = switch id
when '!' then 'UNARY'
when '==', '!=' then 'COMPARE'
when '&&', '||' then 'LOGIC'
when 'true', 'false' then 'BOOL'
when 'break', 'continue' then 'STATEMENT'
else tag
tagToken = @token tag, id, 0, idLength
if poppedToken
[tagToken[2].first_line, tagToken[2].first_column] =
[poppedToken[2].first_line, poppedToken[2].first_column]
if colon
colonOffset = input.lastIndexOf ':'
@token ':', ':', colonOffset, colon.length
input.length
Matches numbers, including decimals, hex, and exponential notation. Be careful not to interfere with ranges-in-progress.
numberToken: ->
return 0 unless match = NUMBER.exec @chunk
number = match[0]
if /^0[BOX]/.test number
@error "radix prefix '#{number}' must be lowercase"
else if /E/.test(number) and not /^0x/.test number
@error "exponential notation '#{number}' must be indicated with a lowercase 'e'"
else if /^0\d*[89]/.test number
@error "decimal literal '#{number}' must not be prefixed with '0'"
else if /^0\d+/.test number
@error "octal literal '#{number}' must be prefixed with '0o'"
lexedLength = number.length
if octalLiteral = /^0o([0-7]+)/.exec number
number = '0x' + parseInt(octalLiteral[1], 8).toString 16
if binaryLiteral = /^0b([01]+)/.exec number
number = '0x' + parseInt(binaryLiteral[1], 2).toString 16
@token 'NUMBER', number, 0, lexedLength
lexedLength
Matches strings, including multi-line strings. Ensures that quotation marks are balanced within the string’s contents, and within nested interpolations.
stringToken: ->
switch quote = @chunk.charAt 0
when "'" then [string] = SIMPLESTR.exec @chunk
when '"' then string = @balancedString @chunk, '"'
return 0 unless string
trimmed = @removeNewlines string[1...-1]
if quote is '"' and 0 < string.indexOf '#{', 1
@interpolateString trimmed, strOffset: 1, lexedLength: string.length
else
@token 'STRING', quote + @escapeLines(trimmed) + quote, 0, string.length
if octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test string
@error "octal escape sequences #{string} are not allowed"
string.length
Matches heredocs, adjusting indentation to the correct level, as heredocs preserve whitespace, but ignore indentation to the left.
heredocToken: ->
return 0 unless match = HEREDOC.exec @chunk
heredoc = match[0]
quote = heredoc.charAt 0
doc = @sanitizeHeredoc match[2], quote: quote, indent: null
if quote is '"' and 0 <= doc.indexOf '#{'
@interpolateString doc, heredoc: yes, strOffset: 3, lexedLength: heredoc.length
else
@token 'STRING', @makeString(doc, quote, yes), 0, heredoc.length
heredoc.length
Matches and consumes comments.
commentToken: ->
return 0 unless match = @chunk.match COMMENT
[comment, here] = match
if here
@token 'HERECOMMENT',
(@sanitizeHeredoc here,
herecomment: true, indent: repeat ' ', @indent),
0, comment.length
comment.length
Matches JavaScript interpolated directly into the source via backticks.
jsToken: ->
return 0 unless @chunk.charAt(0) is '`' and match = JSTOKEN.exec @chunk
@token 'JS', (script = match[0])[1...-1], 0, script.length
script.length
Matches regular expression literals. Lexing regular expressions is difficult to distinguish from division, so we borrow some basic heuristics from JavaScript and Ruby.
regexToken: ->
return 0 if @chunk.charAt(0) isnt '/'
return length if length = @heregexToken()
prev = last @tokens
return 0 if prev and (prev[0] in (if prev.spaced then NOT_REGEX else NOT_SPACED_REGEX))
return 0 unless match = REGEX.exec @chunk
[match, regex, flags] = match
Avoid conflicts with floor division operator.
return 0 if regex is '//'
if regex[..1] is '/*' then @error 'regular expressions cannot begin with `*`'
@token 'REGEX', "#{regex}#{flags}", 0, match.length
match.length
Matches multiline extended regular expressions.
heregexToken: ->
return 0 unless match = HEREGEX.exec @chunk
[heregex, body, flags] = match
if 0 > body.indexOf '#{'
re = @escapeLines body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), yes
if re.match /^\*/ then @error 'regular expressions cannot begin with `*`'
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}", 0, heregex.length
return heregex.length
@token 'IDENTIFIER', 'RegExp', 0, 0
@token 'CALL_START', '(', 0, 0
tokens = []
for token in @interpolateString(body, regex: yes)
[tag, value] = token
if tag is 'TOKENS'
tokens.push value...
else if tag is 'NEOSTRING'
continue unless value = value.replace HEREGEX_OMIT, '$1$2'
Convert NEOSTRING into STRING
value = value.replace /\\/g, '\\\\'
token[0] = 'STRING'
token[1] = @makeString(value, '"', yes)
tokens.push token
else
@error "Unexpected #{tag}"
prev = last @tokens
plusToken = ['+', '+']
plusToken[2] = prev[2] # Copy location data
tokens.push plusToken
Remove the extra “+”
tokens.pop()
unless tokens[0]?[0] is 'STRING'
@token 'STRING', '""', 0, 0
@token '+', '+', 0, 0
@tokens.push tokens...
if flags
Find the flags in the heregex
flagsOffset = heregex.lastIndexOf flags
@token ',', ',', flagsOffset, 0
@token 'STRING', '"' + flags + '"', flagsOffset, flags.length
@token ')', ')', heregex.length-1, 0
heregex.length
Matches newlines, indents, and outdents, and determines which is which. If we can detect that the current line is continued onto the the next line, then the newline is suppressed:
elements
.each( ... )
.map( ... )
Keeps track of the level of indentation, because a single outdent token can close multiple indents, so we need to know how far in we happen to be.
lineToken: ->
return 0 unless match = MULTI_DENT.exec @chunk
indent = match[0]
@seenFor = no
size = indent.length - 1 - indent.lastIndexOf '\n'
noNewlines = @unfinished()
if size - @indebt is @indent
if noNewlines then @suppressNewlines() else @newlineToken 0
return indent.length
if size > @indent
if noNewlines
@indebt = size - @indent
@suppressNewlines()
return indent.length
unless @tokens.length
@baseIndent = @indent = size
return indent.length
diff = size - @indent + @outdebt
@token 'INDENT', diff, indent.length - size, size
@indents.push diff
@ends.push 'OUTDENT'
@outdebt = @indebt = 0
@indent = size
else if size < @baseIndent
@error 'missing indentation', indent.length
else
@indebt = 0
@outdentToken @indent - size, noNewlines, indent.length
indent.length
Record an outdent token or multiple tokens, if we happen to be moving back inwards past several recorded indents. Sets new @indent value.
outdentToken: (moveOut, noNewlines, outdentLength) ->
decreasedIndent = @indent - moveOut
while moveOut > 0
lastIndent =<EMAIL_ADDRESS>- 1]
if not lastIndent
moveOut = 0
else if lastIndent is @outdebt
moveOut -= @outdebt
@outdebt = 0
else if lastIndent < @outdebt
@outdebt -= lastIndent
moveOut -= lastIndent
else
dent = @indents.pop() + @outdebt
if outdentLength and @chunk[outdentLength] in INDENTABLE_CLOSERS
decreasedIndent -= dent - moveOut
moveOut = dent
@outdebt = 0
pair might call outdentToken, so preserve decreasedIndent
@pair 'OUTDENT'
@token 'OUTDENT', moveOut, 0, outdentLength
moveOut -= dent
@outdebt -= moveOut if dent
@tokens.pop() while @value() is ';'
@token 'TERMINATOR', '\n', outdentLength, 0 unless @tag() is 'TERMINATOR' or noNewlines
@indent = decreasedIndent
this
Matches and consumes non-meaningful whitespace. Tag the previous token as being “spaced”, because there are some cases where it makes a difference.
whitespaceToken: ->
return 0 unless (match = WHITESPACE.exec @chunk) or
(nline = @chunk.charAt(0) is '\n')
prev = last @tokens
prev[if match then 'spaced' else 'newLine'] = true if prev
if match then match[0].length else 0
Generate a newline token. Consecutive newlines get merged together.
newlineToken: (offset) ->
@tokens.pop() while @value() is ';'
@token 'TERMINATOR', '\n', offset, 0 unless @tag() is 'TERMINATOR'
this
Use a \
at a line-ending to suppress the newline.
The slash is removed here once its job is done.
suppressNewlines: ->
@tokens.pop() if @value() is '\\'
this
We treat all other single characters as a token. E.g.: ( ) , . !
Multi-character operators are also literal tokens, so that Jison can assign
the proper order of operations. There are some symbols that we tag specially
here. ;
and newlines are both treated as a TERMINATOR
, we distinguish
parentheses that indicate a method call from regular parentheses, and so on.
literalToken: ->
if match = OPERATOR.exec @chunk
[value] = match
@tagParameters() if CODE.test value
else
value = @chunk.charAt 0
tag = value
prev = last @tokens
if value is '=' and prev
if not prev[1].reserved and prev[1] in JS_FORBIDDEN
@error "reserved word \"#{@value()}\" can't be assigned"
if prev[1] in ['||', '&&']
prev[0] = 'COMPOUND_ASSIGN'
prev[1] += '='
return value.length
if value is ';'
@seenFor = no
tag = 'TERMINATOR'
else if value in MATH then tag = 'MATH'
else if value in COMPARE then tag = 'COMPARE'
else if value in COMPOUND_ASSIGN then tag = 'COMPOUND_ASSIGN'
else if value in UNARY then tag = 'UNARY'
else if value in UNARY_MATH then tag = 'UNARY_MATH'
else if value in SHIFT then tag = 'SHIFT'
else if value in LOGIC or value is '?' and prev?.spaced then tag = 'LOGIC'
else if prev and not prev.spaced
if value is '(' and prev[0] in CALLABLE
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
tag = 'CALL_START'
else if value is '[' and prev[0] in INDEXABLE
tag = 'INDEX_START'
switch prev[0]
when '?' then prev[0] = 'INDEX_SOAK'
switch value
when '(', '{', '[' then @ends.push INVERSES[value]
when ')', '}', ']' then @pair value
@token tag, value
value.length
Sanitize a heredoc or herecomment by erasing all external indentation on the left-hand side.
sanitizeHeredoc: (doc, options) ->
{indent, herecomment} = options
if herecomment
if HEREDOC_ILLEGAL.test doc
@error "block comment cannot contain \"*/\", starting"
return doc if doc.indexOf('\n') < 0
else
while match = HEREDOC_INDENT.exec doc
attempt = match[1]
indent = attempt if indent is null or 0 < attempt.length < indent.length
doc = doc.replace /// \n #{indent} ///g, '\n' if indent
doc = doc.replace /^\n/, '' unless herecomment
doc
A source of ambiguity in our grammar used to be parameter lists in function definitions versus argument lists in function calls. Walk backwards, tagging parameters specially in order to make things easier for the parser.
tagParameters: ->
return this if @tag() isnt ')'
stack = []
{tokens} = this
i = tokens.length
tokens[--i][0] = 'PARAM_END'
while tok = tokens[--i]
switch tok[0]
when ')'
stack.push tok
when '(', 'CALL_START'
if stack.length then stack.pop()
else if tok[0] is '('
tok[0] = 'PARAM_START'
return this
else return this
this
Close up all remaining open blocks at the end of the file.
closeIndentation: ->
@outdentToken @indent
Matches a balanced group such as a single or double-quoted string. Pass in a series of delimiters, all of which must be nested correctly within the contents of the string. This method allows us to have strings within interpolations within strings, ad infinitum.
balancedString: (str, end) ->
continueCount = 0
stack = [end]
for i in [1...str.length]
if continueCount
--continueCount
continue
switch letter = str.charAt i
when '\\'
++continueCount
continue
when end
stack.pop()
unless stack.length
return str[0..i]
end = stack[stack.length - 1]
continue
if end is '}' and letter in ['"', "'"]
stack.push end = letter
else if end is '}' and letter is '/' and match = (HEREGEX.exec(str[i..]) or REGEX.exec(str[i..]))
continueCount += match[0].length - 1
else if end is '}' and letter is '{'
stack.push end = '}'
else if end is '"' and prev is '#' and letter is '{'
stack.push end = '}'
prev = letter
@error "missing #{ stack.pop() }, starting"
Expand variables and expressions inside double-quoted strings using Ruby-like notation for substitution of arbitrary expressions.
"Hello #{name.capitalize()}."
If it encounters an interpolation, this method will recursively create a new Lexer, tokenize the interpolated contents, and merge them into the token stream.
str
is the start of the string contents (IE with the “ or “”” stripped
off.)options.offsetInChunk
is the start of the interpolated string in the
current chunk, including the “ or “””, etc… If not provided, this is
assumed to be 0. options.lexedLength
is the length of the
interpolated string, including both the start and end quotes. Both of these
values are ignored if options.regex
is true.options.strOffset
is the offset of str, relative to the start of the
current chunk. interpolateString: (str, options = {}) ->
{heredoc, regex, offsetInChunk, strOffset, lexedLength} = options
offsetInChunk ||= 0
strOffset ||= 0
lexedLength ||= str.length
Parse the string.
tokens = []
pi = 0
i = -1
while letter = str.charAt i += 1
if letter is '\\'
i += 1
continue
unless letter is '#' and str.charAt(i+1) is '{' and
(expr = @balancedString str[i + 1..], '}')
continue
NEOSTRING is a fake token. This will be converted to a string below.
tokens.push @makeToken('NEOSTRING', str[pi...i], strOffset + pi) if pi < i
unless errorToken
errorToken = @makeToken '', 'string interpolation', offsetInChunk + i + 1, 2
inner = expr[1...-1]
if inner.length
[line, column] = @getLineAndColumnFromChunk(strOffset + i + 1)
nested = new Lexer().tokenize inner, line: line, column: column, rewrite: off
popped = nested.pop()
popped = nested.shift() if nested[0]?[0] is 'TERMINATOR'
if len = nested.length
if len > 1
nested.unshift @makeToken '(', '(', strOffset + i + 1, 0
nested.push @makeToken ')', ')', strOffset + i + 1 + inner.length, 0
Push a fake ‘TOKENS’ token, which will get turned into real tokens below.
tokens.push ['TOKENS', nested]
i += expr.length
pi = i + 1
tokens.push @makeToken('NEOSTRING', str[pi..], strOffset + pi) if i > pi < str.length
If regex, then return now and let the regex code deal with all these fake tokens
return tokens if regex
If we didn’t find any tokens, then just return an empty string.
return @token 'STRING', '""', offsetInChunk, lexedLength unless tokens.length
If the first token is not a string, add a fake empty string to the beginning.
tokens.unshift @makeToken('NEOSTRING', '', offsetInChunk) unless tokens[0][0] is 'NEOSTRING'
if interpolated = tokens.length > 1
@token '(', '(', offsetInChunk, 0, errorToken
Push all the tokens
for token, i in tokens
[tag, value] = token
if i
Create a 0-length “+” token.
plusToken = @token '+', '+' if i
locationToken = if tag == 'TOKENS' then value[0] else token
plusToken[2] =
first_line: locationToken[2].first_line
first_column: locationToken[2].first_column
last_line: locationToken[2].first_line
last_column: locationToken[2].first_column
if tag is 'TOKENS'
Push all the tokens in the fake ‘TOKENS’ token. These already have sane location data.
@tokens.push value...
else if tag is 'NEOSTRING'
Convert NEOSTRING into STRING
token[0] = 'STRING'
token[1] = @makeString value, '"', heredoc
@tokens.push token
else
@error "Unexpected #{tag}"
if interpolated
rparen = @makeToken ')', ')', offsetInChunk + lexedLength, 0
rparen.stringEnd = true
@tokens.push rparen
tokens
Pairs up a closing token, ensuring that all listed pairs of tokens are correctly balanced throughout the course of the token stream.
pair: (tag) ->
unless tag is wanted = last @ends
@error "unmatched #{tag}" unless 'OUTDENT' is wanted
@outdentToken last(@indents), true
return @pair tag
@ends.pop()
Returns the line and column number from an offset into the current chunk.
offset
is a number of characters into @chunk.
getLineAndColumnFromChunk: (offset) ->
if offset is 0
return [@chunkLine, @chunkColumn]
if offset >= @chunk.length
string = @chunk
else
string = @chunk[..offset-1]
lineCount = count string, '\n'
column = @chunkColumn
if lineCount > 0
lines = string.split '\n'
column = last(lines).length
else
column += string.length
[@chunkLine + lineCount, column]
Same as “token”, exception this just returns the token without adding it to the results.
makeToken: (tag, value, offsetInChunk = 0, length = value.length) ->
locationData = {}
[locationData.first_line, locationData.first_column] =
@getLineAndColumnFromChunk offsetInChunk
Use length - 1 for the final offset - we’re supplying the last_line and the last_column, so if last_column == first_column, then we’re looking at a character of length 1.
lastCharacter = Math.max 0, length - 1
[locationData.last_line, locationData.last_column] =
@getLineAndColumnFromChunk offsetInChunk + lastCharacter
token = [tag, value, locationData]
token
Add a token to the results.
offset
is the offset into the current @chunk where the token starts.
length
is the length of the token in the @chunk, after the offset. If
not specified, the length of value
will be used.
Returns the new token.
token: (tag, value, offsetInChunk, length, origin) ->
token = @makeToken tag, value, offsetInChunk, length
token.origin = origin if origin
@tokens.push token
token
Peek at a tag in the current token stream.
tag: (index, tag) ->
(tok = last @tokens, index) and if tag then tok[0] = tag else tok[0]
Peek at a value in the current token stream.
value: (index, val) ->
(tok = last @tokens, index) and if val then tok[1] = val else tok[1]
Are we in the midst of an unfinished expression?
unfinished: ->
LINE_CONTINUER.test(@chunk) or
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
'**', 'SHIFT', 'RELATION', 'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
Remove newlines from beginning and (non escaped) from end of string literals.
removeNewlines: (str) ->
str.replace(/^\s*\n\s*/, '')
.replace(/([^\\]|\\\\)\s*\n\s*$/, '$1')
Converts newlines for string literals.
escapeLines: (str, heredoc) ->
Ignore escaped backslashes and remove escaped newlines
str = str.replace /\\[^\S\n]*(\n|\\)\s*/g, (escaped, character) ->
if character is '\n' then '' else escaped
if heredoc
str.replace MULTILINER, '\\n'
else
str.replace /\s*\n\s*/g, ' '
Constructs a string token by escaping quotes and newlines.
makeString: (body, quote, heredoc) ->
return quote + quote unless body
Ignore escaped backslashes and unescape quotes
body = body.replace /// \\( #{quote} | \\ ) ///g, (match, contents) ->
if contents is quote then contents else match
body = body.replace /// #{quote} ///g, '\\$&'
quote + @escapeLines(body, heredoc) + quote
Throws a compiler error on the current position.
error: (message, offset = 0) ->
TODO: Are there some cases we could improve the error line number by passing the offset in the chunk where the error happened?
[first_line, first_column] = @getLineAndColumnFromChunk offset
throwSyntaxError message, {first_line, first_column}
Keywords that CoffeeScript shares in common with JavaScript.
JS_KEYWORDS = [
'true', 'false', 'null', 'this'
'new', 'delete', 'typeof', 'in', 'instanceof'
'return', 'throw', 'break', 'continue', 'debugger'
'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally'
'class', 'extends', 'super'
]
CoffeeScript-only keywords.
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when']
COFFEE_ALIAS_MAP =
and : '&&'
or : '||'
is : '=='
isnt : '!='
not : '!'
yes : 'true'
no : 'false'
on : 'true'
off : 'false'
COFFEE_ALIASES = (key for key of COFFEE_ALIAS_MAP)
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat COFFEE_ALIASES
The list of keywords that are reserved by JavaScript, but not used, or are used by CoffeeScript internally. We throw an error when these are encountered, to avoid having a JavaScript error at runtime.
RESERVED = [
'case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum'
'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind'
'__indexOf', 'implements', 'interface', 'package', 'private', 'protected'
'public', 'static', 'yield'
]
STRICT_PROSCRIBED = ['arguments', 'eval']
The superset of both JavaScript keywords and reserved words, none of which may be used as identifiers or properties.
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED)
exports.RESERVED = RESERVED.concat(JS_KEYWORDS).concat(COFFEE_KEYWORDS).concat(STRICT_PROSCRIBED)
exports.STRICT_PROSCRIBED = STRICT_PROSCRIBED
The character code of the nasty Microsoft madness otherwise known as the BOM.
BOM = 65279
Token matching regexes.
IDENTIFIER = /// ^
( [$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]* )
( [^\n\S]* : (?!:) )? # Is this a property name?
///
NUMBER = ///
^ 0b[01]+ | # binary
^ 0o[0-7]+ | # octal
^ 0x[\da-f]+ | # hex
^ \d*\.?\d+ (?:e[+-]?\d+)? # decimal
///i
HEREDOC = /// ^ ("""|''') ((?: \\[\s\S] | [^\\] )*?) (?:\n[^\n\S]*)? \1 ///
OPERATOR = /// ^ (
?: [-=]> # function
| [-+*/%<>&|^!?=]= # compound assign / compare
| >>>=? # zero-fill right shift
| ([-+:])\1 # doubles
| ([&|<>*/%])\2=? # logic / shift / power / floor division / modulo
| \?(\.|::) # soak access
| \.{2,3} # range or splat
) ///
WHITESPACE = /^[^\n\S]+/
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/
CODE = /^[-=]>/
MULTI_DENT = /^(?:\n[^\n\S]*)+/
SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/
Regex-matching-regexes.
REGEX = /// ^
(/ (?! [\s=] ) # disallow leading whitespace or equals signs
[^ [ / \n \\ ]* # every other thing
(?:
(?: \\[\s\S] # anything escaped
| \[ # character class
[^ \] \n \\ ]*
(?: \\[\s\S] [^ \] \n \\ ]* )*
]
) [^ [ / \n \\ ]*
)*
/) ([imgy]{0,4}) (?!\w)
///
HEREGEX = /// ^ /{3} ((?:\\?[\s\S])+?) /{3} ([imgy]{0,4}) (?!\w) ///
HEREGEX_OMIT = ///
((?:\\\\)+) # consume (and preserve) an even number of backslashes
| \\(\s|/) # preserve escaped whitespace and "de-escape" slashes
| \s+(?:#.*)? # remove whitespace and comments
///g
Token cleaning regexes.
MULTILINER = /\n/g
HEREDOC_INDENT = /\n+([^\n\S]*)/g
HEREDOC_ILLEGAL = /\*\//
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | :: ) ///
TRAILING_SPACES = /\s+$/
Compound assignment tokens.
COMPOUND_ASSIGN = [
'-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>='
'&=', '^=', '|=', '**=', '//=', '%%='
]
Unary tokens.
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO']
UNARY_MATH = ['!', '~']
Logical tokens.
LOGIC = ['&&', '||', '&', '|', '^']
Bit-shifting tokens.
SHIFT = ['<<', '>>', '>>>']
Comparison tokens.
COMPARE = ['==', '!=', '<', '>', '<=', '>=']
Mathematical tokens.
MATH = ['*', '/', '%', '//', '%%']
Relational tokens that are negatable with not
prefix.
RELATION = ['IN', 'OF', 'INSTANCEOF']
Boolean tokens.
BOOL = ['TRUE', 'FALSE']
Tokens which a regular expression will never immediately follow, but which a division operator might.
See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
Our list is shorter, due to sans-parentheses method calls.
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--']
If the previous token is not spaced, there are more preceding tokens that force a division parse:
NOT_SPACED_REGEX = NOT_REGEX.concat ')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']'
Tokens which could legitimately be invoked or indexed. An opening parentheses or bracket following these tokens will be recorded as the start of a function invocation or indexing operation.
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']
INDEXABLE = CALLABLE.concat 'NUMBER', 'BOOL', 'NULL', 'UNDEFINED'
Tokens that, when immediately preceding a WHEN
, indicate that the WHEN
occurs at the start of a line. We disambiguate these from trailing whens to
avoid an ambiguity in the grammar.
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']
Additional indent in front of these is ignored.
INDENTABLE_CLOSERS = [')', '}', ']']


At Spire Labs, we first used Whitelister for filtering and validating incoming parameters. You can find a simplified examples of that and others in examples.
To use the examples, clone the repo and run $ node examples/[filename].js
- e.g. $ node examples/express-app.js
.


Rabbits are important laboratory animals, widely used in many areas of biomedical research, including the production of antibodies and recombinant proteins. Rabbit models have contributed to the understanding of human diseases and the development of therapeutic compounds, devices and techniques. However it has not been possible to engineer precise genetic alterations in rabbits because they have so far been refractory to the two key enabling technologies; (I) rabbit embryonic stem (ES) cells capable of contributing to the germ line have yet to be derived, and (II) rabbits are particularly difficult to produce by somatic cell nuclear transfer [1].
The power and facility of gene targeting in ES cells has made the mouse by far the most intensively studied mammal [2]. Extending gene targeting to other species would deepen our understanding of gene function and further the development of many valuable biomedical applications, but the lack of fully functional ES cells has been a long-standing obstacle.
Nuclear transfer from cultured somatic cells (SCNT) was developed to circumvent the requirement for ES cells to generate gene-targeted animals. This is, however, technically difficult, and more than ten years since our first demonstration of targeting COL1A1 in sheep [3], there are still few other examples: PRNP in sheep, cattle and goats [4]– [6], GGTA1 in pigs [7], [8], IGH in cattle and pigs [5], [9], [10], IGKC in pigs [11] and CFTR in pigs [12].
Zinc-finger nucleases (ZFNs) are new tools that promise to radically simplify gene knockout and targeted gene replacement. An appropriately designed ZFN can create a double-strand break at a single predetermined site in the genomic DNA of an organism. In eukaryotes, double-strand break repair pathways often create small insertions and deletions at the break site, a useful means of inactivating genes of interest (for review, see Urnov et al. [13]). ZFN cleavage can also stimulate homology-directed genetic exchange between an episomal donor construct and a chromosomal locus, as first demonstrated for a native locus in Drosophila [14] and for endogenous loci in human cells [15]– [17].
A particularly promising approach is ZFN-mediated gene knockout directly in early embryos, because it offers a one-step method without any cell intermediate, as shown for zebrafish [18], [19], rats [20], [21] and mice [22]. Most recently, ZFN-mediated gene targeting by homologous recombination has been achieved in mice and rats [23], [24]. However ZFNs are likely to make their greatest impact in species where classical means of gene targeting are not available. Here we demonstrate that ZFNs enable precise genetic engineering in a particularly intractable species.
Given the failure of other techniques, we wished to investigate whether ZFN technology offers a practical means of targeted gene inactivation, addition or replacement in the rabbit. The immunoglobulin M locus was chosen as a suitable target because inactivation of endogenous immunoglobulins is a necessary first step for the production of human antibodies in a human immunoglobulin transgenic rabbit model.
ZFNs directed against exons 1–4 of rabbit IgM ( Figure S1) were designed using an archive of pre-validated zinc finger modules as described [14], [15], [17]– [20]. The ZFNs were ranked for activity using a budding yeast based system previously shown to identify nucleases active in editing endogenous loci in zebrafish and rat [18], [20], and the highest-ranking ZFN for each exon was selected for in-vivo use. Target sequence, structure and recognition helices of the selected ZFNs are shown in Figure 1 A–C.
A. Recognition sequences in the rabbit IgM locus for ZFNs used in this study. B. Screening data using a budding yeast proxy system (see Materials and Methods) for ZFNs shown in panel A. The first sample represents positive control ZFNs that target the human CCR5 locus [51]. The grey and black bars represent reporter gene correction levels at low and high levels of ZFN synthesis, respectively. As detailed in Doyon et al. [18], the ZFN-encoding transgene is inducible, and this allows measurement of ZFN activity at different levels of the nuclease. C. DNA target sequences and recognition helices for the ZFNs used in the present work. The binding regions of left (ZFN-L) and right (ZFN-R) zinc finger protein array are underlined. Bases in capital letters are those that contribute to binding of the ZFP arrays. D. Summary of rabbit IgM mutant alleles obtained and characterized in offspring from ZFN microinjections. Stillborn animals are marked with an asterisk. The genotype of each allele is indicated to the right of the DNA sequence; inserted sequences are highlighted in red.
The kinetics of ZFN activity in fertilized oocytes should be as rapid as possible, preferably before the first cleavage, to ensure that ZFN induced mutations are included in the germ line. ZFN activity should also be transient, to avoid possible accumulation of additional mutations in the developing embryo. In pilot experiments we microinjected EGFP mRNA diluted in either EDTA solution (0.1 mM, pH 8), or Tris/EDTA buffer (5 mM/0.1 mM, pH 7.5) into one of the two pronuclei or the cytoplasm of fertilized rabbit oocytes. Microinjection was verified in each oocyte by observing slight swelling of the pronucleus, or disturbance in the cytoplasm caused by solution streaming from the capillary. Of the oocytes injected into the pronucleus, only those injected with Tris/EDTA survived and developed further. Following cytoplasmic injection, survival and development was better in embryos injected with EDTA. Cytoplasmic microinjection of mRNA diluted in EDTA also led to earlier onset and higher EGFP expression at lower concentrations than pronuclear microinjection of mRNA in Tris/EDTA ( Table S1).
We then examined technical parameters that could affect embryo viability and the levels of ZFN activity. These included ZFN mRNA concentration, site of microinjection (cytoplasm or pronucleus), and in vitro polyadenylation of mRNA. Injected embryos were cultured in vitro and monitored visually for development up to blastocyst stage. Exons 1 or 2 of the IgM locus were then amplified from blastocysts by nested PCR. Results indicated that: the optimal mRNA concentration range was between 3 to 6 ng/µl; microinjection of non-polyadenylated mRNA did not lead to effective mutagenesis; and microinjection into the pronucleus did not lead to effective mutagenesis (shown for exon 1 in Table S2). For gene inactivation experiments we therefore microinjected a 1∶1 mixture of polyadenylated mRNAs coding for the two components of a ZFN heterodimer, diluted to a total of 3 to 5 ng/µl in 0.1 mM EDTA, into the cytoplasm of pronuclear stage fertilized rabbit oocytes.
mRNA coding for ZFN pair 18255/18257 targeted to IgM exon 1 (see Figure 1) was injected into 267 oocytes, 208 embryos were transferred into recipients and 17 live offspring were born. mRNA coding for ZFN pair 18276/18277 targeted to IgM exon 2 (see Figure 1) was injected into 259 oocytes, 212 embryos were transferred into recipients, and 17 live offspring were also born. Sequence analysis of the IgM locus in these 34 rabbits revealed that six animals carried mutations in exon 1, and four had mutations in exon 2. Eighteen stillborn rabbits were also analyzed. Mutations at the IgM locus were detected in six animals ( Table 1), a similar proportion as observed in the live offspring. DNA sequence analysis of live and stillborn rabbits revealed a variety of mutations at the IgM locus, including deletions of 1 to 25 bp, single base insertions, and combinations of small deletions and insertions. Results are summarized in Figure 1D. Two live and one stillborn animal were found to carry two independent mutations at the IgM locus, suggesting that these were compound heterozygotes.
| Target/ZFN Pair | Experiment | mRNA conc. (ng/ µl) | Oocytes injected/transferred | Oocytes per recipient | Offspring live/stillborn | F0 mutated (% of live offspring) | Mutations in F0 | Founder (line) ID/gender | Mutated/total offspring in F1 (%) |
| IgM exon 118255/18257 | 1 | 3 | 40/22 | 11 | 2/1 | 1 (50) | Δ1; Δ25 | 22821/f | 0/17 ° (0) |
| 11 | 1/0 | 1 (100) | Δ10 | 22822/f # | |||||
| 2 | 3 | 133/120 | 30 | 5/0 | 1 (20) | +11 (Δ7+18) | 22823/m | 1/80 (1.3) | |
| 30 | 0/9 | 4 * (0) | Δ5; Δ10; +1; +5 (Δ5+10) | ||||||
| 30 | 7/2 | 3 (43) | Δ10; Δ1 | 22826/m | 21 **/83 (25) | ||||
| Δ10 | 22828/f § | ||||||||
| Δ7 (Δ8+1) | 22830/f | 7/14 (50) | |||||||
| 3 | 5 | 94/66 | 22 | 1/1 | 0 (0) | ||||
| 22 | 1/2 | 1 * (0) | Δ8; Δ13 | ||||||
| 22 | 0 | ||||||||
| IgM exon218276/18277 | 4 | 3 | 96/75 | 20 | 1/0 | 1 (100) | Δ16 | 24656/f | 2/5 (40) |
| 28 | 2/0 | 1 (50) | Δ19 | 24657/m | 5/16 (31) | ||||
| 27 | 0/2 | 1 * (0) | Δ15 | ||||||
| 5 | 3 | 27/25 | 25 | 0/1 | 0 (0) | ||||
| 6 | 3 | 136/112 | 28 | 0/0 | 0 (0) | ||||
| 28 | 6/0 | 0 (0) | |||||||
| 28 | 6/0 | 1 (17) | Δ15 | 25035/f | 1/6 (17) | ||||
| 28 | 2/0 | 1 (50) | +1 | 25039/m | 2/13 (15) |
*Stillborn.
No further breeding.
Exitus at 14 weeks of age.
Exitus at 19 weeks of age.
**10 offspring with 1 bp deletion; 11 offspring with 10 bp deletion.
Of the ten rabbits identified as carrying ZFN induced mutant IgM alleles, eight (four males and four females) survived to sexual maturity and were used as founders to produce a F1 generation. Seven F0 rabbits transmitted mutant IgM alleles at frequencies ranging from 1.3% to 50% ( Table 1). Among these, one male (22826) and one female (22821) both carried two independent mutations. The female failed to pass on either mutation to the next generation, but the male transmitted both mutations at a similar rate, suggesting that founder rabbits had different degrees of mosaicism.
In the immune response, the first antibodies to appear are of the IgM class. IgG, IgA, or IgE are then generated from IgM via class-switch recombination. Lack of IgM should therefore result in the absence of other isotypes. To determine if this was the case in our rabbits, we generated IgM knockout rabbits by breeding ZFN-treated founders and measured both IgM and IgG in serum.
The Δ1 (male founder 22826) and Δ7 (female founder 22830) mutations in exon 1 both result in frameshifts in the IgM coding region and were predicted to disrupt expression of full-length protein. The founder male 22826 was intercrossed with the founder female 22830 to generate Δ1/Δ7 compound heterozygous animals. Three mutated F1 animals were obtained, one carrying the Δ1 mutation, one carrying the Δ7 mutation, and one Δ1/Δ7 compound heterozygote. The Δ7 mutation was also bred to homozygosity in an F2 generation. Serum IgM and IgG levels in these animals were determined by ELISA at 10 weeks of age. IgM and IgG levels were similar to wild type in Δ1 and Δ7 heterozygotes, but were undetectable in Δ1/Δ7 and Δ7/Δ7 rabbits ( Table 2). The peripheral B-cell population in Δ1/Δ7 and Δ7/Δ7 rabbits was characterized by FACS analysis; only ∼0.1% of PBMCs stained positive for surface IgM (sIgM), and sIgG positive PBMCs were completely absent. In contrast, control wild type animals showed 21.4% of PBMC positive for sIgM and 0.7% positive for sIgG, typical for rabbit blood. A rabbit pan B-cell specific antibody [25] also revealed significantly fewer stained cells in the Δ1/Δ7 animal (1.5%) than in wild type (22.9%), see Figure 2 A and B. A second and well-defined B cell-specific marker is CD79a, constituting a part of the B cell receptor. Using an antibody that binds to the highly conserved intracellular domain of CD79a [26], no B cell receptor positive cells could be detected in Δ1/Δ7 and Δ7/Δ7 rabbits, whereas 41.4% of all PBMCs were marked as B cells in control animals ( Figure 2 C).
A. The top panels show representative dot plot profiles of peripheral blood mononuclear cells (PBMCs) of a wild type rabbit stained with antibodies specific for surface IgM (left) and surface IgG (right). Lower panels show Δ1/Δ7 PBMCs stained with the same antibodies. B. The upper dot plot shows wild type PBMCs immunostained with RACT30A, an antibody that recognizes a rabbit B-cell specific surface protein [25]. The lower panel shows Δ1/Δ7 PBMCs stained the same way. A and B: Only live PBMCs were included in these analyses. C. Dot plot profiles showing wild type (left) and Δ7/Δ7 (right) PBMCs, stained intracellularly for the B cell receptor component CD79a. The percentage of gated B cells (IgM +, IgG +, rabbit B cell marker +, or CD79a +) of all PBMCs is indicated in the upper right of each dot plot.
| Parental lines | Genotype of offspring | Serum IgM (mg/ml) | Serum IgG (mg/ml) |
| 22830×22826 | Δ7, Δ1 | bdl * | bdl * |
| 22830×22826 | Δ7, wt | 2.7 | 1.4 |
| 22830×22826 | Δ1, wt | 1.1 | 1.3 |
| 25035×22826 | Δ15, Δ1 | 1.5 | 0.9 |
| 22830×22830 | Δ7, Δ7 | bdl * | bdl * |
| Wild type (3 animals) | wt, wt | 2.2 | 1.8 |
| 1.7 | 5.7 | ||
| 2.2 | 0.9 |
*Below detection limit: <500 ng/ml for rbIgM ELISA and <20 ng/ml for rbIgG ELISA.
The founder 22826 (Δ1 mutation) was also crossed with founder 25035, which carries a Δ15 deletion in exon 2 predicted to result in an in-frame loss of 5 amino acids. Serum analysis of Δ1/Δ15 F1 offspring revealed normal levels of IgM and IgG ( Table 2). Thus, the Δ15 mutation does not appear to affect functional IgM expression or B-cell development.
These results show that ZFN-induced knockout alleles of the rabbit IgM gene transmit normally through the germline, and in homozygous form result in animals that are IgM- and IgG-deficient, but otherwise do not display obvious phenotypic abnormalities. It remains to be elucidated what effect the loss of IgM and IgG has on overall immunological function in these rabbits.
We then tested if ZFN-mediated targeted sequence replacement was feasible directly in the oocyte. A gene targeting vector, IgME1, was designed to replace IgM exon 1 with a PGK neo cassette, providing ∼1.9 kb of novel sequence. The strategy is illustrated in Figure 3; the full sequence of the gene-targeting vector is shown in Figure S2. Although the presence of the PGK neo gene was used for screening, no antibiotic selection was used to enrich for neo-positive embryos.
The structure of the IgME1 gene targeting vector, regions of homology with the IgM locus, and the predicted structure of the targeted locus are shown. Exons are marked and numbered as open boxes. The ZFN 18255/18257 cleavage site within exon 1 is indicated by a vertical arrow. The 5′ and 3′ junction PCR products are indicated; with positions of primers marked by arrows, and restriction sites for MscI and ApaI marked by (M) and (A), respectively. The hybridization probe and the diagnostic fragments used for Southern analysis are indicated in the lower part of the diagram. HinDIII (H) and BspHI (B) restriction sites are marked.
Mixtures of MluI linearised IgME1 DNA (concentrations ranging from 5 to 15 ng/µl) and ZFN 18255/18257 mRNAs (concentrations ranging from 3 to 9 ng/µl of each) were injected into pronuclear stage fertilized oocytes, see Table 3. Since ZFN mRNAs are most effective when injected into the cytoplasm, but IgME1 targeting vector DNA must be located in the nucleus to serve as the donor during homology-directed repair, we employed a two-step microinjection procedure similar to that described by Meyer et al. [23]. A portion of the mRNA/DNA mixture was first injected into a pronucleus to locate the vector DNA with the nuclear DNA. Then, on removing the injection needle, a second dose was injected into the cytoplasm to enable translation of ZFN mRNA. Microinjected oocytes were cultured to blastocyst stage and a total of 242 blastocysts were analyzed by PCR for targeted gene replacement events. Correct gene editing was detected in three blastocysts, as judged by the presence of a diagnostic 1.758 kb PCR product spanning the 5′ junction of the target site, see Figure 4. Data summarized in Table 3 show that concentrations of ZFN mRNA slightly higher than those used for mutagenesis were most effective in driving targeted sequence replacement. Combined data for all mRNA and targeting vector DNA concentrations indicated an overall rate of 1.2% targeted sequence replacement, but efficiency at the most effective mRNA/DNA concentrations was higher (17% at 9 ng/µl ZFN mRNA plus 10–15 ng/µl IgME1 DNA). Positive blastocysts were also screened for the presence of an intact IgM exon 1 by PCR. All gave a positive result, indicating that targeting had occurred at just one IgM allele.
Upper panel, representative 5′ junction PCR products amplified from blastocysts. Upper panel left, 5′ junction PCR from fetuses. Predicted 5′ PCR fragment size: 1.758 kb. Upper panel right, restriction digests of 5′ PCR fragment amplified from fetus 7. Predicted restriction fragment sizes: ApaI - 1242, 516 bp; MscI - 853, 687, 219 bp. Middle and bottom panels, 5′ and 3′ junction PCR products amplified from fetuses 1–12. Predicted 3′ PCR fragment size: 1.683 kb. M - size markers.
| Concentration of ZFN mRNA (ng/ µl) | Concentration of vector DNA (ng/ µl) | Oocytes injected | Blastocysts screened | Blastocysts positive for targeting |
| 3 | 5 | 102 | 45 | 0 |
| 3 | 10 | 39 | 26 | 0 |
| 6 | 5 | 76 | 43 | 0 |
| 6 | 10 | 118 | 76 | 1 |
| 6 | 15 | 28 | 18 | 0 |
| 9 | 10 | 17 | 6 | 1 |
| 9 | 15 | 60 | 28 | 1 |
Oocytes were then injected with 9 ng/µl ZFN 18255/18257 mRNA plus 10 ng/µl IgME1 DNA, and transferred to recipients. Seventeen fetuses were removed at day 15 of gestation and analyzed. All showed normal development, and examination of the uterine horns showed no evidence of degenerate or absorbed conceptuses. DNA was prepared from each fetus and screened by PCR. Three fetuses (2, 7 and 9) showed amplification of a 1.758 kb product across the 5′ junction and a 1.683 kb fragment across the 3′ junction of the target site, consistent with replacement of IgM exon 1 with the PGK neo cassette by homologous recombination, see Figure 4. The identity of the 5′ PCR product was confirmed by restriction digestion, see Figure 4. In addition, the DNA sequence of the 5′ PCR product from fetus 7 was determined and found to be identical to that predicted for the targeted locus, see Figure S2. Southern hybridization analysis was carried out using genomic DNA from the three PCR positive and five PCR negative fetuses. The Southern blotting scheme is outlined in Figure 3 and results shown in Figure S3. Each of the PCR positive fetuses showed a diagnostic restriction fragment spanning the 3′ junction of the target site, consistent with targeted replacement at the first exon, and also a fragment corresponding to a wild type IgM allele. The five negative fetuses showed only the wild type allele.
In summary, our data show efficient ZFN-induced gene disruption and homology-directed sequence replacement through microinjection in rabbit oocytes. We have obtained the first rabbits genetically engineered at a specific endogenous locus, the immunoglobulin M locus.
Gene targeting in ES cells has propelled the mouse to the forefront of biomedical research. This is despite the fact that its small size limits the scope for many physiological investigations and the low blood volume precludes its use as a source of serum factors. Metabolic and physiological differences also limit the relevance of mice to some human diseases, e.g. cardiomyopathy [27] or cystic fibrosis [12]. Other mammals, notably rabbit and pig, are increasingly seen as valuable alternatives but there is a significant need for efficient methods of precise genetic engineering in these species. Here we describe a generally applicable protocol for targeted genome editing in the rabbit. ZFNs introduced into fertilized oocytes can mediate gene inactivation by DNA repair mutagenesis and also homology-directed targeted sequence replacement. The technique is a simple, efficient and practical means of establishing lines of precisely genetically engineered rabbits.
Like mice, rabbits have a short generation time, produce large numbers of offspring and can be raised under specific pathogen free conditions. They have long been an important research animal, and are an indispensible source of polyclonal and monoclonal antibodies [28], [29]. Spontaneous mutant rabbit strains such as WHHL are widely used in the study of lipid metabolism and atherosclerosis [30]. Pronuclear microinjection of DNA is as facile in rabbits as in mice, and transgenic rabbits have been generated as models for retinal degeneration [31], cardiomyopathy [32], inflammation [33], hyperlipidemia [34] and for the evaluation of human vaccines [35]. Rabbits have also been used for the production of pharmaceutical proteins in milk. However, until now the scope of genetic manipulations has been limited to gain-of-function changes by classical random transgenesis.
Human polyclonal antisera produced by hyperimmunisation of animals with a humanized immune system are potentially an extremely useful new class of therapeutic agents. The inactivation of the IgM locus and loss of endogenous IgM and IgG expression on B cells and in serum that we describe is an essential step in the modification of rabbits to produce human immunoglobulins. The expression of immunoglobulin transgenes has been described for pigs, chicken, and rabbits [36]– [38], and recently the inactivation of immunoglobulin genes in pigs was reported [10], [11]. However, the inactivation of endogenous immunoglobulin genes in combination with addition of human immunoglobulin genes has so far only been achieved in mice and cattle [9], [39]– [44]. Experiments are now underway to achieve this in rabbits.
ZFN-mediated mutagenesis of the IgM locus in rabbit oocytes was efficient, yielding up to 30% mutant animals in the founder generation. Seven of eight founders passed on mutant alleles to their progeny. We also assessed whether ZFN-mediated targeted sequence replacement could be carried out directly in the oocyte without subsequent selection for the desired event, as recently described in mice [23]. Our results show targeted sequence replacement in rabbit at a rate of up to 18% in fetuses. The frequency of ZFN mediated homologous recombination events we observed was therefore at least equal to that described in mouse (1.7–4.5%, Meyer et al. [23]) and clearly higher than the rate of approximately 1 in 500 reported in mouse zygotes without ZFN [45]. These results suggest that the technique should be generally applicable, opening the way for the full repertoire of sophisticated gene replacement and modification techniques developed in mouse ES cells. ZFN-mediated genome editing does not require expression at the targeted locus and our data show that regions of homology as short as 1 kb or less, easily obtained by PCR amplification, are sufficient for efficient targeted sequence replacement. With less than 2 kb of total homology, our IgM gene targeting vector was considerably shorter than those described by Meyer et al. [23], but similar to those used for ZFN-mediated gene targeting in human transformed [16], ES and iPS cells [46].
Rodents, rabbits and other mammals all have particular limitations and strengths for biomedical research and are best regarded as complementary. Parallel and comparative studies performed in more than one species will speed progress in disease research and provide more reliable evaluation of novel diagnostic and therapeutic strategies. Gene targeting in ES cells is established in mouse and now in rat [3], but has so far been elusive in rabbit. Our approach circumvents the need for ES cells or SCNT to carry out precise alterations in any gene, because ZFNs can be designed against any native locus of interest [13], [47]. This achievement removes a major block to the development of genetically altered research models in those species where ES and SCNT technologies are not available. Furthermore, unlike ES cell-based methods, the desired genetic change can be introduced directly into the animal strain of choice, and heterozygous individuals obtained in the first generation. We are confident that this can be applied to other rabbit genes and other mammals, including important livestock species such as pigs. The possible applications are manifold.
All animal experiments were approved by the Government of Upper Bavaria (permit numbers 55.2-1-54-2531-26-04 and 55.2-1-54-2531-9-09) and performed according to the European Union Normative for Care and Use of Experimental Animals. Chemical reagents were obtained from Sigma unless otherwise indicated.
The vector IgME1, used for ZFN-mediated targeted replacement, comprised a 0.758 kb homologous arm extending upstream of IgM exon 1 on the 5′ side, and a 1.035 kb arm extending downstream of IgM exon 1 to the end of exon 3 on the 3′ side, separated by a PGK neo polyA cassette (see Figure 3 and Figure S2). Homologous sequences were obtained by PCR from genomic DNA from a ZIKA rabbit.
Synthetic capped and poly A-tailed mRNAs were transcribed in vitro and purified using mMESSAGE mMACHINE T7 Ultra and MEGAclear Kits (Ambion). The quality and concentration of mRNAs were verified by denaturing gel analysis and spectrophotometry.
Animals used as oocyte donors for the gene inactivation experiments were homozogous Alicia/homozogous Basilea back-crossed for several generations onto the ZIKA background. Alicia (Ali) rabbits carry a natural deletion within the IgH locus [48] and homozygous Basilea (Bas) animals do not express Igκ, due to a non-functional splice acceptor [49]. ZIKA rabbits were used as oocyte donors for the gene replacement experiments. Pronuclear stage fertilized oocytes were obtained by flushing oviducts 21 to 24 hrs from female rabbits superovulated by PMSG (Intergonan; Intervet) and hCG (Ovogest; Intervet) injection, inseminated artificially or by natural cover.
Microinjected oocytes were either cultured to blastocyst stage, or allowed to rest for 1 hr then transferred laparoscopically [50] to foster mothers primed by intramuscular injection of 0.2 ml Receptal (Intervet) 3 to 7 hrs previously. Pregnancies were either terminated at day 15 to examine fetuses, or allowed to proceed to term. Offspring were delivered normally and their genotype was determined at approximately 3 weeks of age.
DNA was prepared from blastocysts by lysis in 50 mM KCl, 1.5 mM MgCl 2, 10 mM Tris, pH 8.0, 0.5% NP40, 0.5% Tween20 and 100 µg proteinase K; or by lysis in 8 µl 50 mM NaOH (10 min 95°C; 2 µl 1 M Tris, pH 7.5 then added for neutralization); and from fetal tissue or ear biopsies of offspring by standard methods. Rabbit Cµ was amplified by PCR using primer pairs E1.1f ( TGG CAG GGA CAC AGG AAA ACA) and E1.1r ( GGC TCA CCG GGA AAG GAC); or E1.2f ( GGC TGC CTG GCG CGG GAC TTT CT) and E1.2r ( CTG TTG CTG TTG CTG TGC TGG ACT TTG) for exon1 and E2.1f ( GGC TGC CTG GCG CGG GAC TTT C) and E2.1r ( CCT GGC CTG GGG ACT GGA CAC TCA CT) or E2.2f ( TGC CAG GCC ACA GGT TTC) and E2.2r ( CTC GGA GGA CAT GGA CAC GTT CTT ATC) for exon 2. Nested PCRs from blastocysts were performed using the two primer pairs specific for exon 1 or 2 consecutively. PCR products containing mutated sequences detected by DNA sequence chromatography were cloned into the TOPO TA cloning kit (Invitrogen) for DNA sequencing of ZFN-induced mutations.
Targeted insertion of the PGK neo gene was detected by PCR across the 5′ junction using primers targF4 ( GCT GTA CAG AGG TGA ACT GGG CTG GTC TTA) and targR4 ( CCG CTG TAA GTC TGC AGA AAT TGA TGA TCT) and across the 3′ junction using primers targF2 ( CGG AGA ACC TGC GTG CAA TCC ATC T) and targR2 ( TGG GCA GAG AGA AGG TGG TGA GCC T). Southern hybridization of 10 µg samples of genomic DNA was performed with a digoxigenin dUTP labeled probe and detected by chemiluminescence using standard methods.
Serum antibody concentrations from animals between 7 and 15 weeks of age were determined by ELISA on streptavidin pre-coated 96 well microtiter plates (Micro Coat Biotechnologie, Germany). Capture was by anti-rabbit-IgM (μ-chain) or anti-rabbit-IgG (Fc) biotin (624085 and 550326, BD Pharmingen); detection used mouse anti-rabbit IgM or IgG horseradish peroxidase (BD Pharmingen).
PBMCs were isolated from whole blood samples using separation media (Lympholyte-Mammal; Cedarlane) according to the manufacturer's instruction and stained and analysed immediately. For single colour flow cytometry, 5×10 5 PBMCs were distributed as 50 µl aliquots in 1.5 ml tubes and kept on ice. Anti-rabbit IgG FITC was obtained from AbD Serotec (Düsseldorf, Germany). Anti-rabbit IgM biotin was from BD Pharmingen (San Diego, USA). FITC labelled streptavidin and anti-mouse IgM phycoerythrin (PE) conjugate were from Invitrogen (Germany). The monoclonal antibody RACT30A, which detects an unidentified rabbit B-cell surface marker [25], was obtained from VMRD (Pullman, USA). The PE-labelled antibody (clone HM47, BD Pharmingen), which binds the highly conserved intracellular domain of human CD79a (component of the B cell receptor) cross-reacts with rabbit CD79a [26]. For intracellular staining, PBMCs were fixed with Cytofix and permeabilised with Perm/Wash (BD Pharmingen) as mentioned in the instructions from the manufacturer. PBMC aliquots were incubated with 50 µl fluorochrome labelled mAbs or streptavidin in PBS for 30 min under rotation at 4°C in the dark. PBMCs were washed twice with ice cold PBS, resuspended in ice cold PBS and subjected to FACS analysis. For all surface staining, propidium iodide at a concentration of 5 µg/ml (BD Pharmingen, USA) was added prior to FACS analysis to discriminate between live and dead cells. 10,000 live PBMCs were analysed per sample. A FACSAria flow cytometer equipped with a computer and FACSDiva software (Becton Dickinson) was used to collect and analyse the data, FACS gates used are shown in each panel of Figure 2.
IgM sequence polymorphisms in different rabbit strains. The DNA sequence of the genomic IgM locus in 14 rabbits was determined; 6 rabbits of the ZIKA strain, 2 of the Alicia strain [48], which carry a mutation in the immunoglobulin heavy chain locus, and 6 of mixed breed (NZW/ZIKA/Alicia) carrying the Basilea [49] loss-of-function mutation at the immunoglobulin kappa light chain locus, which is on a different chromosome. Exon sequences are underlined (Exons: E1–E4). Polymorphisms are shaded in grey (R: A or G; Y: C or T). Five sequence polymorphisms were found in E1, two in E2, four in E3 and one in E4. The binding sites of the ZFNs used for microinjection are highlighted in red.
(TIF)
Click here for additional data file.
DNA sequence of IgME-1 targeted locus. The sequence of the IgME1 gene targeting vector is indicated by highlights; the 5′ and 3′ homologous arms in yellow and the PGK neo cassette in blue. The positions of primers used to amplify PCR fragments across the 5′ junction (targF4 and targR4) and across the 3′ junction (targF2 and targR2) are indicated. ApaI and MscI restriction sites used to confirm the identity of the 5′ PCR product (shown in Figure 3) and the BspHI site used for Southern analysis ( Figure S3) are indicated.
(TIF)
Click here for additional data file.
Southern analysis of fetuses. Samples of genomic DNA from 9 of the 17 fetuses recovered (numbers indicated) were digested with BspHI and HinDIII and hybridized to a probe comprising IgM exon 3, intron 3 and exon 4. Arrows indicate positions of the diagnostic 5.911 kb HindIII-HindIII fragment, derived from the wild type allele, and the 3.943 kb HindIII-BspHI fragment, derived from the targeted allele.
(TIF)
Click here for additional data file.
Microinjection of mRNA coding for EGFP. 1 Experiment.
(DOC)
Click here for additional data file.
Microinjection of mRNAs coding for ZFN SBS 18257/18255. 4 Experiments (separated by double lines).
(DOC)
Click here for additional data file.
We would like to thank Daniela Buntefuß, Marco Friedrich, Janine Gabler, Brigitte Huemer, Sabrina Kettenbach, Christoph Schühlmann, and the Sangamo Production group for excellent technical assistance, Edward Rebar, Beilin Zhang and Jeffrey Miller for assistance with ZFN design, and Nicole Schüler and Frederic Schultz for expert work in cloning the DNA vector for targeted gene replacement. We also thank Fyodor Urnov for editorial input and Susan Abrahamson for helpful comments on the manuscript.
Competing Interests: The authors have read the journal's policy and have the following conflicts. IT, SO, FR, VL, HN and JP are employees of Roche Diagnostics GmbH. Roche Diagnostics is a division of F. Hoffmann-LaRoche Ltd - a company involved in the research and manufacture of medical products including antibodies. BZ, AV, LZ, SJ and PG are current or former employees of Sangamo BioSciences Inc - a biotechnology company focused on the commercialization of zinc finger protein technology.
Funding: The work was funded by F. Hoffmann-LaRoche Ltd. The funders set the overall goal of the project but had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript. The manuscript was approved in its final form by the funders.


Hello, I'm Gabor. As a practising chef, I love gastronomique, food and cooking, but I'm ready for new challenges and for a better living. For this reason, I participated in Codeberry's course to be a web developer. I'm also interested in gardening, DIY and travelling. You can get in touch by clicking on one of the buttons.


* Name of Bottle x_______________________________
* Date of Activiation: 8/17/2018 1:00 PM
* Amount of Water Filled:
Number- 0/32 fluid onces
Percentage- 0%
* Status : Lost? YES | NO
Nearby and Sealed


Index
A B C D E F G H I K L M N O P R S T U W
All Classes All Packages
All Classes All Packages
All Classes All Packages
M
- main - package main
-
The main package.
- main(String[]) - Static method in class main.OnlineMain
-
The main function.
- main(String[]) - Static method in class main.tests.BatchMain
- main(String[]) - Static method in class main.tests.TestConfusionMatrix
- main(String[]) - Static method in class main.tests.TestGraph
- main(String[]) - Static method in class main.tests.TestTrainingModel
- main.tests - package main.tests
-
This sub-package contains tests made to the submodules of the program.
- MDLScore - Class in score
-
A class that extends the LLScore class.
- MDLScore() - Constructor for class score.MDLScore
- metrics - package metrics
-
A package that implements simple metrics such as accuracy score, confusion matrix, F1 score, specificity score and sensitivity score.
- metrics.perclass - package metrics.perclass
-
A package that implements simple metrics such as accuracy score, confusion matrix, F1 score, specificity score and sensitivity score among others, considering only individual classes.
- Model<T> - Interface in datamodel
-
An interface that exposes the services for a model that saves labels of a generic type
- ModelCategory<T> - Class in datamodel.categories
-
A class that implements the Category interface.
- ModelCategory(String, int) - Constructor for class datamodel.categories.ModelCategory
-
The constructor for the ModelCategory.
- ModelClassfication<T> - Class in datamodel.classifications
-
A class that implements the Classification interface.
- ModelClassfication() - Constructor for class datamodel.classifications.ModelClassfication
-
The constructor for the ModelClassification.
- MST - Interface in graph.search
-
An interface that provides the methods to calculate the Minimum/Maximum spanning tree of a graph and return it in the form of an array of integers where the content of the index i corresponds to j, the parent of i
- MultipleScore<T> - Interface in metrics
-
An interface that provides 2 methods: getScore() and getLabels().
All Classes All Packages


Lightweight client
Windows(portable)
Windows(setup)
Mac
Linux
Android
Coming Soon....
iOS
Source Code
Release Note
Old Version


Bengaluru hotel worker robbed, thrown out of moving train near Guntakal
Three persons, who befriend Govind Shetty on the Bengaluru-Nanded Express, rob him of cash and luggage.
by Ramesh SusarlaGovind Shetty, 50, a Bengaluru-based hotel worker, was thrown out of the Bengaluru-Nanded Express at Thimmamcherla village just before the train was to reach Guntakal at 6.30 a.m. on Sunday.
The victim was travelling to Mantralayam from Bengaluru. Three persons, in their early thirties, boarded the train at Hindupur and befriended Mr. Govind.
At Thimmamcherla, they called him to the door, telling him that the train was approaching Guntakal. Then they snatched his purse and travelling bag, and pushed him out of the moving train.
Mr. Shetty suffered minor head injuries, and has been admitted to the Guntakal Government Hospital.
He is out of danger, Guntakal Government Railway Police Inspector G. Gurunath Babu told The Hindu.
The GRP has alerted the Raichur and Wadi stations to look out for the youths. They are also reviewing the CCTV footage that was recorded at the Guntakal station.


The latest urgent product recalls for Waitrose, Cadbury, Asda, Lidl and more
Dozens of products are being recalled
by Briana MillettEvery month the Food Standards Agency (FSA) issues product recalls - and this month has been no different.
So far in November 2019 dozens of products have been recalled, with reasons ranging from allergy fears to the presence of salmonella or glass.
In the article below we've rounded up all of the major product recalls issued by the FSA since November 1.
If you have purchased these products, you are advised not to eat them but to return them for a full refund.
The brands include Cadbury, while many of the items are sold at supermarkets including Asda, Lidl, Waitrose and more.
Here's the full list.
Waitrose soup
Waitrose is recalling its Carrot & Coriander Soup because of undeclared allergens.
The vegetable soup contains barley and celery, two ingredients which are not included on the other product’s label.
Product details:
- Waitrose Carrot & Coriander Soup (600g). Use by: November 27, 2019.
A spokesperson for Waitrose & Partners said: "We are recalling our carrot & coriander soup 600g, use by date 27 November.
"Some of the pots have been filled with the wrong soup (vegetable soup), which contains gluten (barley) and celery that are not declared on the label.
"Any customers with an allergy to gluten or celery should not eat the soup.
"Any customer that has bought the soup please return it to us for a refund. We're very sorry to our customers for this error."
No other Waitrose products are known to be affected.
Spelt & Fruit Cake
Welsh Cottage Cakes is recalling its Spelt & Fruit Cake because it contains wheat which is not mentioned on the label. This means the product is a possible health risk for anyone with an allergy or intolerance to wheat or gluten.
Product details:
- Spelt & Fruit Cake (550g and 360g). Batch codes: 190920, 191004, 191017, 191025, 191108. Use by: 23 November 2019, 7 December 2019, 20 December 2019, 28 December 2019, 11 January 2020.
No other Welsh Cottage Cakes products are known to be affected.
Cadbury
A Cadbury product is this week being recalled by its parent company Mondelez UK over safety concerns.
The issue concerns some packs of Dairy Milk Little Robins (93g) which contain undeclared almonds and are therefore a possible health risk for anyone with an allergy to nuts.
The FSA have revealed the labelling error is due to some of the product having been incorrectly packed with Cadbury Dairy Milk Little Robins Daim Chocolate.
The affected items have the batch codes of CIS3092812 and CIS3092822, and have a best before date of March 31, 2020.
Little Robins products are currently sold at stores including Tesco, Sainsbury's and Asda.
Waitrose desserts
Pots & Co. is recalling part of its range of products, which are currently stocked at Waitrose & Partners.
The manufacturer recently explained that four of its pot varieties may contain pieces of glass, and are therefore unsafe for consumption.
Colombian Chocolate Pot (65g) which has the identifying barcode of<PHONE_NUMBER>920.
Mango & Passionfruit Pot (65g) which has the identifying barcode of<PHONE_NUMBER>906.
Mango & Passionfruit Pot (6x65g) which has the identifying barcode of<PHONE_NUMBER>224.
Summer Berry Pot (65g) which has the identifying barcode of<PHONE_NUMBER>913
The affected products are those with dates codes up to and including November 23, 2019.
Brioche Hot Dog Buns
La Boulangere is recalling its Brioche Hot-Dog Buns because they contain milk and wheat (gluten) which are not mentioned on the label in English. This means the product is a possible health risk for anyone with an allergy or intolerance to milk or milk constituents or an allergy or intolerance to wheat or gluten.
Product details:
- La Boulangere Brioche Hot-Dog buns (270g). Best before November 8, 23 and 30.
No other La Boulangere products are known to be affected.
Harvey Nichols chocolates
Harvey Nichols is recalling its own brand Dark Chocolate Gingers because the product contains pistachio (nuts) which is not mentioned on the label. The product has been incorrectly packed with Dark Chocolate Pistachios.
Product details:
- HARVEY NICHOLS Dark Chocolate Gingers (125g). Batch code: 190916. Best before: August 30, 2020
No other Harvey Nichols products are known to be affected.
If you have bought the above product and have an allergy to nuts, do not eat it. Instead return it to the store from where it was bought for a full refund.
Houmous Selection - Aldi, Asda, Sainsbury's, Lidl and more
Dip maker Zorba Delicacies issued an alert as a "precaution" after an ingredient it uses was found to have the possible presence of salmonella.
Shoppers are being urged to return the food items for a refund following a previous warning from the FSA.
It is feared around 83 products could be contaminated.
Zorba Delicacies Limited supplies hummus to several supermarkets including Aldi, Asda, Lidl, Morrisons, and Sainsbury's, as well as Spar, Safeway, Iceland and John Lewis.
You can read the full recall and list of products here.
For the latest news in and around Bristol, visit and bookmark Bristol Live's homepage.


title = "Blog Post" url = "/blog/post/:slug" layout = "default" description = "This Is the Page containing single blog posts." hidden = "0" [blogPost] slug = "{{ :slug }}" categoryPage = "blog/category" [forumEmbedTopic] embedCode = ":slug" channelSlug = "blog-comments" memberPage = "Account" == page->title = $this['post']->title; } ?> ==


Ajit Pawar back-stabbed Shiv Sena by joining hands with BJP: Sanjay Raut
Talking to reporters, Raut also said the state will never forgive Ajit Pawar for this act of his
by Press Trust of IndiaShiv Sena's Sanjay Raut on Saturday said NCP leader Ajit Pawar had stabbed the Sena in the back by joining hands with the BJP to form the government in Maharashtra.
Talking to reporters, Raut also said the state will never forgive Ajit Pawar for this act of his.
"Ajit Pawar has stabbed the Shiv Sena in the back. Joining hands with the BJP to form the government is betrayal," he said.
"Ajit Pawar's decision does not have the approval of NCP chief Sharad Pawar," Raut said.
He added that Sharad Pawar and Sena chief Uddhav Thackeray will address a joint press conference soon.


Volume controller?
-
anonymous
I guess this is a feature request - or I've missed something - but it would be nice to be able to control iTunes volume from Synergy
Otherwise ... it's great!
-
Greg Hurrell
You can. See the hot keys preferences.
See also this feature request: https://wincent.com/a/support/bugs/show_bug.cgi?id=49
-
anonymous
Quote: You can. See the hot keys preferences.
I looked there ... are you sure you didn't sneak it in there while I was asleep?
Seriously though, I thought I had missed something, as something as good as Synergy was bound to have such functionality built in
Thanks for sorting me out!
Reply
This topic is now closed.


Maitree means “friendliness” in Thai. Maitree is a serif Latin and looped Thai typeface with wide proportions. It is characterized by its bigger-than-usual looped terminal in Thai, and long serifs in Latin, that balance out the whole structure. Maitree offers 6 weights, and its asymmetrically curved terminals are well-suited for both formal and casual usage, especially for works that require an antique and historical manner.
A similarity between some glyphs such as ก ถ ภ ฤ ฦ, ฎ ฏ, บ ป, or ข ช is something to take into consideration because it might lead to confusion when typesetting very short texts. Sizes and positions of Thai vowels and tone marks have been managed carefully, because they are all relevant to readability, legibility, and overall texture.
The Maitree project is led by Cadson Demak, a type foundry in Thailand. To contribute, see github.com/cadsondemak/maitree


Netanyahu to Israel's enemies: Don't try us
In wake of the political developments, PM Netanyahu sent a message to Israel's enemies: "When it comes to security, we stand as one"
by Yoni KempinskiPrime Minister Netanyahu conveyed a message to Israel's enemies as he was speaking to members of the right wing 'bloc' of Knesset parties in wake of the recent political developments.
"As you know very well", Netanyahu said, "there are also threats for us to deal with. Look what happened last week in Gaza, and look at what we did yesterday in Syria".
"I have a message to our enemies", Netanyahu declared, "to all our enemies... those in Tehran, in Damascus, in Beirut and in Gaza. We may be in a transition government, but when it comes to the security of Israel - we stand together, unified as one".
"Don't be mistaken, and don't try us", the Prime Minister concluded.


helooooooooo
Choose Your Favorite Pizza from The Hut!
Home Page
IndexTwo Page
DeltaV GitHub Page
Pizza Hut
The Various Pizzas of Pizza Hut


--- layout: default nav: tutorial ---
This tutorial will show you how to implement "Click To Load" behavior with only a few lines of IntercoolerJS. It builds on the previous Infinite Scroll tutorial.
Here are the steps for implementing inifinite scroll
tbody
so
we can target it for appending.
page
and
value of the next page to load
ic-append-from
,
ic-target
, and
ic-trigger-on
attributes to trigger appending to the table body, and that includes the hidden input using the
ic-include
tag to include the last hidden
input in the table.
Here is a diff between infinite scroll and click-to-load:
https://github.com/LeadDyno/intercooler-tutorial-app/commit/11322f35cda1a7c9fa480f845b43cb28e162f64a


three.js
- instanced circle billboards - colors
Sorry your graphics card + browser does not support hardware instancing


Mark Selected
Delete Selected
Birthday range start:
Birthday range end:
Country:
All
{{country}}
Marked:
All
Marked
Unmarked
ID
Birthday
First Name
Last Name
Country
Net Worth
Marked
{{row.id}}
{{row.birthday | date : 'shortDate'}}
{{row.firstName}}
{{row.lastName}}
{{row.country}}
{{row.netWorth | customCurrency}}


Darlene Holland
About
Portfolio
Contact
Apps
doSomethingProject
Lead Nynja React App
Homemade Summer-Camp App
1
2
3
Connect with Me