PageSourceSearch

https://www.droz.org/store/js/CSL.js?clientCacheVersion=20250927112400

js droz.org collected 2026-09-24 09:37:29 UTC 475,290 bytes, 14,309 lines download raw bytes

1if (!Array.indexOf) {
2	Array.prototype.indexOf = function (obj) {
3		var i, len;
4		for (i = 0, len = this.length; i < len; i += 1) {
5			if (this[i] === obj) {
6				return i;
7			}
8		}
9		return -1;
10	};
11}
12if ("undefined" === typeof CSL_IS_IE) {
13    var CSL_IS_IE;
14};
15var CSL_CHROME = function () {
16    if ("undefined" == typeof DOMParser || CSL_IS_IE) {
17        CSL_IS_IE = true;
18        DOMParser = function() {};
19        DOMParser.prototype.parseFromString = function(str, contentType) {
20            if ("undefined" != typeof ActiveXObject) {
21                var xmldata = new ActiveXObject('MSXML.DomDocument');
22                xmldata.async = false;
23                xmldata.loadXML(str);
24                return xmldata;
25            } else if ("undefined" != typeof XMLHttpRequest) {
26                var xmldata = new XMLHttpRequest;
27                if (!contentType) {
28                    contentType = 'text/xml';
29                }
30                xmldata.open('GET', 'data:' + contentType + ';charset=utf-8,' + encodeURIComponent(str), false);
31                if(xmldata.overrideMimeType) {
32                    xmldata.overrideMimeType(contentType);
33                }
34                xmldata.send(null);
35                return xmldata.responseXML;
36            }
37        };
38        this.hasAttributes = function (node) {
39            var ret;
40            if (node.attributes && node.attributes.length) {
41                ret = true;
42            } else {
43                ret = false;
vendor: 4,237 bytes, lines 44-174
44            }
45            return ret;
46        };
47    } else {
48        this.hasAttributes = function (node) {
49            var ret;
50            if (node.attributes && node.attributes.length) {
51                ret = true;
52            } else {
53                ret = false;
54            }
55            return ret;
56        };
57    }
58    this.importNode = function (doc, srcElement) {
59        if ("undefined" == typeof doc.importNode) {
60            var ret = this._importNode(doc, srcElement, true);
61        } else {
62            var ret = doc.importNode(srcElement, true);
63        }
64        return ret;
65    };
66    this._importNode = function(doc, node, allChildren) {
67        switch (node.nodeType) {
68            case 1:
69                var newNode = doc.createElement(node.nodeName);
70                if (node.attributes && node.attributes.length > 0)
71                    for (var i = 0, il = node.attributes.length; i < il;)
72                        newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName));
73                    if (allChildren && node.childNodes && node.childNodes.length > 0)
74                        for (var i = 0, il = node.childNodes.length; i < il;)
75                            newNode.appendChild(this._importNode(doc, node.childNodes[i++], allChildren));
76                return newNode;
77                break;
78            case 3:
79            case 4:
80            case 8:
81        }
82    };
83    this.parser = new DOMParser();
84    var str = "<docco><institution institution-parts=\"long\" delimiter=\", \" substitute-use-first=\"1\" use-last=\"1\"><institution-part name=\"long\"/></institution></docco>";
85    var inst_doc = this.parser.parseFromString(str, "text/xml");
86    var inst_node = inst_doc.getElementsByTagName("institution");
87    this.institution = inst_node.item(0);
88    var inst_part_node = inst_doc.getElementsByTagName("institution-part");
89    this.institutionpart = inst_part_node.item(0);
90    this.ns = "http://purl.org/net/xbiblio/csl";
91};
92CSL_CHROME.prototype.clean = function (xml) {
93    xml = xml.replace(/<\?[^?]+\?>/g, "");
94    xml = xml.replace(/<![^>]+>/g, "");
95    xml = xml.replace(/^\s+/, "");
96    xml = xml.replace(/\s+$/, "");
97    xml = xml.replace(/^\n*/, "");
98    return xml;
99};
100CSL_CHROME.prototype.getStyleId = function (myxml) {
101    var text = "";
102    var node = myxml.getElementsByTagName("id");
103    if (node && node.length) {
104        node = node.item(0);
105    }
106    if (node) {
107        text = node.textContent;
108    }
109    if (!text) {
110        text = node.innerText;
111    }
112    if (!text) {
113        text = node.innerHTML;
114    }
115    return text;
116};
117CSL_CHROME.prototype.children = function (myxml) {
118    var children, pos, len, ret;
119    if (myxml) {
120        ret = [];
121        children = myxml.childNodes;
122        for (pos = 0, len = children.length; pos < len; pos += 1) {
123            if (children[pos].nodeName != "#text") {
124                ret.push(children[pos]);
125            }
126        }
127        return ret;
128    } else {
129        return [];
130    }
131};
132CSL_CHROME.prototype.nodename = function (myxml) {
133    var ret = myxml.nodeName;
134    return ret;
135};
136CSL_CHROME.prototype.attributes = function (myxml) {
137    var ret, attrs, attr, key, xml, pos, len;
138    ret = new Object();
139    if (myxml && this.hasAttributes(myxml)) {
140        attrs = myxml.attributes;
141        for (pos = 0, len=attrs.length; pos < len; pos += 1) {
142            attr = attrs[pos];
143            ret["@" + attr.name] = attr.value;
144        }
145    }
146    return ret;
147};
148CSL_CHROME.prototype.content = function (myxml) {
149    var ret;
150    if ("undefined" != typeof myxml.textContent) {
151        ret = myxml.textContent;
152    } else if ("undefined" != typeof myxml.innerText) {
153        ret = myxml.innerText;
154    } else {
155        ret = myxml.txt;
156    }
157    return ret;
158};
159CSL_CHROME.prototype.namespace = {
160    "xml":"http://www.w3.org/XML/1998/namespace"
161}
162CSL_CHROME.prototype.numberofnodes = function (myxml) {
163    if (myxml) {
164        return myxml.length;
165    } else {
166        return 0;
167    }
168};
169CSL_CHROME.prototype.getAttributeName = function (attr) {
170    var ret = attr.name;
171    return ret;
172}
173CSL_CHROME.prototype.getAttributeValue = function (myxml,name,namespace) {
174    var ret = false;
175    if (namespace) {
176        name = namespace+":"+name;
177    }
178    if (myxml && this.hasAttributes(myxml)) {
179        if (myxml.getAttribute(name)) {
180            ret = myxml.getAttribute(name);
181        }
182    } else {
183        ret = "";
184    }
185    return ret;
186}
187CSL_CHROME.prototype.getNodeValue = function (myxml,name) {
188    var ret = "";
189    if (name){
190        var vals = myxml.getElementsByTagName(name);
191        if (vals.length > 0) {
192            if ("undefined" != typeof vals[0].textContent) {
193                ret = vals[0].textContent;
194            } else if ("undefined" != typeof vals[0].innerText) {
195                ret = vals[0].innerText;
196            } else {
197                ret = vals[0].text;
198            }
199        }
200    } else {
201        ret = myxml;
202    }
203    if (ret && ret.childNodes && (ret.childNodes.length == 0 || (ret.childNodes.length == 1 && ret.firstChild.nodeName == "#text"))) {
204        if ("undefined" != typeof ret.textContent) {
205            ret = ret.textContent;
206        } else if ("undefined" != typeof ret.innerText) {
207            ret = ret.innerText;
208        } else {
209            ret = ret.text;
210        }
211    }
212    return ret;
213}
214CSL_CHROME.prototype.setAttributeOnNodeIdentifiedByNameAttribute = function (myxml,nodename,partname,attrname,val) {
215    var pos, len, xml, nodes, node;
216    if (attrname.slice(0,1) === '@'){
217        attrname = attrname.slice(1);
218    }
219    nodes = myxml.getElementsByTagName(nodename);
220    for (pos = 0, len = nodes.length; pos < len; pos += 1) {
221        node = nodes[pos];
222        if (node.getAttribute("name") != partname) {
223            continue;
224        }
225        node.setAttribute(attrname, val);
226    }
227}
228CSL_CHROME.prototype.deleteNodeByNameAttribute = function (myxml,val) {
229    var pos, len, node, nodes;
230    nodes = myxml.childNodes;
231    for (pos = 0, len = nodes.length; pos < len; pos += 1) {
232        node = nodes[pos];
233        if (!node || node.nodeType == node.TEXT_NODE) {
234            continue;
235        }
236        if (this.hasAttributes(node) && node.getAttribute("name") == val) {
237            myxml.removeChild(nodes[pos]);
238        }
239    }
240}
241CSL_CHROME.prototype.deleteAttribute = function (myxml,attr) {
242    myxml.removeAttribute(attr);
243}
244CSL_CHROME.prototype.setAttribute = function (myxml,attr,val) {
245    if (!myxml.ownerDocument) {
246        myxml = myxml.firstChild;
247    }
248    if (["function", "unknown"].indexOf(typeof myxml.setAttribute) > -1) {
249        myxml.setAttribute(attr, val);
250    }
251    return false;
252}
253CSL_CHROME.prototype.nodeCopy = function (myxml) {
254    var cloned_node = myxml.cloneNode(true);
255    return cloned_node;
256}
257CSL_CHROME.prototype.getNodesByName = function (myxml,name,nameattrval) {
258    var ret, nodes, node, pos, len;
259    ret = [];
260    nodes = myxml.getElementsByTagName(name);
261    for (pos = 0, len = nodes.length; pos < len; pos += 1) {
262        node = nodes.item(pos);
263        if (nameattrval && !(this.hasAttributes(node) && node.getAttribute("name") == nameattrval)) {
264            continue;
265        }
266        ret.push(node);
267    }
268    return ret;
269}
270CSL_CHROME.prototype.nodeNameIs = function (myxml,name) {
271    if (name == myxml.nodeName) {
272        return true;
273    }
274    return false;
275}
276CSL_CHROME.prototype.makeXml = function (myxml) {
277    var ret, topnode;
278    if (!myxml) {
279        myxml = "<docco><bogus/></docco>";
280    }
281    myxml = myxml.replace(/\s*<\?[^>]*\?>\s*\n*/g, "");
282    var nodetree = this.parser.parseFromString(myxml, "application/xml");
283    return nodetree.firstChild;
284};
285CSL_CHROME.prototype.insertChildNodeAfter = function (parent,node,pos,datexml) {
286    var myxml, xml;
287    myxml = this.importNode(node.ownerDocument, datexml);
288    parent.replaceChild(myxml, node);
289     return parent;
290};
291CSL_CHROME.prototype.insertPublisherAndPlace = function(myxml) {
292    var group = myxml.getElementsByTagName("group");
293    for (var i = 0, ilen = group.length; i < ilen; i += 1) {
294        var node = group.item(i);
295        var skippers = [];
296        for (var j = 0, jlen = node.childNodes.length; j < jlen; j += 1) {
297            if (node.childNodes.item(j).nodeType !== 1) {
298                skippers.push(j);
299            }
300        }
301        if (node.childNodes.length - skippers.length === 2) {
302            var twovars = [];
303            for (var j = 0, jlen = 2; j < jlen; j += 1) {
304                if (skippers.indexOf(j) > -1) {
305                    continue;
306                }
307                var child = node.childNodes.item(j);                    
308                var subskippers = [];
309                for (var k = 0, klen = child.childNodes.length; k < klen; k += 1) {
310                    if (child.childNodes.item(k).nodeType !== 1) {
311                        subskippers.push(k);
312                    }
313                }
314                if (child.childNodes.length - subskippers.length === 0) {
315                    twovars.push(child.getAttribute('variable'));
316                    if (child.getAttribute('suffix')
317                        || child.getAttribute('prefix')) {
318                        twovars = [];
319                        break;
320                    }
321                }
322            }
323            if (twovars.indexOf("publisher") > -1 && twovars.indexOf("publisher-place") > -1) {
324                node.setAttribute('has-publisher-and-publisher-place', true);
325            }
326        }
327    }
328};
329CSL_CHROME.prototype.addMissingNameNodes = function(myxml) {
330    var nameslist = myxml.getElementsByTagName("names");
331    for (var i = 0, ilen = nameslist.length; i < ilen; i += 1) {
332        var names = nameslist.item(i);
333        var namelist = names.getElementsByTagName("name");
334        if ((!namelist || namelist.length === 0)
335            && names.parentNode.tagName.toLowerCase() !== "substitute") {
336            var doc = names.ownerDocument;
337            var name = doc.createElement("name");
338            names.appendChild(name);
339        }
340    }
341};
342CSL_CHROME.prototype.addInstitutionNodes = function(myxml) {
343    var names, thenames, institution, theinstitution, name, thename, xml, pos, len;
344    names = myxml.getElementsByTagName("names");
345    for (pos = 0, len = names.length; pos < len; pos += 1) {
346        thenames = names.item(pos);
347        name = thenames.getElementsByTagName("name");
348        if (name.length == 0) {
349            continue;
350        }
351        institution = thenames.getElementsByTagName("institution");
352        if (institution.length == 0) {
353            theinstitution = this.importNode(myxml.ownerDocument, this.institution);
354            theinstitutionpart = theinstitution.getElementsByTagName("institution-part").item(0);
355            thename = name.item(0);
356            thenames.insertBefore(theinstitution, thename.nextSibling);
357            for (var j = 0, jlen = CSL.INSTITUTION_KEYS.length; j < jlen; j += 1) {
358                var attrname = CSL.INSTITUTION_KEYS[j];
359                var attrval = thename.getAttribute(attrname);
360                if (attrval) {
361                    theinstitutionpart.setAttribute(attrname, attrval);
362                }
363            }
364            var nameparts = thename.getElementsByTagName("name-part");
365            for (var j = 0, jlen = nameparts.length; j < jlen; j += 1) {
366                if ('family' === nameparts[j].getAttribute('name')) {
367                    for (var k = 0, klen = CSL.INSTITUTION_KEYS.length; k < klen; k += 1) {
368                        var attrname = CSL.INSTITUTION_KEYS[k];
369                        var attrval = nameparts[j].getAttribute(attrname);
370                        if (attrval) {
371                            theinstitutionpart.setAttribute(attrname, attrval);
372                        }
373                    }
374                }
375            }
376        }
377    }
378};
379CSL_CHROME.prototype.flagDateMacros = function(myxml) {
380    var pos, len, thenode, thedate;
381    nodes = myxml.getElementsByTagName("macro");
382    for (pos = 0, len = nodes.length; pos < len; pos += 1) {
383        thenode = nodes.item(pos);
384        thedate = thenode.getElementsByTagName("date");
385        if (thedate.length) {
386            thenode.setAttribute('macro-has-date', 'true');
387        }
388    }
389};
390var CSL = {
391	PROCESSOR_VERSION: "1.0.550",
392	CONDITION_LEVEL_TOP: 1,
393	CONDITION_LEVEL_BOTTOM: 2,
394	PLAIN_HYPHEN_REGEX: /(?:[^\\]-|\u2013)/,
395	LOCATOR_LABELS_REGEXP: new RegExp("^((art|ch|Ch|subch|col|fig|l|n|no|op|p|pp|para|subpara|pt|r|sec|subsec|Sec|sv|sch|tit|vrs|vol)\\.)\\s+(.*)"),
396	STATUTE_SUBDIV_GROUPED_REGEX: /((?:^| )(?:art|ch|Ch|subch|p|pp|para|subpara|pt|r|sec|subsec|Sec|sch|tit)\.)/g,
397	STATUTE_SUBDIV_PLAIN_REGEX: /(?:(?:^| )(?:art|ch|Ch|subch|p|pp|para|subpara|pt|r|sec|subsec|Sec|sch|tit)\.)/,
398	STATUTE_SUBDIV_STRINGS: {
399		"art.": "article",
400		"bk.": "book",
401		"ch.": "chapter",
402		"Ch.": "Chapter",
403		"subch.": "subchapter",
404		"p.": "page",
405		"pp.": "page",
406		"para.": "paragraph",
407		"subpara.": "subparagraph",
408		"pt.": "part",
409		"r.": "rule",
410		"sec.": "section",
411		"subsec.": "subsection",
412		"Sec.": "Section",
413		"sch.": "schedule",
414		"tit.": "title",
415		"col.": "column",
416		"fig.": "figure",
417		"fol.": "folio",
418		"l.": "line",
419		"n.": "note",
420		"no.": "issue",
421		"op.": "opus",
422		"sv.": "sub-verbo",
423		"vrs.": "verse",
424		"vol.": "volume"
425	},
426	STATUTE_SUBDIV_STRINGS_REVERSE: {
427		"article": "art.",
428		"book": "bk.",
429		"chapter": "ch.",
430		"Chapter": "Ch.",
431		"subchapter": "subch.",
432		"page": "p.",
433		"paragraph": "para.",
434		"subparagraph": "subpara.",
435		"part": "pt.",
436		"rule": "r.",
437		"section": "sec.",
438		"subsection": "subsec.",
439		"Section": "Sec.",
440		"schedule": "sch.",
441		"title": "tit.",
442		"column": "col.",
443		"figure": "fig.",
444		"folio": "fol.",
445		"line": "l.",
446		"note": "n.",
447		"issue": "no.",
448		"opus": "op.",
449		"sub-verbo": "sv.",
450		"sub verbo": "sv.",
451		"verse": "vrs.",
452		"volume": "vol."
453	},
454	LOCATOR_LABELS_MAP: {
455		"art": "article",
456		"bk": "book",
457		"ch": "chapter",
458		"Ch": "Chapter",
459		"subch": "subchapter",
460		"col": "column",
461		"fig": "figure",
462		"fol": "folio",
463		"l": "line",
464		"n": "note",
465		"no": "issue",
466		"op": "opus",
467		"p": "page",
468		"pp": "page",
469		"para": "paragraph",
470		"subpara": "subparagraph",
471		"pt": "part",
472		"r": "rule",
473		"sec": "section",
474		"subsec": "subsection",
475		"Sec": "Section",
476		"sv": "sub-verbo",
477		"sch": "schedule",
478		"tit": "title",
479		"vrs": "verse",
480		"vol": "volume"
481	},
482	NestedBraces: [
483		["(", "["],
484		[")", "]"]
485	],
486	checkNestedBraceOpen: new RegExp(".*\\("),
487	checkNestedBraceClose: new RegExp(".*\\)"),
488	LangPrefsMap: {
489		"title":"titles",
490		"title-short":"titles",
491		"container-title":"journals",
492		"collection-title":"journals",
493		"publisher":"publishers",
494		"authority":"publishers",
495		"publisher-place": "places",
496		"event-place": "places",
497		"number": "number",
498		"edition":"number",
499		"issue":"number",
500		"volume":"number"
501	},
502	AbbreviationSegments: function () {
503		this["container-title"] = {};
504		this["collection-title"] = {};
505		this["institution-entire"] = {};
506		this["institution-part"] = {};
507		this.nickname = {};
508		this.number = {};
509		this.title = {};
510		this.place = {};
511		this.hereinafter = {};
512		this.classic = {};
513		this["container-phrase"] = {};
514		this["title-phrase"] = {};
515	},
516	GENDERS: ["masculine", "feminine"],
517	ERROR_NO_RENDERED_FORM: 1,
518	PREVIEW: "Just for laughs.",
519	ASSUME_ALL_ITEMS_REGISTERED: 2,
520	START: 0,
521	END: 1,
522	SINGLETON: 2,
523	SEEN: 6,
524	SUCCESSOR: 3,
525	SUCCESSOR_OF_SUCCESSOR: 4,
526	SUPPRESS: 5,
527	SINGULAR: 0,
528	PLURAL: 1,
529	LITERAL: true,
530	BEFORE: 1,
531	AFTER: 2,
532	DESCENDING: 1,
533	ASCENDING: 2,
534	ONLY_FIRST: 1,
535	ALWAYS: 2,
536	ONLY_LAST: 3,
537	FINISH: 1,
538	POSITION_FIRST: 0,
539	POSITION_SUBSEQUENT: 1,
540	POSITION_IBID: 2,
541	POSITION_IBID_WITH_LOCATOR: 3,
542	MARK_TRAILING_NAMES: true,
543	POSITION_TEST_VARS: ["position", "first-reference-note-number", "near-note"],
544	AREAS: ["citation", "citation_sort", "bibliography", "bibliography_sort"],
545	MULTI_FIELDS: ["event", "publisher", "publisher-place", "event-place", "title", "container-title", "collection-title", "authority","edition","genre","title-short","medium","jurisdiction","archive","archive-place"],
546	CITE_FIELDS: ["first-reference-note-number", "locator", "locator-revision"],
547	MINIMAL_NAME_FIELDS: ["literal", "family"],
548	SWAPPING_PUNCTUATION: [".", "!", "?", ":", ","],
549	TERMINAL_PUNCTUATION: [":", ".", ";", "!", "?", " "],
550	NONE: 0,
551	NUMERIC: 1,
552	POSITION: 2,
553	COLLAPSE_VALUES: ["citation-number", "year", "year-suffix"],
554	DATE_PARTS: ["year", "month", "day"],
555	DATE_PARTS_ALL: ["year", "month", "day", "season"],
556	DATE_PARTS_INTERNAL: ["year", "month", "day", "year_end", "month_end", "day_end"],
557	NAME_PARTS: ["family", "given", "dropping-particle", "non-dropping-particle", "suffix", "literal"],
558	DECORABLE_NAME_PARTS: ["given", "family", "suffix"],
559	DISAMBIGUATE_OPTIONS: [
560		"disambiguate-add-names",
561		"disambiguate-add-givenname",
562		"disambiguate-add-year-suffix"
563	],
564	GIVENNAME_DISAMBIGUATION_RULES: [
565		"all-names",
566		"all-names-with-initials",
567		"primary-name",
568		"primary-name-with-initials",
569		"by-cite"
570	],
571	NAME_ATTRIBUTES: [
572		"and",
573		"delimiter-precedes-last",
574		"delimiter-precedes-et-al",
575		"initialize-with",
576		"initialize",
577		"name-as-sort-order",
578		"sort-separator",
579		"et-al-min",
580		"et-al-use-first",
581		"et-al-subsequent-min",
582		"et-al-subsequent-use-first",
583		"form",
584		"prefix",
585		"suffix",
586		"delimiter"
587	],
588	PARALLEL_MATCH_VARS: ["container-title"],
589	PARALLEL_TYPES: ["bill","gazette","regulation","legislation","legal_case","treaty","article-magazine","article-journal"],
590	PARALLEL_COLLAPSING_MID_VARSET: ["volume", "issue", "container-title", "section", "collection-number"],
591	LOOSE: 0,
592	STRICT: 1,
593	TOLERANT: 2,
594	PREFIX_PUNCTUATION: /[.;:]\s*$/,
595	SUFFIX_PUNCTUATION: /^\s*[.;:,\(\)]/,
596	NUMBER_REGEXP: /(?:^\d+|\d+$)/,
597	NAME_INITIAL_REGEXP: /^([A-Z\u0590-\u05ff\u0080-\u017f\u0400-\u042f\u0600-\u06ff\u0370\u0372\u0376\u0386\u0388-\u03ab\u03e2\u03e4\u03e6\u03e8\u03ea\u03ec\u03ee\u03f4\u03f7\u03fd-\u03ff])([a-zA-Z\u0080-\u017f\u0400-\u052f\u0600-\u06ff\u0370-\u03ff\u1f00-\u1fff]*|)/,
598	ROMANESQUE_REGEXP: /[-0-9a-zA-Z\u0590-\u05d4\u05d6-\u05ff\u0080-\u017f\u0400-\u052f\u0370-\u03ff\u1f00-\u1fff\u0600-\u06ff\u200c\u200d\u200e\u0218\u0219\u021a\u021b\u202a-\u202e]/,
599	ROMANESQUE_NOT_REGEXP: /[^a-zA-Z\u0590-\u05ff\u0080-\u017f\u0400-\u052f\u0370-\u03ff\u1f00-\u1fff\u0600-\u06ff\u200c\u200d\u200e\u0218\u0219\u021a\u021b\u202a-\u202e]/g,
600	STARTSWITH_ROMANESQUE_REGEXP: /^[&a-zA-Z\u0590-\u05d4\u05d6-\u05ff\u0080-\u017f\u0400-\u052f\u0370-\u03ff\u1f00-\u1fff\u0600-\u06ff\u200c\u200d\u200e\u0218\u0219\u021a\u021b\u202a-\u202e]/,
601	ENDSWITH_ROMANESQUE_REGEXP: /[.;:&a-zA-Z\u0590-\u05d4\u05d6-\u05ff\u0080-\u017f\u0400-\u052f\u0370-\u03ff\u1f00-\u1fff\u0600-\u06ff\u200c\u200d\u200e\u0218\u0219\u021a\u021b\u202a-\u202e]$/,
602	ALL_ROMANESQUE_REGEXP: /^[a-zA-Z\u0590-\u05ff\u0080-\u017f\u0400-\u052f\u0370-\u03ff\u1f00-\u1fff\u0600-\u06ff\u200c\u200d\u200e\u0218\u0219\u021a\u021b\u202a-\u202e]+$/,
603	VIETNAMESE_SPECIALS: /[\u00c0-\u00c3\u00c8-\u00ca\u00cc\u00cd\u00d2-\u00d5\u00d9\u00da\u00dd\u00e0-\u00e3\u00e8-\u00ea\u00ec\u00ed\u00f2-\u00f5\u00f9\u00fa\u00fd\u0101\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01a0\u01a1\u01af\u01b0\u1ea0-\u1ef9]/,
604	VIETNAMESE_NAMES: /^(?:(?:[.AaBbCcDdEeGgHhIiKkLlMmNnOoPpQqRrSsTtUuVvXxYy \u00c0-\u00c3\u00c8-\u00ca\u00cc\u00cd\u00d2-\u00d5\u00d9\u00da\u00dd\u00e0-\u00e3\u00e8-\u00ea\u00ec\u00ed\u00f2-\u00f5\u00f9\u00fa\u00fd\u0101\u0103\u0110\u0111\u0128\u0129\u
6040168\u0169\u01a0\u01a1\u01af\u01b0\u1ea0-\u1ef9]{2,6})(\s+|$))+$/,
605	NOTE_FIELDS_REGEXP: /\{:(?:[\-_a-z]+|[A-Z]+):[^\}]+\}/g,
606	NOTE_FIELD_REGEXP: /\{:([\-_a-z]+|[A-Z]+):\s*([^\}]+)\}/,
607	DISPLAY_CLASSES: ["block", "left-margin", "right-inline", "indent"],
608	NAME_VARIABLES: [
609		"author",
610		"editor",
611		"translator",
612		"contributor",
613		"collection-editor",
614		"composer",
615		"container-author",
616		"director",
617		"editorial-director",
618		"interviewer",
619		"original-author",
620		"recipient"
621	],
622	NUMERIC_VARIABLES: [
623		"call-number",
624		"chapter-number",
625		"collection-number",
626		"edition",
627		"page",
628		"issue",
629		"locator",
630		"number",
631		"number-of-pages",
632		"number-of-volumes",
633		"volume",
634		"citation-number"
635	],
636	DATE_VARIABLES: [
637		"locator-date",
638		"issued",
639		"event-date",
640		"accessed",
641		"container",
642		"original-date",
643		"publication-date",
644		"original-date",
645		"available-date",
646		"submitted"
647	],
648	TAG_ESCAPE: function (str) {
649		var mx, lst, len, pos, m, buf1, buf2, idx, ret, myret;
650		mx = str.match(/((?:\"|\')|(?:(?:<span\s+class=\"no(?:case|decor)\">).*?(?:<\/span>|<\/?(?:i|sc|b)>)))/g);
651		lst = str.split(/(?:(?:\"|\')|(?:(?:<span\s+class=\"no(?:case|decor)\">).*?(?:<\/span>|<\/?(?:i|sc|b)>)))/g);
652		myret = [lst[0]];
653		for (pos = 1, len = lst.length; pos < len; pos += 1) {
654			myret.push(mx[pos - 1]);
655			myret.push(lst[pos]);
656		}
657		lst = myret.slice();
658		return lst;
659	},
660	TAG_USEALL: function (str) {
661		var ret, open, close, end;
662		ret = [""];
663		open = str.indexOf("<");
664		close = str.indexOf(">");
665		while (open > -1 && close > -1) {
666			if (open > close) {
667				end = open + 1;
668			} else {
669				end = close + 1;
670			}
671			if (open < close && str.slice(open + 1, close).indexOf("<") === -1) {
672				ret[ret.length - 1] += str.slice(0, open);
673				ret.push(str.slice(open, close + 1));
674				ret.push("");
675				str = str.slice(end);
676			} else {
677				ret[ret.length - 1] += str.slice(0, close + 1);
678				str = str.slice(end);
679			}
680			open = str.indexOf("<");
681			close = str.indexOf(">");
682		}
683		ret[ret.length - 1] += str;
684		return ret;
685	},
686	SKIP_WORDS: ["about","above","across","afore","after","against","along","alongside","amid","amidst","among","amongst","anenst","apropos","apud","around","as","aside","astride","at","athwart","atop","barring","before","behind","below","beneath","beside","besides","between","beyond","but","by","circa","despite","down","during","except","for","forenenst","from","given","in","inside","into","lest","like","modulo","near","next","notwithstanding","of","off","on","onto","out","over","per","plus","pro","qua","sans","since","than","through"," thru","throughout","thruout","till","to","toward","towards","under","underneath","until","unto","up","upon","versus","vs.","v.","vs","v","via","vis-à-vis","with","within","without","according to","ahead of","apart from","as for","as of","as per","as regards","aside from","back to","because of","close to","due to","except for","far from","inside of","instead of","near to","next to","on to","out from","out of","outside of","prior to","pursuant to","rather than","regardless of","such as","that of","up to","where as","or", "yet", "so", "for", "and", "nor", "a", "an", "the", "de", "d'", "von", "van", "c", "et", "ca"],
687	FORMAT_KEY_SEQUENCE: [
688		"@strip-periods",
689		"@font-style",
690		"@font-variant",
691		"@font-weight",
692		"@text-decoration",
693		"@vertical-align",
694		"@quotes"
695	],
696	INSTITUTION_KEYS: [
697		"font-style",
698		"font-variant",
699		"font-weight",
700		"text-decoration",
701		"text-case"
702	],
703	SUFFIX_CHARS: "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z",
704	ROMAN_NUMERALS: [
705		[ "", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix" ],
706		[ "", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc" ],
707		[ "", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm" ],
708		[ "", "m", "mm", "mmm", "mmmm", "mmmmm"]
709	],
710	CREATORS: [
711		"author",
712		"editor",
713		"contributor",
714		"translator",
715		"recipient",
716		"interviewer",
717		"composer",
718		"original-author",
719		"container-author",
720		"collection-editor"
721	],
722	LANGS: {
723		"af-ZA":"Afrikaans",
724		"ar-AR":"Arabic",
725		"bg-BG":"Bulgarian",
726		"ca-AD":"Catalan",
727		"cs-CZ":"Czech",
728		"da-DK":"Danish",
729		"de-AT":"Austrian",
730		"de-CH":"German (CH)",
731		"de-DE":"German (DE)",
732		"el-GR":"Greek",
733		"en-GB":"English (GB)",
734		"en-US":"English (US)",
735		"es-ES":"Spanish",
736		"et-EE":"Estonian",
737		"eu":"European",
738		"fa-IR":"Persian",
739		"fi-FI":"Finnish",
740		"fr-CA":"French (CA)",
741		"fr-FR":"French (FR)",
742		"he-IL":"Hebrew",
743		"hr-HR":"Croatian",
744		"hu-HU":"Hungarian",
745		"is-IS":"Icelandic",
746		"it-IT":"Italian",
747		"ja-JP":"Japanese",
748		"km-KH":"Khmer",
749		"ko-KR":"Korean",
750		"lt-LT":"Lithuanian",
751		"lv-LV":"Latvian",
752		"mn-MN":"Mongolian",
753		"nb-NO":"Norwegian (Bokmål)",
754		"nl-NL":"Dutch",
755		"nn-NO":"Norwegian (Nynorsk)",
756		"pl-PL":"Polish",
757		"pt-BR":"Portuguese (BR)",
758		"pt-PT":"Portuguese (PT)",
759		"ro-RO":"Romanian",
760		"ru-RU":"Russian",
761		"sk-SK":"Slovak",
762		"sl-SI":"Slovenian",
763		"sr-RS":"Serbian",
764		"sv-SE":"Swedish",
765		"th-TH":"Thai",
766		"tr-TR":"Turkish",
767		"uk-UA":"Ukranian",
768		"vi-VN":"Vietnamese",
769		"zh-CN":"Chinese (CN)",
770		"zh-TW":"Chinese (TW)"
771	},
772	LANG_BASES: {
773		af: "af_ZA",
774		ar: "ar_AR",
775		bg: "bg_BG",
776		ca: "ca_AD",
777		cs: "cs_CZ",
778		da: "da_DK",
779		de: "de_DE",
780		el: "el_GR",
781		en: "en_US",
782		es: "es_ES",
783		et: "et_EE",
784		eu: "eu",
785		fa: "fa_IR",
786		fi: "fi_FI",
787		fr: "fr_FR",
788		he: "he_IL",
789		hu: "hu_HU",
790		is: "is_IS",
791		it: "it_IT",
792		ja: "ja_JP",
793		km: "km_KH",
794		ko: "ko_KR",
795		lt: "lt_LT",
796		mn: "mn_MN",
797		nb: "nb_NO",
798		nl: "nl_NL",
799		nn: "nn-NO",
800		pl: "pl_PL",
801		pt: "pt_PT",
802		ro: "ro_RO",
803		ru: "ru_RU",
804		sk: "sk_SK",
805		sl: "sl_SI",
806		sr: "sr_RS",
807		sv: "sv_SE",
808		th: "th_TH",
809		tr: "tr_TR",
810		uk: "uk_UA",
811		vi: "vi_VN",
812		zh: "zh_CN"
813	},
814	SUPERSCRIPTS: {
815		"\u00AA": "\u0061",
816		"\u00B2": "\u0032",
817		"\u00B3": "\u0033",
818		"\u00B9": "\u0031",
819		"\u00BA": "\u006F",
820		"\u02B0": "\u0068",
821		"\u02B1": "\u0266",
822		"\u02B2": "\u006A",
823		"\u02B3": "\u0072",
824		"\u02B4": "\u0279",
825		"\u02B5": "\u027B",
826		"\u02B6": "\u0281",
827		"\u02B7": "\u0077",
828		"\u02B8": "\u0079",
829		"\u02E0": "\u0263",
830		"\u02E1": "\u006C",
831		"\u02E2": "\u0073",
832		"\u02E3": "\u0078",
833		"\u02E4": "\u0295",
834		"\u1D2C": "\u0041",
835		"\u1D2D": "\u00C6",
836		"\u1D2E": "\u0042",
837		"\u1D30": "\u0044",
838		"\u1D31": "\u0045",
839		"\u1D32": "\u018E",
840		"\u1D33": "\u0047",
841		"\u1D34": "\u0048",
842		"\u1D35": "\u0049",
843		"\u1D36": "\u004A",
844		"\u1D37": "\u004B",
845		"\u1D38": "\u004C",
846		"\u1D39": "\u004D",
847		"\u1D3A": "\u004E",
848		"\u1D3C": "\u004F",
849		"\u1D3D": "\u0222",
850		"\u1D3E": "\u0050",
851		"\u1D3F": "\u0052",
852		"\u1D40": "\u0054",
853		"\u1D41": "\u0055",
854		"\u1D42": "\u0057",
855		"\u1D43": "\u0061",
856		"\u1D44": "\u0250",
857		"\u1D45": "\u0251",
858		"\u1D46": "\u1D02",
859		"\u1D47": "\u0062",
860		"\u1D48": "\u0064",
861		"\u1D49": "\u0065",
862		"\u1D4A": "\u0259",
863		"\u1D4B": "\u025B",
864		"\u1D4C": "\u025C",
865		"\u1D4D": "\u0067",
866		"\u1D4F": "\u006B",
867		"\u1D50": "\u006D",
868		"\u1D51": "\u014B",
869		"\u1D52": "\u006F",
870		"\u1D53": "\u0254",
871		"\u1D54": "\u1D16",
872		"\u1D55": "\u1D17",
873		"\u1D56": "\u0070",
874		"\u1D57": "\u0074",
875		"\u1D58": "\u0075",
876		"\u1D59": "\u1D1D",
877		"\u1D5A": "\u026F",
878		"\u1D5B": "\u0076",
879		"\u1D5C": "\u1D25",
880		"\u1D5D": "\u03B2",
881		"\u1D5E": "\u03B3",
882		"\u1D5F": "\u03B4",
883		"\u1D60": "\u03C6",
884		"\u1D61": "\u03C7",
885		"\u2070": "\u0030",
886		"\u2071": "\u0069",
887		"\u2074": "\u0034",
888		"\u2075": "\u0035",
889		"\u2076": "\u0036",
890		"\u2077": "\u0037",
891		"\u2078": "\u0038",
892		"\u2079": "\u0039",
893		"\u207A": "\u002B",
894		"\u207B": "\u2212",
895		"\u207C": "\u003D",
896		"\u207D": "\u0028",
897		"\u207E": "\u0029",
898		"\u207F": "\u006E",
899		"\u2120": "\u0053\u004D",
900		"\u2122": "\u0054\u004D",
901		"\u3192": "\u4E00",
902		"\u3193": "\u4E8C",
903		"\u3194": "\u4E09",
904		"\u3195": "\u56DB",
905		"\u3196": "\u4E0A",
906		"\u3197": "\u4E2D",
907		"\u3198": "\u4E0B",
908		"\u3199": "\u7532",
909		"\u319A": "\u4E59",
910		"\u319B": "\u4E19",
911		"\u319C": "\u4E01",
912		"\u319D": "\u5929",
913		"\u319E": "\u5730",
914		"\u319F": "\u4EBA",
915		"\u02C0": "\u0294",
916		"\u02C1": "\u0295",
917		"\u06E5": "\u0648",
918		"\u06E6": "\u064A"
919	},
920	SUPERSCRIPTS_REGEXP: new RegExp("[\u00AA\u00B2\u00B3\u00B9\u00BA\u02B0\u02B1\u02B2\u02B3\u02B4\u02B5\u02B6\u02B7\u02B8\u02E0\u02E1\u02E2\u02E3\u02E4\u1D2C\u1D2D\u1D2E\u1D30\u1D31\u1D32\u1D33\u1D34\u1D35\u1D36\u1D37\u1D38\u1D39\u1D3A\u1D3C\u1D3D\u1D3E\u1D3F\u1D40\u1D41\u1D42\u1D43\u1D44\u1D45\u1D46\u1D47\u1D48\u1D49\u1D4A\u1D4B\u1D4C\u1D4D\u1D4F\u1D50\u1D51\u1D52\u1D53\u1D54\u1D55\u1D56\u1D57\u1D58\u1D59\u1D5A\u1D5B\u1D5C\u1D5D\u1D5E\u1D5F\u1D60\u1D61\u2070\u2071\u2074\u2075\u2076\u2077\u2078\u2079\u207A\u207B\u207C\u207D\u207E\u207F\u2120\u2122\u3192\u3193\u3194\u3195\u3196\u3197\u3198\u3199\u319A\u319B\u319C\u319D\u319E\u319F\u02C0\u02C1\u06E5\u06E6]", "g"),
921	locale: {},
922	locale_opts: {},
923	locale_dates: {}
924};
925if (typeof require !== "undefined" && typeof module !== 'undefined' && "exports" in module) {
926	var CSL_IS_NODEJS = true;
927	var CSL_NODEJS = require("./csl_nodejs_jsdom").CSL_NODEJS_JSDOM;
928	exports.CSL = CSL;
929}
930CSL.TERMINAL_PUNCTUATION_REGEXP = new RegExp("^([" + CSL.TERMINAL_PUNCTUATION.slice(0, -1).join("") + "])(.*)");
931CSL.CLOSURES = new RegExp(".*[\\]\\)]");
932if ("object" === typeof console && "function" === typeof console.log) {
933	CSL.debug = function (str) {
934		console.log("CSL: " + str);
935	};
936	CSL.error = function (str) {
937		console.log("CSL error: " + str);
938	};
939} else {
940	CSL.debug = function () {};
941	CSL.error = function (str) {
942		throw "CSL error: " + str;
943	};
944}
945var XML_PARSING;
946if ("undefined" !== typeof CSL_IS_NODEJS) {
947	XML_PARSING = CSL_NODEJS;
948} else if ("undefined" !== typeof CSL_E4X) {
949	XML_PARSING = CSL_E4X;
950} else if ("undefined" !== typeof CSL_JSON) {
951	XML_PARSING = CSL_JSON;
952} else {
953	XML_PARSING = CSL_CHROME;
954}
955CSL.System = {};
956CSL.System.Xml = {
957	"Parsing": XML_PARSING
958};
959CSL.getSortCompare = function (default_locale) {
960	if (CSL.stringCompare) {
961		return CSL.stringCompare;
962	}
963	var strcmp;
964	var strcmp_opts = {
965		sensitivity:"base",
966		ignorePunctuation:true,
967		numeric:true
968	 }
969	if (!default_locale) {
970		default_locale = "en-US";
971	}
972	strcmp = function (a, b) {
973		return a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase(),default_locale,strcmp_opts);
974	};
975	var stripPunct = function (str) {
976		return str.replace(/^[\[\]\'\"]*/g, "");
977	}
978	var getBracketPreSort = function () {
979		if (!strcmp("[x","x")) {
980			return false;
981		} else {
982			return function (a, b) {
983				return strcmp(stripPunct(a), stripPunct(b));
984			}
985		}
986	}
987	var bracketPreSort = getBracketPreSort();
988	var sortCompare = function (a, b) {
989		if (bracketPreSort) {
990			return bracketPreSort(a, b);
991		} else {
992			return strcmp(a, b);
993		}
994	}
995	return sortCompare;
996};
997CSL.ambigConfigDiff = function(a, b) {
998	var ret, pos, len, ppos, llen;
999	if (a.names.length !== b.names.length) {
1000		return 1;
1001	} else {
1002		for (pos = 0, len = a.names.length; pos < len; pos += 1) {
1003			if (a.names[pos] !== b.names[pos]) {
1004				return 1;
1005			} else {
1006				for (ppos = 0, llen = a.givens[pos]; ppos < llen; ppos += 1) {
1007					if (a.givens[pos][ppos] !== b.givens[pos][ppos]) {
1008						return 1;
1009					}
1010				}
1011			}
1012		}
1013	}
1014	if (a.disambiguate != b.disambiguate) {
1015		return 1;
1016	}
1017	if (a.year_suffix !== b.year_suffix) {
1018		return 1;
1019	}
1020	return 0;
1021};
1022CSL.cloneAmbigConfig = function (config, oldconfig, tainters) {
1023	var i, ilen, j, jlen, k, klen, param;
1024	var ret = {};
1025	ret.names = [];
1026	ret.givens = [];
1027	ret.year_suffix = false;
1028	ret.disambiguate = false;
1029	for (i = 0, ilen = config.names.length; i < ilen; i += 1) {
1030		param = config.names[i];
1031		ret.names[i] = param;
1032	}
1033	for (i  = 0, ilen = config.givens.length; i < ilen; i += 1) {
1034		param = [];
1035		for (j = 0, jlen = config.givens[i].length; j < jlen; j += 1) {
1036			param.push(config.givens[i][j]);
1037		}
1038		ret.givens.push(param);
1039	}
1040	if (oldconfig) {
1041		ret.year_suffix = oldconfig.year_suffix;
1042		ret.disambiguate = oldconfig.disambiguate;
1043	} else {
1044		ret.year_suffix = config.year_suffix;
1045		ret.disambiguate = config.disambiguate;
1046	}
1047	return ret;
1048};
1049CSL.getAmbigConfig = function () {
1050	var config, ret;
1051	config = this.tmp.disambig_request;
1052	if (!config) {
1053		config = this.tmp.disambig_settings;
1054	}
1055	ret = CSL.cloneAmbigConfig(config);
1056	return ret;
1057};
1058CSL.getMaxVals = function () {
1059	return this.tmp.names_max.mystack.slice();
1060};
1061CSL.getMinVal = function () {
1062	return this.tmp["et-al-min"];
1063};
1064CSL.tokenExec = function (token, Item, item) {
1065	var next, maybenext, exec, pos, len, debug;
1066	debug = false;
1067	next = token.next;
1068	maybenext = false;
1069	var record = function (result) {
1070		if (result) {
1071			this.tmp.jump.replace("succeed");
1072			return token.succeed;
1073		} else {
1074			this.tmp.jump.replace("fail");
1075			return token.fail;
1076		}
1077	}
1078	if (token.test) {
1079		next = record.call(this,token.test(Item, item));
1080	}
1081	len = token.execs.length;
1082	for (pos = 0; pos < len; pos += 1) {
1083		exec = token.execs[pos];
1084		maybenext = exec.call(token, this, Item, item);
1085		if (maybenext) {
1086			next = maybenext;
1087		}
1088	}
1089	return next;
1090};
1091CSL.expandMacro = function (macro_key_token) {
1092	var mkey, start_token, key, end_token, navi, macro_nodes, newoutput, mergeoutput, end_of_macro, func;
1093	mkey = macro_key_token.postponed_macro;
1094	if (this.build.macro_stack.indexOf(mkey) > -1) {
1095		throw "CSL processor error: call to macro \"" + mkey + "\" would cause an infinite loop";
1096	} else {
1097		this.build.macro_stack.push(mkey);
1098	}
1099	var hasDate = false;
1100	var macroid = false;
1101	macro_nodes = this.sys.xml.getNodesByName(this.cslXml, 'macro', mkey);
1102	if (macro_nodes.length) {
1103		macroid = this.sys.xml.getAttributeValue(macro_nodes[0],'cslid');
1104		hasDate = this.sys.xml.getAttributeValue(macro_nodes[0], "macro-has-date");
1105	}
1106	if (hasDate) {
1107		func = function (state, Item) {
1108			if (state.tmp.extension) {
1109				state.tmp["doing-macro-with-date"] = true;
1110			}
1111		};
1112		macro_key_token.execs.push(func);
1113	}
1114	macro_key_token.tokentype = CSL.START;
1115	macro_key_token.cslid = macroid;
1116	CSL.Node.group.build.call(macro_key_token, this, this[this.build.area].tokens, true);
1117	if (!this.sys.xml.getNodeValue(macro_nodes)) {
1118		throw "CSL style error: undefined macro \"" + mkey + "\"";
1119	}
1120	var builder = CSL.makeBuilder(this);
1121	builder(macro_nodes[0]);
1122	end_of_macro = new CSL.Token("group", CSL.END);
1123	if (macro_key_token.decorations) {
1124		end_of_macro.decorations = macro_key_token.decorations.slice();
1125	}
1126	if (hasDate) {
1127		func = function (state, Item) {
1128			if (state.tmp.extension) {
1129				state.tmp["doing-macro-with-date"] = false;
1130			}
1131		};
1132		end_of_macro.execs.push(func);
1133	}
1134	CSL.Node.group.build.call(end_of_macro, this, this[this.build.area].tokens, true);
1135	this.build.macro_stack.pop();
1136};
1137CSL.XmlToToken = function (state, tokentype) {
1138	var name, txt, attrfuncs, attributes, decorations, token, key, target;
1139	name = state.sys.xml.nodename(this);
1140	if (state.build.skip && state.build.skip !== name) {
1141		return;
1142	}
1143	if (!name) {
1144		txt = state.sys.xml.content(this);
1145		if (txt) {
1146			state.build.text = txt;
1147		}
1148		return;
1149	}
1150	if (!CSL.Node[state.sys.xml.nodename(this)]) {
1151		throw "Undefined node name \"" + name + "\".";
1152	}
1153	attrfuncs = [];
1154	attributes = state.sys.xml.attributes(this);
1155	decorations = CSL.setDecorations.call(this, state, attributes);
1156	token = new CSL.Token(name, tokentype);
1157	if (tokentype !== CSL.END || name === "if" || name === "else-if" || name === "layout") {
1158		for (key in attributes) {
1159			if (attributes.hasOwnProperty(key)) {
1160				if (tokentype === CSL.END && key !== "@language" && key !== "@locale") {
1161					continue;
1162				}
1163				if (attributes.hasOwnProperty(key)) {
1164					if (CSL.Attributes[key]) {
1165						try {
1166							CSL.Attributes[key].call(token, state, "" + attributes[key]);
1167						} catch (e) {
1168							CSL.error(e);
1169							throw "CSL processor error, " + key + " attribute: " + e;
1170						}
1171					} else {
1172						CSL.debug("warning: undefined attribute \""+key+"\" in style");
1173					}
1174				}
1175			}
1176		}
1177		token.decorations = decorations;
1178	} else if (tokentype === CSL.END && attributes['@variable']) {
1179		token.hasVariable = true;
1180	}
1181	target = state[state.build.area].tokens;
1182	CSL.Node[name].build.call(token, state, target);
1183};
1184CSL.DateParser = function () {
1185	var jiy_list, jiy, jiysplitter, jy, jmd, jr, pos, key, val, yearlast, yearfirst, number, rangesep, fuzzychar, chars, rex, rexdash, rexdashslash, rexslashdash, seasonstrs, seasonrexes, seasonstr, monthstrs, monthstr, mrexes, seasonrex, len, jiymatchstring, jiymatcher;
1186	jiy_list = [
1187		["\u660E\u6CBB", 1867],
1188		["\u5927\u6B63", 1911],
1189		["\u662D\u548C", 1925],
1190		["\u5E73\u6210", 1988]
1191	];
1192	jiy = {};
1193	len = jiy_list.length;
1194	for (pos = 0; pos < len; pos += 1) {
1195		key = jiy_list[pos][0];
1196		val = jiy_list[pos][1];
1197		jiy[key] = val;
1198	}
1199	jiymatchstring = [];
1200	for (pos = 0; pos < len; pos += 1) {
1201		val = jiy_list[pos][0];
1202		jiymatchstring.push(val);
1203	}
1204	jiymatchstring = jiymatchstring.join("|");
1205	jiysplitter = "(?:" + jiymatchstring + ")(?:[0-9]+)";
1206	jiysplitter = new RegExp(jiysplitter);
1207	jiymatcher = "(?:" + jiymatchstring + ")(?:[0-9]+)";
1208	jiymatcher = new RegExp(jiymatcher, "g");
1209	jmd = /(\u6708|\u5E74)/g;
1210	jy = /\u65E5/;
1211	jr = /\u301c/g;
1212	yearlast = "(?:[?0-9]{1,2}%%NUMD%%){0,2}[?0-9]{4}(?![0-9])";
1213	yearfirst = "[?0-9]{4}(?:%%NUMD%%[?0-9]{1,2}){0,2}(?![0-9])";
1214	number = "[?0-9]{1,3}";
1215	rangesep = "[%%DATED%%]";
1216	fuzzychar = "[?~]";
1217	chars = "[a-zA-Z]+";
1218	rex = "(" + yearfirst + "|" + yearlast + "|" + number + "|" + rangesep + "|" + fuzzychar + "|" + chars + ")";
1219	rexdash = new RegExp(rex.replace(/%%NUMD%%/g, "-").replace(/%%DATED%%/g, "-"));
1220	rexdashslash = new RegExp(rex.replace(/%%NUMD%%/g, "-").replace(/%%DATED%%/g, "\/"));
1221	rexslashdash = new RegExp(rex.replace(/%%NUMD%%/g, "\/").replace(/%%DATED%%/g, "-"));
1222	seasonstrs = [];
1223	seasonrexes = [];
1224	len = seasonstrs.length;
1225	for (pos = 0; pos < len; pos += 1) {
1226		seasonrex = new RegExp(seasonstrs[pos] + ".*");
1227		seasonrexes.push(seasonrex);
1228	}
1229	this.mstrings = "january february march april may june july august september october november december spring summer fall winter spring summer";
1230	this.mstrings = this.mstrings.split(" ");
1231	this.setOrderDayMonth = function() {
1232		this.monthguess = 1;
1233		this.dayguess = 0;
1234	};
1235	this.setOrderMonthDay = function() {
1236		this.monthguess = 0;
1237		this.dayguess = 1;
1238	};
1239	this.setOrderMonthDay();
1240	this.resetMonths = function() {
1241		var i, ilen, j, jlen;
1242		this.msets = [];
1243		for (i = 0, ilen = this.mstrings.length; i < ilen; i += 1) {
1244			this.msets.push([this.mstrings[i]]);
1245		}
1246		this.mabbrevs = [];
1247		for (i = 0, ilen = this.msets.length; i < ilen; i += 1) {
1248			this.mabbrevs.push([]);
1249			for (j = 0, jlen = this.msets[i].length; j < jlen; j += 1) {
1250				this.mabbrevs[i].push(this.msets[i][0].slice(0, 3));
1251			}
1252		}
1253		this.mrexes = [];
1254		for (i = 0, ilen = this.mabbrevs.length; i < ilen; i += 1) {
1255			this.mrexes.push(new RegExp("(?:" + this.mabbrevs[i].join("|") + ")"));
1256		}
1257	};
1258	this.resetMonths();
1259	this.addMonths = function(lst) {
1260		var i, ilen, j, jlen, k, klen, jkey, kkey;
1261		if ("string" === typeof lst) {
1262			lst = lst.split(/\s+/);
1263		}
1264		if (lst.length !== 12 && lst.length !== 16) {
1265			CSL.debug("month [+season] list of "+lst.length+", expected 12 or 16. Ignoring.");
1266			return;
1267		}
1268		var othermatch = [];
1269		var thismatch = [];
1270		for (i = 0, ilen = lst.length; i < ilen; i += 1) {
1271			var abbrevlen = false;
1272			var skip = false;
1273			var insert = 3;
1274			var extend = {};
1275			for (j = 0, jlen = this.mabbrevs.length; j < jlen; j += 1) {
1276				extend[j] = {};
1277				if (j === i) {
1278					for (k = 0, klen = this.mabbrevs[i].length; k < klen; k += 1) {
1279						if (this.mabbrevs[i][k] === lst[i].slice(0, this.mabbrevs[i][k].length)) {
1280							skip = true;
1281							break;
1282						}
1283					}
1284				} else {
1285					for (k = 0, klen = this.mabbrevs[j].length; k < klen; k += 1) {
1286						abbrevlen = this.mabbrevs[j][k].length;
1287						if (this.mabbrevs[j][k] === lst[i].slice(0, abbrevlen)) {
1288							while (this.msets[j][k].slice(0, abbrevlen) === lst[i].slice(0, abbrevlen)) {
1289								if (abbrevlen > lst[i].length || abbrevlen > this.msets[j][k].length) {
1290									CSL.debug("unable to disambiguate month string in date parser: "+lst[i]);
1291									break;
1292								} else {
1293									abbrevlen += 1;
1294								}
1295							}
1296							insert = abbrevlen;
1297							extend[j][k] = abbrevlen;
1298						}
1299					}
1300				}
1301				for (jkey in extend) {
1302					if (extend.hasOwnProperty(jkey)) {
1303						for (kkey in extend[jkey]) {
1304							if (extend[jkey].hasOwnProperty(kkey)) {
1305								abbrevlen = extend[jkey][kkey];
1306								jkey = parseInt(jkey, 10);
1307								kkey = parseInt(kkey, 10);
1308								this.mabbrevs[jkey][kkey] = this.msets[jkey][kkey].slice(0, abbrevlen);
1309							}
1310						}
1311					}
1312				}
1313			}
1314			if (!skip) {
1315				this.msets[i].push(lst[i]);
1316				this.mabbrevs[i].push(lst[i].slice(0, insert));
1317			}
1318		}
1319		this.mrexes = [];
1320		for (i = 0, ilen = this.mabbrevs.length; i < ilen; i += 1) {
1321			this.mrexes.push(new RegExp("(?:" + this.mabbrevs[i].join("|") + ")"));
1322		}
1323	};
1324	this.parse = function (txt) {
1325		var slash, dash, lst, l, m, number, note, thedate, slashcount, range_delim, date_delim, ret, delim_pos, delims, isrange, suff, date, breakme, item, delim, element, mm, slst, mmpos, i, ilen, j, jlen, k, klen;
1326	if (txt) {
1327		txt = "" + txt;
1328		txt = txt.replace(/\s*[0-9]{2}:[0-9]{2}(?::[0-9]+)/,"");
1329		m = txt.match(jmd);
1330		if (m) {
1331			txt = txt.replace(/\s+/, "", "g");
1332			txt = txt.replace(jy, "", "g");
1333			txt = txt.replace(jmd, "-", "g");
1334			txt = txt.replace(jr, "/", "g");
1335			txt = txt.replace("-/", "/", "g");
1336			txt = txt.replace(/-$/,"", "g");
1337			slst = txt.split(jiysplitter);
1338			lst = [];
1339			mm = txt.match(jiymatcher);
1340			if (mm) {
1341				var mmx = [];
1342				for (pos = 0, len = mm.length; pos < len; pos += 1) {
1343					mmx = mmx.concat(mm[pos].match(/([^0-9]+)([0-9]+)/).slice(1));
1344				}
1345				for (pos = 0, len = slst.length; pos < len; pos += 1) {
1346					lst.push(slst[pos]);
1347					if (pos !== (len - 1)) {
1348						mmpos = (pos * 2);
1349						lst.push(mmx[mmpos]);
1350						lst.push(mmx[mmpos + 1]);
1351					}
1352				}
1353			} else {
1354				lst = slst;
1355			}
1356			l = lst.length;
1357			for    (pos = 1; pos < l; pos += 3) {
1358				lst[pos + 1] = jiy[lst[pos]] + parseInt(lst[pos + 1], 10);
1359				lst[pos] = "";
1360			}
1361			txt = lst.join("");
1362			txt = txt.replace(/\s*-\s*$/, "").replace(/\s*-\s*\//, "/");
1363			txt = txt.replace(/\.\s*$/, "");
1364			txt = txt.replace(/\.(?! )/, "");
1365			slash = txt.indexOf("/");
1366			dash = txt.indexOf("-");
1367		}
1368	}
1369		txt = txt.replace(/([A-Za-z])\./g, "$1");
1370		number = "";
1371		note = "";
1372		thedate = {};
1373		if (txt.slice(0, 1) === "\"" && txt.slice(-1) === "\"") {
1374			thedate.literal = txt.slice(1, -1);
1375			return thedate;
1376		}
1377		if (slash > -1 && dash > -1) {
1378			slashcount = txt.split("/");
1379			if (slashcount.length > 3) {
1380				range_delim = "-";
1381				date_delim = "/";
1382				lst = txt.split(rexslashdash);
1383			} else {
1384				range_delim = "/";
1385				date_delim = "-";
1386				lst = txt.split(rexdashslash);
1387			}
1388		} else {
1389			txt = txt.replace("/", "-");
1390			range_delim = "-";
1391			date_delim = "-";
1392			lst = txt.split(rexdash);
1393		}
1394		ret = [];
1395		len = lst.length;
1396		for (pos = 0; pos < len; pos += 1) {
1397			item = lst[pos];
1398			m = item.match(/^\s*([\-\/]|[a-zA-Z]+|[\-~?0-9]+)\s*$/);
1399			if (m) {
1400				ret.push(m[1]);
1401			}
1402		}
1403		delim_pos = ret.indexOf(range_delim);
1404		delims = [];
1405		isrange = false;
1406		if (delim_pos > -1) {
1407			delims.push([0, delim_pos]);
1408			delims.push([(delim_pos + 1), ret.length]);
1409			isrange = true;
1410		} else {
1411			delims.push([0, ret.length]);
1412		}
1413		suff = "";
1414		for (i = 0, ilen = delims.length; i < ilen; i += 1) {
1415			delim = delims[i];
1416			date = ret.slice(delim[0], delim[1]);
1417			for (j = 0, jlen = date.length; j < jlen; j += 1) {
1418				element = date[j];
1419				if (element.indexOf(date_delim) > -1) {
1420					this.parseNumericDate(thedate, date_delim, suff, element);
1421					continue;
1422				}
1423				if (element.match(/[0-9]{4}/)) {
1424					thedate[("year" + suff)] = element.replace(/^0*/, "");
1425					continue;
1426				}
1427				breakme = false;
1428				for (k = 0, klen = this.mrexes.length; k < klen; k += 1) {
1429					if (element.toLocaleLowerCase().match(this.mrexes[k])) {
1430						thedate[("month" + suff)] = "" + (parseInt(k, 10) + 1);
1431						breakme = true;
1432						break;
1433					}
1434					if (breakme) {
1435						continue;
1436					}
1437					if (element.match(/^[0-9]+$/)) {
1438						number = parseInt(element, 10);
1439					}
1440					if (element.toLocaleLowerCase().match(/^bc/) && number) {
1441						thedate[("year" + suff)] = "" + (number * -1);
1442						number = "";
1443						continue;
1444					}
1445					if (element.toLocaleLowerCase().match(/^ad/) && number) {
1446						thedate[("year" + suff)] = "" + number;
1447						number = "";
1448						continue;
1449					}
1450				}
1451				breakme = false;
1452				for (k = 0, klen = seasonrexes.length; k < klen; k += 1) {
1453					if (element.toLocaleLowerCase().match(seasonrexes[k])) {
1454						thedate[("season" + suff)] = "" + (parseInt(k, 10) + 1);
1455						breakme = true;
1456						break;
1457					}
1458				}
1459				if (breakme) {
1460					continue;
1461				}
1462				if (element === "~" || element === "?" || element === "c" || element.match(/^cir/)) {
1463					thedate.circa = "" + 1;
1464					continue;
1465				}
1466				if (element.toLocaleLowerCase().match(/(?:mic|tri|hil|eas)/) && !thedate[("season" + suff)]) {
1467					note = element;
1468					continue;
1469				}
1470			}
1471			if (number) {
1472				thedate[("day" + suff)] = number;
1473				number = "";
1474			}
1475			if (note && !thedate[("season" + suff)]) {
1476				thedate[("season" + suff)] = note;
1477				note = "";
1478			}
1479			suff = "_end";
1480		}
1481		if (isrange) {
1482			for (j = 0, jlen = CSL.DATE_PARTS_ALL.length; j < jlen; j += 1) {
1483				item = CSL.DATE_PARTS_ALL[j];
1484				if (thedate[item] && !thedate[(item + "_end")]) {
1485					thedate[(item + "_end")] = thedate[item];
1486				} else if (!thedate[item] && thedate[(item + "_end")]) {
1487					thedate[item] = thedate[(item + "_end")];
1488				}
1489			}
1490		}
1491		if (!thedate.year) {
1492			thedate = { "literal": txt };
1493		}
1494		if (this.use_array) {
1495			this.toArray(thedate);
1496		}
1497		return thedate;
1498	};
1499	this.returnAsArray = function () {
1500		this.use_array = true;
1501	};
1502	this.returnAsKeys = function () {
1503		this.use_array = false;
1504	};
1505	this.toArray = function (thedate) {
1506		var i, ilen, part;
1507		thedate["date-parts"] = [];
1508		thedate["date-parts"].push([]);
1509		var slicelen = 0;
1510		for (i = 0, ilen = 3; i < ilen; i += 1) {
1511			part = ["year", "month", "day"][i];
1512			if (!thedate[part]) {
1513				break;
1514			}
1515			slicelen += 1;
1516			thedate["date-parts"][0].push(thedate[part]);
1517			delete thedate[part];
1518		}
1519		thedate["date-parts"].push([]);
1520		for (i = 0, ilen = slicelen; i < ilen; i += 1) {
1521			part = ["year_end", "month_end", "day_end"][i];
1522			if (!thedate[part]) {
1523				break;
1524			}
1525			thedate["date-parts"][1].push(thedate[part]);
1526			delete thedate[part];
1527		}
1528		if (thedate["date-parts"][0].length !== thedate["date-parts"][1].length) {
1529			thedate["date-parts"].pop();
1530		}
1531	};
1532	this.parseNumericDate = function (ret, delim, suff, txt) {
1533		var lst, i, ilen;
1534		lst = txt.split(delim);
1535		for (i = 0, ilen = lst.length; i < ilen; i += 1) {
1536			if (lst[i].length === 4) {
1537				ret[("year" + suff)] = lst[i].replace(/^0*/, "");
1538				if (!i) {
1539					lst = lst.slice(1);
1540				} else {
1541					lst = lst.slice(0, i);
1542				}
1543				break;
1544			}
1545		}
1546		for (i = 0, ilen = lst.length; i < ilen; i += 1) {
1547			lst[i] = parseInt(lst[i], 10);
1548		}
1549		if (lst.length === 1 || (lst.length === 2 && !lst[1])) {
1550			ret[("month" + suff)] = "" + lst[0];
1551		} else if (lst.length === 2) {
1552			if (lst[this.monthguess] > 12) {
1553				ret[("month" + suff)] = "" + lst[this.dayguess];
1554				ret[("day" + suff)] = "" + lst[this.monthguess];
1555			} else {
1556				ret[("month" + suff)] = "" + lst[this.monthguess];
1557				ret[("day" + suff)] = "" + lst[this.dayguess];
1558			}
1559		}
1560	};
1561};
1562CSL.Engine = function (sys, style, lang, forceLang) {
1563	var attrs, langspec, localexml, locale;
1564	this.processor_version = CSL.PROCESSOR_VERSION;
1565	this.csl_version = "1.0";
1566	this.sys = sys;
1567	if (sys.variableWrapper) {
1568		CSL.VARIABLE_WRAPPER_PREPUNCT_REX = new RegExp('^([' + [" "].concat(CSL.SWAPPING_PUNCTUATION).join("") + ']*)(.*)');
1569	}
1570	this.sys.xml = new CSL.System.Xml.Parsing();
1571	if ("undefined" === typeof CSL_JSON && "string" !== typeof style) {
1572		style = "";
1573	}
1574	if (CSL.getAbbreviation) {
1575		this.sys.getAbbreviation = CSL.getAbbreviation;
1576	}
1577	if (this.sys.stringCompare) {
1578		CSL.stringCompare = this.sys.stringCompare;
1579	}
1580	this.sys.AbbreviationSegments = CSL.AbbreviationSegments;
1581	this.parallel = new CSL.Parallel(this);
1582	this.transform = new CSL.Transform(this);
1583	this.setParseNames = function (val) {
1584		this.opt['parse-names'] = val;
1585	};
1586	this.opt = new CSL.Engine.Opt();
1587	this.tmp = new CSL.Engine.Tmp();
1588	this.build = new CSL.Engine.Build();
1589	this.fun = new CSL.Engine.Fun(this);
1590	this.configure = new CSL.Engine.Configure();
1591	this.citation_sort = new CSL.Engine.CitationSort();
1592	this.bibliography_sort = new CSL.Engine.BibliographySort();
1593	this.citation = new CSL.Engine.Citation(this);
1594	this.bibliography = new CSL.Engine.Bibliography();
1595	this.output = new CSL.Output.Queue(this);
1596	this.dateput = new CSL.Output.Queue(this);
1597	this.cslXml = this.sys.xml.makeXml(style);
1598	if (this.opt.development_extensions.csl_reverse_lookup_support || this.sys.csl_reverse_lookup_support) {
1599		this.build.cslNodeId = 0;
1600		this.setCslNodeIds = function(myxml, nodename) {
1601			var children = this.sys.xml.children(myxml);
1602			this.sys.xml.setAttribute(myxml, 'cslid', this.build.cslNodeId);
1603			this.opt.nodenames.push(nodename);
1604			this.build.cslNodeId += 1;
1605			for (var i = 0, ilen = this.sys.xml.numberofnodes(children); i < ilen; i += 1) {
1606				nodename = this.sys.xml.nodename(children[i]);
1607				if (nodename) {
1608					this.setCslNodeIds(children[i], nodename);
1609				}
1610			}
1611		};
1612		this.setCslNodeIds(this.cslXml, "style");
1613	}
1614	this.sys.xml.addMissingNameNodes(this.cslXml);
1615	this.sys.xml.addInstitutionNodes(this.cslXml);
1616	this.sys.xml.insertPublisherAndPlace(this.cslXml);
1617	this.sys.xml.flagDateMacros(this.cslXml);
1618	attrs = this.sys.xml.attributes(this.cslXml);
1619	if ("undefined" === typeof attrs["@sort-separator"]) {
1620		this.sys.xml.setAttribute(this.cslXml, "sort-separator", ", ");
1621	}
1622	this.opt["initialize-with-hyphen"] = true;
1623	this.setStyleAttributes();
1624	this.opt.xclass = sys.xml.getAttributeValue(this.cslXml, "class");
1625	this.opt.styleID = this.sys.xml.getStyleId(this.cslXml);
1626	this.opt.styleName = this.sys.xml.getStyleId(this.cslXml, true);
1627	if (CSL.getSuppressJurisdictions) {
1628		this.opt.suppressJurisdictions = CSL.getSuppressJurisdictions(this.opt.styleID);
1629	}
1630	if (this.opt.version.slice(0,4) === "1.1m") {
1631		this.opt.development_extensions.static_statute_locator = true;
1632		this.opt.development_extensions.handle_parallel_articles = true;
1633		this.opt.development_extensions.main_title_from_short_title = true;
1634		this.opt.development_extensions.strict_page_numbers = true;
1635		this.opt.development_extensions.rtl_support = true;
1636		this.opt.development_extensions.expect_and_symbol_form = true;
1637		this.opt.development_extensions.require_explicit_legal_case_title_short = true;
1638	}
1639	if (lang) {
1640		lang = lang.replace("_", "-");
1641	}
1642	if (this.opt["default-locale"][0]) {
1643		this.opt["default-locale"][0] = this.opt["default-locale"][0].replace("_", "-");
1644	}
1645	if (lang && forceLang) {
1646		this.opt["default-locale"] = [lang];
1647	}
1648	if (lang && !forceLang && this.opt["default-locale"][0]) {
1649		lang = this.opt["default-locale"][0];
1650	}
1651	if (this.opt["default-locale"].length === 0) {
1652		if (!lang) {
1653			lang = "en-US";
1654		}
1655		this.opt["default-locale"].push("en-US");
1656	}
1657	if (!lang) {
1658		lang = this.opt["default-locale"][0];
1659	}
1660	langspec = CSL.localeResolve(lang);
1661	this.opt.lang = langspec.best;
1662	this.opt["default-locale"][0] = langspec.best;
1663	this.locale = {};
1664	if (!this.opt["default-locale-sort"]) {
1665		this.opt["default-locale-sort"] = this.opt["default-locale"][0];
1666	}
1667	this.localeConfigure(langspec);
1668	function makeRegExp(lst) {
1669		var lst = lst.slice();
1670		var ret = new RegExp( "((?:[?!:]*\\s+|-|^)(?:" + lst.join("|") + ")(?=[!?:]*\\s+|-|$))" );
1671		return ret;
1672	}
1673	this.locale[this.opt.lang].opts["skip-words-regexp"] = makeRegExp(this.locale[this.opt.lang].opts["skip-words"]);
1674	this.output.adjust = new CSL.Output.Queue.adjust(this.getOpt('punctuation-in-quote'));
1675	this.registry = new CSL.Registry(this);
1676	this.buildTokenLists("citation");
1677	this.buildTokenLists("bibliography");
1678	this.configureTokenLists();
1679	this.disambiguate = new CSL.Disambiguation(this);
1680	this.splice_delimiter = false;
1681	this.fun.dateparser = new CSL.DateParser();
1682	this.fun.flipflopper = new CSL.Util.FlipFlopper(this);
1683	this.setCloseQuotesArray();
1684	this.fun.ordinalizer.init(this);
1685	this.fun.long_ordinalizer.init(this);
1686	this.fun.page_mangler = CSL.Util.PageRangeMangler.getFunction(this, "page");
1687	this.fun.year_mangler = CSL.Util.PageRangeMangler.getFunction(this, "year");
1688	this.setOutputFormat("html");
1689};
1690CSL.Engine.prototype.setCloseQuotesArray = function () {
1691	var ret;
1692	ret = [];
1693	ret.push(this.getTerm("close-quote"));
1694	ret.push(this.getTerm("close-inner-quote"));
1695	ret.push('"');
1696	ret.push("'");
1697	this.opt.close_quotes_array = ret;
1698};
1699CSL.makeBuilder = function (me) {
1700	function enterFunc (node) {
1701		CSL.XmlToToken.call(node, me, CSL.START);
1702	};
1703	function leaveFunc (node) {
1704		CSL.XmlToToken.call(node, me, CSL.END);
1705	};
1706	function singletonFunc (node) {
1707		CSL.XmlToToken.call(node, me, CSL.SINGLETON);
1708	};
1709	function buildStyle (node) {
1710		var starttag, origparent;
1711		if (me.sys.xml.numberofnodes(me.sys.xml.children(node))) {
1712			origparent = node;
1713			enterFunc(origparent);
1714			for (var i=0;i<me.sys.xml.numberofnodes(me.sys.xml.children(origparent));i+=1) {
1715				node = me.sys.xml.children(origparent)[i];
1716				if (me.sys.xml.nodename(node) === null) {
1717					continue;
1718				}
1719				if (me.sys.xml.nodename(node) === "date") {
1720					CSL.Util.fixDateNode.call(me, origparent, i, node)
1721					node = me.sys.xml.children(origparent)[i];
1722				}
1723				buildStyle(node, enterFunc, leaveFunc, singletonFunc);
1724			}
1725			leaveFunc(origparent);
1726		} else {
1727			singletonFunc(node);
1728		}
1729	}
1730	return buildStyle;
1731};
1732CSL.Engine.prototype.buildTokenLists = function (area) {
1733	var builder = CSL.makeBuilder(this);
1734	var area_nodes;
1735	area_nodes = this.sys.xml.getNodesByName(this.cslXml, area);
1736	if (!this.sys.xml.getNodeValue(area_nodes)) {
1737		return;
1738	}
1739	this.build.area = area;
1740	var mynode = area_nodes[0];
1741	builder(mynode);
1742};
1743CSL.Engine.prototype.setStyleAttributes = function () {
1744	var dummy, attr, key, attributes, attrname;
1745	dummy = {};
1746	var cslXml = this.cslXml;
1747	var tagName = this.cslXml.tagName ? ("" + this.cslXml.tagName).toLowerCase() : "";
1748	if (tagName !== 'style' && tagName !== 'cslstyle') {
1749		if (this.cslXml.getElementsByTagName) {
1750			var cslXml = this.cslXml.getElementsByTagName('style')[0];
1751		}
1752	}
1753	dummy.name = this.sys.xml.nodename(cslXml);
1754	attributes = this.sys.xml.attributes(cslXml);
1755	for (attrname in attributes) {
1756		if (attributes.hasOwnProperty(attrname)) {
1757			CSL.Attributes[attrname].call(dummy, this, attributes[attrname]);
1758		}
1759	}
1760};
1761CSL.Engine.prototype.getTerm = function (term, form, plural, gender, mode, forceDefaultLocale) {
1762	if (term && term.match(/[A-Z]/) && term === term.toUpperCase()) {
1763		CSL.debug("Warning: term key is in uppercase form: "+term);
1764		term = term.toLowerCase();
1765	}
1766	var lang;
1767	if (forceDefaultLocale) {
1768		lang = this.opt["default-locale"][0];
1769	} else {
1770		lang = this.opt.lang;
1771	}
1772	var ret = CSL.Engine.getField(CSL.LOOSE, this.locale[lang].terms, term, form, plural, gender);
1773	if (!ret && term === "range-delimiter") {
1774		ret = "\u2013";
1775	}
1776	if (typeof ret === "undefined") {
1777		if (mode === CSL.STRICT) {
1778			throw "Error in getTerm: term \"" + term + "\" does not exist.";
1779		} else if (mode === CSL.TOLERANT) {
1780			ret = "";
1781		}
1782	}
1783	if (ret) {
1784		this.tmp.cite_renders_content = true;
1785	}
1786	return ret;
1787};
1788CSL.Engine.prototype.getDate = function (form, forceDefaultLocale) {
1789	var lang;
1790	if (forceDefaultLocale) {
1791		lang = this.opt["default-locale"];
1792	} else {
1793		lang = this.opt.lang;
1794	}
1795	if (this.locale[lang].dates[form]) {
1796		return this.locale[lang].dates[form];
1797	} else {
1798		return false;
1799	}
1800};
1801CSL.Engine.prototype.getOpt = function (arg) {
1802	if ("undefined" !== typeof this.locale[this.opt.lang].opts[arg]) {
1803		return this.locale[this.opt.lang].opts[arg];
1804	} else {
1805		return false;
1806	}
1807};
1808CSL.Engine.prototype.getVariable = function (Item, varname, form, plural) {
1809	return CSL.Engine.getField(CSL.LOOSE, Item, varname, form, plural);
1810};
1811CSL.Engine.prototype.getDateNum = function (ItemField, partname) {
1812	if ("undefined" === typeof ItemField) {
1813		return 0;
1814	} else {
1815		return ItemField[partname];
1816	}
1817};
1818CSL.Engine.getField = function (mode, hash, term, form, plural, gender) {
1819	var ret, forms, f, pos, len, hashterm;
1820	ret = "";
1821	if ("undefined" === typeof hash[term]) {
1822		if (mode === CSL.STRICT) {
1823			throw "Error in getField: term \"" + term + "\" does not exist.";
1824		} else {
1825			return undefined;
1826		}
1827	}
1828	if (gender && hash[term][gender]) {
1829		hashterm = hash[term][gender];
1830	} else {
1831		hashterm = hash[term];
1832	}
1833	forms = [];
1834	if (form === "symbol") {
1835		forms = ["symbol", "short"];
1836	} else if (form === "verb-short") {
1837		forms = ["verb-short", "verb"];
1838	} else if (form !== "long") {
1839		forms = [form];
1840	}
1841	forms = forms.concat(["long"]);
1842	len = forms.length;
1843	for (pos = 0; pos < len; pos += 1) {
1844		f = forms[pos];
1845		if ("string" === typeof hashterm || "number" === typeof hashterm) {
1846			ret = hashterm;
1847		} else if ("undefined" !== typeof hashterm[f]) {
1848			if ("string" === typeof hashterm[f] || "number" === typeof hashterm[f]) {
1849				ret = hashterm[f];
1850			} else {
1851				if ("number" === typeof plural) {
1852					ret = hashterm[f][plural];
1853				} else {
1854					ret = hashterm[f][0];
1855				}
1856			}
1857			break;
1858		}
1859	}
1860	return ret;
1861};
1862CSL.Engine.prototype.configureTokenLists = function () {
1863	var dateparts_master, area, pos, token, dateparts, part, ppos, pppos, len, llen, lllen;
1864	dateparts_master = ["year", "month", "day"];
1865	len = CSL.AREAS.length;
1866	for (pos = 0; pos < len; pos += 1) {
1867		area = CSL.AREAS[pos];
1868		llen = this[area].tokens.length - 1;
1869		for (ppos = llen; ppos > -1; ppos += -1) {
1870			token = this[area].tokens[ppos];
1871			if ("date" === token.name && CSL.END === token.tokentype) {
1872				dateparts = [];
1873			}
1874			if ("date-part" === token.name && token.strings.name) {
1875				lllen = dateparts_master.length;
1876				for (pppos = 0; pppos < lllen; pppos += 1) {
1877					part = dateparts_master[pppos];
1878					if (part === token.strings.name) {
1879						dateparts.push(token.strings.name);
1880					}
1881				}
1882			}
1883			if ("date" === token.name && CSL.START === token.tokentype) {
1884				dateparts.reverse();
1885				token.dateparts = dateparts;
1886			}
1887			token.next = (ppos + 1);
1888			if (token.name && CSL.Node[token.name].configure) {
1889				CSL.Node[token.name].configure.call(token, this, ppos);
1890			}
1891		}
1892	}
1893	this.version = CSL.version;
1894	return this.state;
1895};
1896CSL.Engine.prototype.retrieveItems = function (ids) {
1897	var ret, pos, len;
1898	ret = [];
1899	for (var i = 0, ilen = ids.length; i < ilen; i += 1) {
1900		ret.push(this.retrieveItem("" + ids[i]));
1901	}
1902	return ret;
1903};
1904CSL.ITERATION = 0;
1905CSL.Engine.prototype.retrieveItem = function (id) {
1906	var Item, m, pos, len, mm;
1907	if (this.opt.development_extensions.normalize_lang_keys_to_lowercase &&
1908		"boolean" === typeof this.opt.development_extensions.normalize_lang_keys_to_lowercase) {
1909		for (var i=0,ilen=this.opt["default-locale"].length; i<ilen; i+=1) {
1910			this.opt["default-locale"][i] = this.opt["default-locale"][i].toLowerCase();
1911		}
1912		for (var i=0,ilen=this.opt["locale-translit"].length; i<ilen; i+=1) {
1913			this.opt["locale-translit"][i] = this.opt["locale-translit"][i].toLowerCase();
1914		}
1915		for (var i=0,ilen=this.opt["locale-translat"].length; i<ilen; i+=1) {
1916			this.opt["locale-translat"][i] = this.opt["locale-translat"][i].toLowerCase();
1917		}
1918		this.opt.development_extensions.normalize_lang_keys_to_lowercase = 100;
1919	}
1920	CSL.ITERATION += 1;
1921	Item = this.sys.retrieveItem("" + id);
1922	if (this.opt.development_extensions.normalize_lang_keys_to_lowercase) {
1923		if (Item.multi) {
1924			if (Item.multi._keys) {
1925				for (var field in Item.multi._keys) {
1926					for (var key in Item.multi._keys[field]) {
1927						if (key !== key.toLowerCase()) {
1928							Item.multi._keys[field][key.toLowerCase()] = Item.multi._keys[field][key];
1929							delete Item.multi._keys[field][key];
1930						}
1931					}
1932				}
1933			}
1934			if (Item.multi.main) {
1935				for (var field in Item.multi.main) {
1936					Item.multi.main[field] = Item.multi.main[field].toLowerCase();
1937				}
1938			}
1939		}
1940		for (var i=0, ilen=CSL.CREATORS.length; i>ilen; i+=1) {
1941			var ctype = CSL.CREATORS[i];
1942			if (Item[ctype] && Item[ctype].multi) {
1943				for (var j=0, jlen=Item[ctype].length; j<jlen; j+=1) {
1944					var creator = Item[ctype][j];
1945					if (creator.multi) {
1946						if (creator.multi._key) {
1947							for (var key in creator.multi._key) {
1948								if (key !== key.toLowerCase()) {
1949									creator.multi._key[key.toLowerCase()] = creator.multi._key[key];
1950									delete creator.multi._key[key];
1951								}
1952							}
1953						}
1954						if (creator.multi.main) {
1955							creator.multi.main = creator.multi.main.toLowerCase();
1956						}
1957					}
1958				}
1959			}
1960		}
1961	}
1962	if (Item.page) {
1963		Item["page-first"] = Item.page;
1964		var num = "" + Item.page;
1965		m = num.split(/\s*(?:&|,|-|\u2013)\s*/);
1966		if (m[0].slice(-1) !== "\\") {
1967			Item["page-first"] = m[0];
1968		}
1969	}
1970	if (this.opt.development_extensions.field_hack && Item.note) {
1971		m = Item.note.match(CSL.NOTE_FIELDS_REGEXP);
1972		if (m) {
1973			var names = {};
1974			for (pos = 0, len = m.length; pos < len; pos += 1) {
1975				mm = m[pos].match(CSL.NOTE_FIELD_REGEXP);
1976				if (!Item[mm[1]] && CSL.DATE_VARIABLES.indexOf(mm[1]) > -1) {
1977					Item[mm[1]] = {raw:mm[2]};
1978				} else if (!Item[mm[1]] && CSL.NAME_VARIABLES.indexOf(mm[1]) > -1) {
1979					if (!Item[mm[1]]) {
1980						Item[mm[1]] = [];
1981					}
1982					var lst = mm[2].split(/\s*\|\|\s*/);
1983					if (lst.length === 1) {
1984						Item[mm[1]].push({family:lst[0],isInstitution:true});
1985					} else if (lst.length === 2) {
1986						Item[mm[1]].push({family:lst[0],given:lst[1]});
1987					}
1988				} else if (!Item[mm[1]] || mm[1] === "type") {
1989					Item[mm[1]] = mm[2].replace(/^\s+/, "").replace(/\s+$/, "");
1990				}
1991				Item.note.replace(CSL.NOTE_FIELD_REGEXP, "");
1992			}
1993		}
1994	}
1995	for (var i = 1, ilen = CSL.DATE_VARIABLES.length; i < ilen; i += 1) {
1996		var dateobj = Item[CSL.DATE_VARIABLES[i]];
1997		if (dateobj) {
1998			if (this.opt.development_extensions.raw_date_parsing) {
1999				if (dateobj.raw) {
2000					dateobj = this.fun.dateparser.parse(dateobj.raw);
2001				}
2002			}
2003			Item[CSL.DATE_VARIABLES[i]] = this.dateParseArray(dateobj);
2004		}
2005	}
2006	if (this.opt.development_extensions.static_statute_locator) {
2007		if (Item.type && ["bill","gazette","legislation","treaty"].indexOf(Item.type) > -1) {
2008			var varname;
2009			var elements = ["type", "title", "jurisdiction", "genre", "volume", "container-title"];
2010			var legislation_id = [];
2011			for (i = 0, ilen = elements.length; i < ilen; i += 1) {
2012				varname = elements[i];
2013				if (Item[varname]) {
2014					legislation_id.push(Item[varname]);
2015				}
2016			}
2017			elements = ["original-date", "issued"];
2018			for (i = 0, elements.length; i < ilen; i += 1) {
2019				varname = elements[i];
2020				if (Item[varname] && Item[varname].year) {
2021					var value = Item[varname].year;
2022					legislation_id.push(value);
2023					break;
2024				}
2025			}
2026			Item.legislation_id = legislation_id.join("::");
2027		}
2028	}
2029	if (!Item["title-short"]) {
2030		Item["title-short"] = Item.shortTitle;
2031	}
2032	if (this.opt.development_extensions.main_title_from_short_title) {
2033		Item["title-main"] = Item.title;
2034		Item["title-sub"] = false;
2035		if (Item.title && Item['title-short']) {
2036			var shortTitle = Item['title-short'];
2037			offset = shortTitle.length;
2038			if (Item.title.slice(0,offset) === shortTitle && Item.title.slice(offset).match(/^\s*:/)) {
2039				Item["title-main"] = Item.title.slice(0,offset).replace(/\s+$/,"");
2040				Item["title-sub"] = Item.title.slice(offset).replace(/^\s*:\s*/,"");
2041				if (this.opt.development_extensions.uppercase_subtitles && Item["title-sub"]) {
2042					var subtitle = Item["title-sub"]
2043					for (var i=0,ilen=subtitle.length;i<ilen;i++) {
2044						if (subtitle.charAt(i).toLowerCase() !== subtitle.charAt(i).toUpperCase()) {
2045							Item["title-sub"] = subtitle.slice(0,i) + subtitle.charAt(i).toUpperCase() + subtitle.slice(i+1);
2046							break
2047						}
2048					}
2049				}
2050				var mainPlusJoinOffset = offset + Item.title.length - Item["title-main"].length - Item["title-sub"].length;
2051				Item.title = Item.title.slice(0,mainPlusJoinOffset) + Item["title-sub"];
2052			}
2053		}
2054	}
2055	var isLegalType = ["legal_case","legislation","gazette","regulation"].indexOf(Item.type) > -1;
2056	if (!isLegalType && Item.title && this.sys.getAbbreviation) {
2057		var noHints = false;
2058		if (!Item.jurisdiction) {
2059			noHints = true;
2060		}
2061		var jurisdiction = this.transform.loadAbbreviation(Item.jurisdiction, "title", Item.title, Item.type, true);
2062		if (this.transform.abbrevs[jurisdiction].title) {
2063			if (this.transform.abbrevs[jurisdiction].title[Item.title]) {
2064				Item["title-short"] = this.transform.abbrevs[jurisdiction].title[Item.title];
2065			}
2066		}
2067	}
2068	Item["container-title-short"] = Item.journalAbbreviation;
2069	if (Item["container-title"] && this.sys.getAbbreviation) {
2070		var jurisdiction = this.transform.loadAbbreviation(Item.jurisdiction, "container-title", Item["container-title"]);
2071		if (this.transform.abbrevs[jurisdiction]["container-title"]) {
2072			if (this.transform.abbrevs[jurisdiction]["container-title"][Item["container-title"]]) {
2073				Item["container-title-short"] = this.transform.abbrevs[jurisdiction]["container-title"][Item["container-title"]];
2074			}
2075		}
2076	}
2077	return Item;
2078};
2079CSL.Engine.prototype.setOpt = function (token, name, value) {
2080	if (token.name === "style" || token.name === "cslstyle") {
2081		this.opt[name] = value;
2082	} else if (["citation", "bibliography"].indexOf(token.name) > -1) {
2083		this[token.name].opt[name] = value;
2084	} else if (["name-form", "name-delimiter", "names-delimiter"].indexOf(name) === -1) {
2085		token.strings[name] = value;
2086	}
2087};
2088CSL.Engine.prototype.fixOpt = function (token, name, localname) {
2089	if (["citation", "bibliography"].indexOf(token.name) > -1) {
2090		if (! this[token.name].opt[name] && "undefined" !== typeof this.opt[name]) {
2091			this[token.name].opt[name] = this.opt[name];
2092		}
2093	}
2094	if ("name" === token.name || "names" === token.name) {
2095		if ("undefined" === typeof token.strings[localname] && "undefined" !== typeof this[this.build.root].opt[name]) {
2096			token.strings[localname] = this[this.build.root].opt[name];
2097		}
2098	}
2099};
2100CSL.Engine.prototype.remapSectionVariable = function (inputList) {
2101	for (var i = 0, ilen = inputList.length; i < ilen; i += 1) {
2102		var Item = inputList[i][0];
2103		var item = inputList[i][1];
2104		var section_label_count = 0;
2105		var later_label = false;
2106		var value = false;
2107		if (["bill","gazette","legislation","treaty"].indexOf(Item.type) > -1) {
2108			item.force_pluralism = 0;
2109			if (!item.label) {
2110				item.label = "page"
2111			}
2112			var loci = ["section","","",""];
2113			var split;
2114			if (this.opt.development_extensions.static_statute_locator && Item.section) {
2115				splt = Item.section.replace(/^\s+/,"").replace(/\s+$/, "").split(/\s+/);
2116				if (CSL.STATUTE_SUBDIV_STRINGS[splt[0]]) {
2117					loci[0] = " " + splt[0] + " ";
2118					loci[1] = splt.slice(1).join(" ");
2119				} else {
2120					loci[0] = " sec. ";
2121					loci[1] = splt.slice(0).join(" ");
2122				}
2123			} else {
2124				if (this.opt.development_extensions.clobber_locator_if_no_statute_section) {
2125					item.locator = undefined;
2126					item.label = undefined;
2127				}
2128			}
2129			if (item.locator) {
2130				var splt = item.locator.replace(/^\s+/,"").replace(/\s+$/, "").split(/\s+/);
2131				if (CSL.STATUTE_SUBDIV_STRINGS[splt[0]]) {
2132					loci[2] = " " + splt[0] + " ";
2133					loci[3] = splt.slice(1).join(" ");
2134				} else if (item.label) {
2135					loci[2] = " " + CSL.STATUTE_SUBDIV_STRINGS_REVERSE[item.label] + " ";
2136					loci[3] = splt.slice(0).join(" ");
2137				} else {
2138					loci[3] = splt.join(" ")
2139				}
2140				if (loci[3] && loci[3].slice(0,1) === "&") {
2141					loci[3] = " " + loci[3];
2142				}
2143			}
2144			if (!loci[2]) {
2145				loci[2] = loci[0];
2146			}
2147			if (loci[3]) {
2148				if (loci[3].match(/^[^0-9a-zA-Z]/)) {
2149					var loclst = loci[3].split(/\s+/);
2150					if (loci[0] === loci[2] && loclst[1] && !CSL.STATUTE_SUBDIV_STRINGS[loclst[1].replace(/\s+/, "").replace(/\s+/, "")]) {
2151						item.force_pluralism = 1;
2152					}
2153					loci[2] = "";
2154				}
2155			} else {
2156				loci[2] = "";
2157			}
2158			if (!loci[1]) {
2159				loci[0] = "";
2160			}
2161			var value = loci.join("");
2162			value = value.replace(/^\s+/,"").replace(/\s+$/, "");
2163			if (value) {
2164				splt = value.split(/\s+/);
2165				if (CSL.STATUTE_SUBDIV_STRINGS[splt[0]]) {
2166					var has_other = false;
2167					for (var j = splt.length - 2; j > 0; j += -2) {
2168						if (splt[j] === splt[0]) {
2169							item.force_pluralism = 1;
2170							splt = splt.slice(0,j).concat(splt.slice(j + 1));
2171						}
2172					}
2173					item.label = CSL.STATUTE_SUBDIV_STRINGS[splt[0]];
2174					item.locator = splt.slice(1).join(" ");
2175					if (item.force_pluralism === 0) {
2176						delete item.force_pluralism;
2177					}
2178				} else {
2179					item.locator = splt.slice(0).join(" ");
2180				}
2181			}
2182		}
2183	}
2184}
2185CSL.Engine.prototype.setNumberLabels = function (Item) {
2186	if (Item.number
2187		&& ["bill", "gazette", "legislation", "treaty"].indexOf(Item.type) > -1
2188		&& this.opt.development_extensions.static_statute_locator
2189		&& !this.tmp.shadow_numbers["number"]) {
2190		this.tmp.shadow_numbers["number"] = {};
2191		this.tmp.shadow_numbers["number"].values = [];
2192		this.tmp.shadow_numbers["number"].plural = 0;
2193		this.tmp.shadow_numbers["number"].numeric = false;
2194		this.tmp.shadow_numbers["number"].label = false;
2195		var value = "" + Item.number;
2196		value = value.replace("\\", "", "g");
2197		var firstword = value.split(/\s/)[0];
2198		var firstlabel = CSL.STATUTE_SUBDIV_STRINGS[firstword];
2199		if (firstlabel) {
2200			var m = value.match(CSL.STATUTE_SUBDIV_GROUPED_REGEX);
2201			var splt = value.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX);
2202			if (splt.length > 1) {
2203				var lst = [];
2204				for (var j=1, jlen=splt.length; j < jlen; j += 1) {
2205					var subdiv = m[j - 1].replace(/^\s*/, "");
2206					lst.push(subdiv.replace("sec.", "Sec.").replace("ch.", "Ch."));
2207					lst.push(splt[j].replace(/\s*$/, "").replace(/^\s*/, ""));
2208				}
2209				value = lst.join(" ");
2210			} else {
2211				value = splt[0];
2212			}
2213			this.tmp.shadow_numbers["number"].values.push(["Blob", value, false]);
2214			this.tmp.shadow_numbers["number"].numeric = false;
2215		} else {
2216			this.tmp.shadow_numbers["number"].values.push(["Blob", value, false]);
2217			this.tmp.shadow_numbers["number"].numeric = true;
2218		}
2219	}
2220}
2221CSL.substituteOne = function (template) {
2222	return function (state, list) {
2223		if (!list) {
2224			return "";
2225		} else {
2226			return template.replace("%%STRING%%", list);
2227		}
2228	};
2229};
2230CSL.substituteTwo = function (template) {
2231	return function (param) {
2232		var template2 = template.replace("%%PARAM%%", param);
2233		return function (state, list) {
2234			if (!list) {
2235				return "";
2236			} else {
2237				return template2.replace("%%STRING%%", list);
2238			}
2239		};
2240	};
2241};
2242CSL.Mode = function (mode) {
2243	var decorations, params, param, func, val, args;
2244	decorations = {};
2245	params = CSL.Output.Formats[mode];
2246	for (param in params) {
2247		if (true) {
2248			if ("@" !== param.slice(0, 1)) {
2249				decorations[param] = params[param];
2250				continue;
2251			}
2252			func = false;
2253			val = params[param];
2254			args = param.split('/');
2255			if (typeof val === "string" && val.indexOf("%%STRING%%") > -1)  {
2256				if (val.indexOf("%%PARAM%%") > -1) {
2257					func = CSL.substituteTwo(val);
2258				} else {
2259					func = CSL.substituteOne(val);
2260				}
2261			} else if (typeof val === "boolean" && !val) {
2262				func = CSL.Output.Formatters.passthrough;
2263			} else if (typeof val === "function") {
2264				func = val;
2265			} else {
2266				throw "CSL.Compiler: Bad " + mode + " config entry for " + param + ": " + val;
2267			}
vendor: 7,558 bytes, lines 2268-2533
2268			if (args.length === 1) {
2269				decorations[args[0]] = func;
2270			} else if (args.length === 2) {
2271				if (!decorations[args[0]]) {
2272					decorations[args[0]] = {};
2273				}
2274				decorations[args[0]][args[1]] = func;
2275			}
2276		}
2277	}
2278	return decorations;
2279};
2280CSL.setDecorations = function (state, attributes) {
2281	var ret, key, pos;
2282	ret = [];
2283	for (pos in CSL.FORMAT_KEY_SEQUENCE) {
2284		if (true) {
2285			key = CSL.FORMAT_KEY_SEQUENCE[pos];
2286			if (attributes[key]) {
2287				ret.push([key, attributes[key]]);
2288				delete attributes[key];
2289			}
2290		}
2291	}
2292	return ret;
2293};
2294CSL.Engine.prototype.normalDecorIsOrphan = function (blob, params) {
2295	if (params[1] === "normal") {
2296		var use_param = false;
2297		var all_the_decor;
2298		if (this.tmp.area === "citation") {
2299			all_the_decor = [this.citation.opt.layout_decorations].concat(blob.alldecor);
2300		} else {
2301			all_the_decor = blob.alldecor;
2302		}
2303		for (var k = all_the_decor.length - 1; k > -1; k += -1) {
2304			for (var n = all_the_decor[k].length - 1; n > -1; n += -1) {
2305				if (all_the_decor[k][n][0] === params[0]) {
2306					if (all_the_decor[k][n][1] !== "normal") {
2307						use_param = true;
2308					}
2309				}
2310			}
2311		}
2312		if (!use_param) {
2313			return true;
2314		}
2315	}
2316	return false;
2317};
2318CSL.Engine.prototype.getCitationLabel = function (Item) {
2319	var label = "";
2320	var params = this.getTrigraphParams();
2321	var config = params[0];
2322	var myname = this.getTerm("reference", "short", 0);
2323	if ("undefined" === typeof myname) {
2324		myname = "reference";
2325	}
2326	myname = myname.replace(".", "");
2327	myname = myname.slice(0, 1).toUpperCase() + myname.slice(1);
2328	for (var i = 0, ilen = CSL.CREATORS.length; i < ilen; i += 1) {
2329		var n = CSL.CREATORS[i];
2330		if (Item[n]) {
2331			var names = Item[n];
2332			if (names.length > params.length) {
2333				config = params[params.length - 1];
2334			} else {
2335				config = params[names.length - 1];
2336			}
2337			for (var j = 0, jlen = names.length; j < jlen; j += 1) {
2338				if (j === config.authors.length) {
2339					break;
2340				}
2341				var res = this.nameOutput.getName(names[j], "locale-translit", true);
2342				var name = res.name;
2343				if (name && name.family) {
2344					myname = name.family;
2345					myname = myname.replace(/^([ \'\u2019a-z]+\s+)/, "");
2346				} else if (name && name.literal) {
2347					myname = name.literal;
2348				}
2349				var m = myname.toLowerCase().match(/^(a\s+|the\s+|an\s+)/);
2350				if (m) {
2351					myname = myname.slice(m[1].length);
2352				}
2353				myname = myname.replace(CSL.ROMANESQUE_NOT_REGEXP, "", "g");
2354				if (!myname) {
2355					break;
2356				}
2357				myname = myname.slice(0, config.authors[j]);
2358				if (myname.length > 1) {
2359					myname = myname.slice(0, 1).toUpperCase() + myname.slice(1).toLowerCase();
2360				} else if (myname.length === 1) {
2361					myname = myname.toUpperCase();
2362				}
2363				label += myname;
2364			}
2365			break;
2366		}
2367	}
2368	var year = "0000";
2369	if (Item.issued) {
2370		if (Item.issued.year) {
2371			year = "" + Item.issued.year;
2372		}
2373	}
2374	year = year.slice((config.year * -1));
2375	label = label + year;
2376	return label;
2377};
2378CSL.Engine.prototype.getTrigraphParams = function () {
2379	var params = [];
2380	var ilst = this.opt.trigraph.split(":");
2381	if (!this.opt.trigraph || this.opt.trigraph.slice(0,1) !== "A") {
2382		throw "Bad trigraph definition: "+this.opt.trigraph;
2383	}
2384	for (var i = 0, ilen = ilst.length; i < ilen; i += 1) {
2385		var str = ilst[i];
2386		var config = {authors:[], year:0};
2387		for (var j = 0, jlen = str.length; j < jlen; j += 1) {
2388			switch (str.slice(j,j+1)) {
2389			case "A":
2390				config.authors.push(1);
2391				break;
2392			case "a":
2393				config.authors[config.authors.length - 1] += 1;
2394				break;
2395			case "0":
2396				config.year += 1;
2397				break;
2398			default:
2399				throw "Invalid character in trigraph definition: "+this.opt.trigraph;
2400			}
2401		}
2402		params.push(config);
2403	}
2404	return params;
2405};
2406CSL.Engine.prototype.setOutputFormat = function (mode) {
2407	this.opt.mode = mode;
2408	this.fun.decorate = CSL.Mode(mode);
2409	if (!this.output[mode]) {
2410		this.output[mode] = {};
2411		this.output[mode].tmp = {};
2412	}
2413};
2414CSL.Engine.prototype.getSortFunc = function () {
2415	return function (a,b) {
2416		a = a.split("-");
2417		b = b.split("-");
2418		if (a.length < b.length) {
2419			return 1
2420		} else if (a.length > b.length) {
2421			return -1
2422		} else {
2423			a = a.slice(-1)[0];
2424			b = b.slice(-1)[0];
2425			if (a.length < b.length) {
2426				return 1;
2427			} else if (a.length > b.length) {
2428				return -1;
2429			} else {
2430				return 0;
2431			}
2432		}
2433	};
2434};
2435CSL.Engine.prototype.setLangTagsForCslSort = function (tags) {
2436	var i, ilen;
2437	if (tags) {
2438		this.opt['locale-sort'] = [];
2439		for (i = 0, ilen = tags.length; i < ilen; i += 1) {
2440			this.opt['locale-sort'].push(tags[i]);
2441		}
2442	}
2443	this.opt['locale-sort'].sort(this.getSortFunc());
2444};
2445CSL.Engine.prototype.setLangTagsForCslTransliteration = function (tags) {
2446	var i, ilen;
2447	this.opt['locale-translit'] = [];
2448	if (tags) {
2449		for (i = 0, ilen = tags.length; i < ilen; i += 1) {
2450			this.opt['locale-translit'].push(tags[i]);
2451		}
2452	}
2453	this.opt['locale-translit'].sort(this.getSortFunc());
2454};
2455CSL.Engine.prototype.setLangTagsForCslTranslation = function (tags) {
2456	var i, ilen;
2457	this.opt['locale-translat'] = [];
2458	if (tags) {
2459		for (i = 0, ilen = tags.length; i < ilen; i += 1) {
2460			this.opt['locale-translat'].push(tags[i]);
2461		}
2462	}
2463	this.opt['locale-translat'].sort(this.getSortFunc());
2464};
2465CSL.Engine.prototype.setLangPrefsForCites = function (obj, conv) {
2466	var opt = this.opt['cite-lang-prefs'];
2467	if (!conv) {
2468		conv = function (key) {
2469			return key.toLowerCase();
2470		};
2471	}
2472	var segments = ['Persons', 'Institutions', 'Titles', 'Journals', 'Publishers', 'Places'];
2473	for (var i = 0, ilen = segments.length; i < ilen; i += 1) {
2474		var clientSegment = conv(segments[i]);
2475		var citeprocSegment = segments[i].toLowerCase();
2476		if (!obj[clientSegment]) {
2477			continue;
2478		}
2479		var supplements = [];
2480		while (obj[clientSegment].length > 1) {
2481			supplements.push(obj[clientSegment].pop());
2482		}
2483		var sortval = {orig:1,translit:2,translat:3};
2484		if (supplements.length === 2 && sortval[supplements[0]] < sortval[supplements[1]]) {
2485			supplements.reverse();
2486		}
2487		while (supplements.length) {
2488			obj[clientSegment].push(supplements.pop());
2489		}
2490		var lst = opt[citeprocSegment];
2491		while (lst.length) {
2492			lst.pop();
2493		}
2494		for (var j = 0, jlen = obj[clientSegment].length; j < jlen; j += 1) {
2495			lst.push(obj[clientSegment][j]);
2496		}
2497	}
2498};
2499CSL.Engine.prototype.setLangPrefsForCiteAffixes = function (affixList) {
2500	if (affixList && affixList.length === 48) {
2501		var affixes = this.opt.citeAffixes;
2502		var count = 0;
2503		var settings = ["persons", "institutions", "titles", "journals", "publishers", "places"];
2504		var forms = ["translit", "orig", "translit", "translat"];
2505		var value;
2506		for (var i = 0, ilen = settings.length; i < ilen; i += 1) {
2507			for (var j = 0, jlen = forms.length; j < jlen; j += 1) {
2508				value = "";
2509				if ((count % 8) === 4) {
2510					if (!affixes[settings[i]]["locale-"+forms[j]].prefix
2511						&& !affixes[settings[i]]["locale-"+forms[j]].suffix) {
2512						value = affixList[count] ? affixList[count] : "";
2513						affixes[settings[i]]["locale-" + forms[j]].prefix = value;
2514						value = affixList[count] ? affixList[count + 1] : "";
2515						affixes[settings[i]]["locale-" + forms[j]].suffix = value;
2516					}
2517				} else {
2518					value = affixList[count] ? affixList[count] : "";
2519					affixes[settings[i]]["locale-" + forms[j]].prefix = value;
2520					value = affixList[count] ? affixList[count + 1] : "";
2521					affixes[settings[i]]["locale-" + forms[j]].suffix = value;
2522				}
2523				count += 2;
2524			}
2525		}
2526		this.opt.citeAffixes = affixes;
2527	}
2528};
2529CSL.Engine.prototype.setAutoVietnameseNamesOption = function (arg) {
2530	if (arg) {
2531		this.opt["auto-vietnamese-names"] = true;
2532	} else {
2533		this.opt["auto-vietnamese-names"] = false;
2534	}
2535};
2536CSL.Engine.prototype.setAbbreviations = function (arg) {
2537	if (this.sys.setAbbreviations) {
2538		this.sys.setAbbreviations(arg);
2539	}
2540};
2541CSL.Engine.prototype.setSuppressTrailingPunctuation = function (arg) {
2542	this.citation.opt.suppressTrailingPunctuation = !!arg;
2543};
2544CSL.Output = {};
2545CSL.Output.Queue = function (state) {
2546	this.levelname = ["top"];
2547	this.state = state;
2548	this.queue = [];
2549	this.empty = new CSL.Token("empty");
2550	var tokenstore = {};
2551	tokenstore.empty = this.empty;
2552	this.formats = new CSL.Stack(tokenstore);
2553	this.current = new CSL.Stack(this.queue);
2554};
2555CSL.Output.Queue.prototype.pop = function () {
2556	var drip = this.current.value();
2557	if (drip.length) {
2558		return drip.pop();
2559	} else {
2560		return drip.blobs.pop();
2561	}
2562};
2563CSL.Output.Queue.prototype.getToken = function (name) {
2564	var ret = this.formats.value()[name];
2565	return ret;
2566};
2567CSL.Output.Queue.prototype.mergeTokenStrings = function (base, modifier) {
2568	var base_token, modifier_token, ret, key;
2569	base_token = this.formats.value()[base];
2570	modifier_token = this.formats.value()[modifier];
2571	ret = base_token;
2572	if (modifier_token) {
2573		if (!base_token) {
2574			base_token = new CSL.Token(base, CSL.SINGLETON);
2575			base_token.decorations = [];
2576		}
2577		ret = new CSL.Token(base, CSL.SINGLETON);
2578		key = "";
2579		for (key in base_token.strings) {
2580			if (base_token.strings.hasOwnProperty(key)) {
2581				ret.strings[key] = base_token.strings[key];
2582			}
2583		}
2584		for (key in modifier_token.strings) {
2585			if (modifier_token.strings.hasOwnProperty(key)) {
2586				ret.strings[key] = modifier_token.strings[key];
2587			}
2588		}
2589		ret.decorations = base_token.decorations.concat(modifier_token.decorations);
2590	}
2591	return ret;
2592};
2593CSL.Output.Queue.prototype.addToken = function (name, modifier, token) {
2594	var newtok, attr;
2595	newtok = new CSL.Token("output");
2596	if ("string" === typeof token) {
2597		token = this.formats.value()[token];
2598	}
2599	if (token && token.strings) {
2600		for (attr in token.strings) {
2601			if (token.strings.hasOwnProperty(attr)) {
2602				newtok.strings[attr] = token.strings[attr];
2603			}
2604		}
2605		newtok.decorations = token.decorations;
2606	}
2607	if ("string" === typeof modifier) {
2608		newtok.strings.delimiter = modifier;
2609	}
2610	this.formats.value()[name] = newtok;
2611};
2612CSL.Output.Queue.prototype.pushFormats = function (tokenstore) {
2613	if (!tokenstore) {
2614		tokenstore = {};
2615	}
2616	tokenstore.empty = this.empty;
2617	this.formats.push(tokenstore);
2618};
2619CSL.Output.Queue.prototype.popFormats = function (tokenstore) {
2620	this.formats.pop();
2621};
2622CSL.Output.Queue.prototype.startTag = function (name, token) {
2623	var tokenstore = {};
2624	if (this.state.tmp["doing-macro-with-date"] && this.state.tmp.extension) {
2625		token = this.empty;
2626		name = "empty";
2627	}
2628	tokenstore[name] = token;
2629	this.pushFormats(tokenstore);
2630	this.openLevel(name);
2631};
2632CSL.Output.Queue.prototype.endTag = function (name) {
2633	this.closeLevel();
2634	this.popFormats();
2635};
2636CSL.Output.Queue.prototype.openLevel = function (token, ephemeral) {
2637	var blob, curr, x, has_ephemeral;
2638	if ("object" === typeof token) {
2639		blob = new CSL.Blob(undefined, token);
2640	} else if ("undefined" === typeof token) {
2641		blob = new CSL.Blob(undefined, this.formats.value().empty, "empty");
2642	} else {
2643		if (!this.formats.value() || !this.formats.value()[token]) {
2644			throw "CSL processor error: call to nonexistent format token \"" + token + "\"";
2645		}
2646		blob = new CSL.Blob(undefined, this.formats.value()[token], token);
2647	}
2648	if (this.nestedBraces) {
2649		blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
2650		blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
2651		blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
2652		blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
2653	}
2654	curr = this.current.value();
2655	curr.push(blob);
2656	this.current.push(blob);
2657};
2658CSL.Output.Queue.prototype.closeLevel = function (name) {
2659	if (name && name !== this.current.value().levelname) {
2660		CSL.error("Level mismatch error:  wanted " + name + " but found " + this.current.value().levelname);
2661	}
2662	this.current.pop();
2663};
2664CSL.Output.Queue.prototype.append = function (str, tokname, notSerious, ignorePredecessor, noStripPeriods) {
2665	var token, blob, curr;
2666	var useblob = true;
2667	if (notSerious) {
2668		ignorePredecessor = true;
2669	}
2670	if (this.state.tmp["doing-macro-with-date"] && !notSerious) {
2671		if (tokname !== "macro-with-date") {
2672			return false;
2673		}
2674		if (tokname === "macro-with-date") {
2675			tokname = "empty";
2676		}
2677	}
2678	if ("undefined" === typeof str) {
2679		return false;
2680	}
2681	if ("number" === typeof str) {
2682		str = "" + str;
2683	}
2684	if (!notSerious
2685		&& this.state.tmp.element_trace
2686		&& this.state.tmp.element_trace.value() === "suppress-me") {
2687		return false;
2688	}
2689	blob = false;
2690	if (!tokname) {
2691		token = this.formats.value().empty;
2692	} else if (tokname === "literal") {
2693		token = true;
2694		useblob = false;
2695	} else if ("string" === typeof tokname) {
2696		token = this.formats.value()[tokname];
2697	} else {
2698		token = tokname;
2699	}
2700	if (!token) {
2701		throw "CSL processor error: unknown format token name: " + tokname;
2702	}
2703	if (token.strings && "undefined" === typeof token.strings.delimiter) {
2704		token.strings.delimiter = "";
2705	}
2706	if ("string" === typeof str && str.length) {
2707		str = str.replace(/ ([:;?!\u00bb])/g, "\u202f$1").replace(/\u00ab /g, "\u00ab\u202f");
2708		this.last_char_rendered = str.slice(-1);
2709		str = str.replace(/\s+'/g, "  \'").replace(/^'/g, " \'");
2710		if (!ignorePredecessor) {
2711			this.state.tmp.term_predecessor = true;
2712		} else if (notSerious) {
2713			this.state.tmp.term_predecessor_name = true;
2714		}
2715	}
2716	blob = new CSL.Blob(str, token);
2717	if (this.nestedBraces) {
2718		blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
2719		blob.strings.prefix = blob.strings.prefix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
2720		blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[0][0], this.nestedBraces[0][1]);
2721		blob.strings.suffix = blob.strings.suffix.replace(this.nestedBraces[1][0], this.nestedBraces[1][1]);
2722	}
2723	curr = this.current.value();
2724	if ("undefined" === typeof curr && this.current.mystack.length === 0) {
2725		this.current.mystack.push([]);
2726		curr = this.current.value();
2727	}
2728	if ("string" === typeof blob.blobs) {
2729		if (!ignorePredecessor) {
2730			this.state.tmp.term_predecessor = true;
2731		} else if (notSerious) {
2732			this.state.tmp.term_predecessor_name = true;
2733		}
2734	}
2735	if (!notSerious) {
2736		this.state.parallel.AppendBlobPointer(curr);
2737	}
2738	if ("string" === typeof str) {
2739		curr.push(blob);
2740		if (blob.strings["text-case"]) {
2741			blob.blobs = CSL.Output.Formatters[blob.strings["text-case"]](this.state, str);
2742		}
2743		if (this.state.tmp.strip_periods && !noStripPeriods) {
2744			blob.blobs = blob.blobs.replace(/\.([^a-z]|$)/g, "$1");
2745		}
2746		for (var i = blob.decorations.length - 1; i > -1; i += -1) {
2747			if (blob.decorations[i][0] === "@quotes" && blob.decorations[i][1] === "true") {
2748				blob.punctuation_in_quote = this.state.getOpt("punctuation-in-quote");
2749			}
2750			if (!blob.blobs.match(CSL.ROMANESQUE_REGEXP)) {
2751				if (blob.decorations[i][0] === "@font-style") {
2752					blob.decorations = blob.decorations.slice(0, i).concat(blob.decorations.slice(i + 1));
2753				}
2754			}
2755		}
2756		this.state.fun.flipflopper.init(str, blob);
2757		this.state.fun.flipflopper.processTags();
2758	} else if (useblob) {
2759		curr.push(blob);
2760	} else {
2761		curr.push(str);
2762	}
2763	return true;
2764};
2765CSL.Output.Queue.prototype.string = function (state, myblobs, blob) {
2766	var i, ilen, j, jlen, b;
2767	var txt_esc = CSL.getSafeEscape(this.state);
2768	var blobs = myblobs.slice();
2769	var ret = [];
2770	if (blobs.length === 0) {
2771		return ret;
2772	}
2773	var blob_delimiter = "";
2774	if (blob) {
2775		blob_delimiter = blob.strings.delimiter;
2776	} else {
2777		state.tmp.count_offset_characters = false;
2778		state.tmp.offset_characters = 0;
2779	}
2780	if (blob && blob.new_locale) {
2781		blob.old_locale = state.opt.lang;
2782		state.opt.lang = blob.new_locale;
2783	}
2784	var blobjr, use_suffix, use_prefix, params;
2785	for (i = 0, ilen = blobs.length; i < ilen; i += 1) {
2786		blobjr = blobs[i];
2787		if (blobjr.strings.first_blob) {
2788			state.tmp.count_offset_characters = blobjr.strings.first_blob;
2789		}
2790		if ("string" === typeof blobjr.blobs) {
2791			if ("number" === typeof blobjr.num) {
2792				ret.push(blobjr);
2793			} else if (blobjr.blobs) {
2794				b = txt_esc(blobjr.blobs);
2795				var blen = b.length;
2796				if (!state.tmp.suppress_decorations) {
2797					for (j = 0, jlen = blobjr.decorations.length; j < jlen; j += 1) {
2798						params = blobjr.decorations[j];
2799						if (params[0] === "@showid") {
2800							continue;
2801						}
2802						if (state.normalDecorIsOrphan(blobjr, params)) {
2803							continue;
2804						}
2805						b = state.fun.decorate[params[0]][params[1]].call(blobjr, state, b, params[2]);
2806					}
2807				}
2808				if (b && b.length) {
2809					b = txt_esc(blobjr.strings.prefix, state.tmp.nestedBraces) + b + txt_esc(blobjr.strings.suffix, state.tmp.nestedBraces);
2810					if ((state.opt.development_extensions.csl_reverse_lookup_support || state.sys.csl_reverse_lookup_support) && !state.tmp.suppress_decorations) {
2811						for (j = 0, jlen = blobjr.decorations.length; j < jlen; j += 1) {
2812							params = blobjr.decorations[j];
2813							if (params[0] === "@showid") {
2814								b = state.fun.decorate[params[0]][params[1]].call(blobjr, state, b, params[2]);
2815							}
2816						}
2817					}
2818					ret.push(b);
2819					if (state.tmp.count_offset_characters) {
2820						state.tmp.offset_characters += (blen + blobjr.strings.suffix.length + blobjr.strings.prefix.length);
2821					}
2822				}
2823			}
2824		} else if (blobjr.blobs.length) {
2825			var addtoret = state.output.string(state, blobjr.blobs, blobjr);
2826			ret = ret.concat(addtoret);
2827		}
2828		if (blobjr.strings.first_blob) {
2829			state.registry.registry[blobjr.strings.first_blob].offset = state.tmp.offset_characters;
2830			state.tmp.count_offset_characters = false;
2831		}
2832	}
2833	for (i=0,ilen=ret.length - 1;i<ilen;i+=1) {
2834		if ("number" === typeof ret[i].num && "number" === typeof ret[i+1].num && !ret[i+1].UGLY_DELIMITER_SUPPRESS_HACK) {
2835			ret[i].strings.suffix = ret[i].strings.suffix + (blob_delimiter ? blob_delimiter : "");
2836			ret[i+1].successor_prefix = "";
2837			ret[i+1].UGLY_DELIMITER_SUPPRESS_HACK = true;
2838		}
2839	}
2840	var span_split = 0;
2841	for (i = 0, ilen = ret.length; i < ilen; i += 1) {
2842		if ("string" === typeof ret[i]) {
2843			span_split = (parseInt(i, 10) + 1);
2844			if (i < ret.length - 1  && "object" === typeof ret[i + 1]) {
2845				if (blob_delimiter && !ret[i + 1].UGLY_DELIMITER_SUPPRESS_HACK) {
2846					ret[i] += txt_esc(blob_delimiter);
2847				}
2848				ret[i + 1].UGLY_DELIMITER_SUPPRESS_HACK = true;
2849			}
2850		}
2851	}
2852	if (blob && (blob.decorations.length || blob.strings.suffix || blob.strings.prefix)) {
2853		span_split = ret.length;
2854	}
2855	var blobs_start = state.output.renderBlobs(ret.slice(0, span_split), blob_delimiter, true, blob);
2856	if (blobs_start && blob && (blob.decorations.length || blob.strings.suffix || blob.strings.prefix)) {
2857		if (!state.tmp.suppress_decorations) {
2858			for (i = 0, ilen = blob.decorations.length; i < ilen; i += 1) {
2859				params = blob.decorations[i];
2860				if (["@cite","@bibliography", "@display", "@showid"].indexOf(params[0]) > -1) {
2861					continue;
2862				}
2863				if (state.normalDecorIsOrphan(blobjr, params)) {
2864					continue;
2865				}
2866				if ("string" === typeof blobs_start) {
2867					blobs_start = state.fun.decorate[params[0]][params[1]].call(blob, state, blobs_start, params[2]);
2868				}
2869			}
2870		}
2871		b = blobs_start;
2872		use_suffix = blob.strings.suffix;
2873		if (b && b.length) {
2874			use_prefix = blob.strings.prefix;
2875			b = txt_esc(use_prefix, state.tmp.nestedBraces) + b + txt_esc(use_suffix, state.tmp.nestedBraces);
2876			if (state.tmp.count_offset_characters) {
2877				state.tmp.offset_characters += (use_prefix.length + use_suffix.length);
2878			}
2879		}
2880		blobs_start = b;
2881		if (!state.tmp.suppress_decorations) {
2882			for (i = 0, ilen = blob.decorations.length; i < ilen; i += 1) {
2883				params = blob.decorations[i];
2884				if (["@cite","@bibliography", "@display", "@showid"].indexOf(params[0]) === -1) {
2885					continue;
2886				}
2887				if ("string" === typeof blobs_start) {
2888					blobs_start = state.fun.decorate[params[0]][params[1]].call(blob, state, blobs_start, params[2]);
2889				}
2890			}
2891		}
2892	}
2893	var blobs_end = ret.slice(span_split, ret.length);
2894	if (!blobs_end.length && blobs_start) {
2895		ret = [blobs_start];
2896	} else if (blobs_end.length && !blobs_start) {
2897		ret = blobs_end;
2898	} else if (blobs_start && blobs_end.length) {
2899		ret = [blobs_start].concat(blobs_end);
2900	}
2901	if ("undefined" === typeof blob) {
2902		this.queue = [];
2903		this.current.mystack = [];
2904		this.current.mystack.push(this.queue);
2905		if (state.tmp.suppress_decorations) {
2906			ret = state.output.renderBlobs(ret, undefined, true);
2907		}
2908	} else if ("boolean" === typeof blob) {
2909		ret = state.output.renderBlobs(ret, undefined, true);
2910	}
2911	if (blob && blob.new_locale) {
2912		state.opt.lang = blob.old_locale;
2913	}
2914	return ret;
2915};
2916CSL.Output.Queue.prototype.clearlevel = function () {
2917	var blob, pos, len;
2918	blob = this.current.value();
2919	len = blob.blobs.length;
2920	for (pos = 0; pos < len; pos += 1) {
2921		blob.blobs.pop();
2922	}
2923};
2924CSL.Output.Queue.prototype.renderBlobs = function (blobs, delim, in_cite, parent) {
2925	var state, ret, ret_last_char, use_delim, i, blob, pos, len, ppos, llen, pppos, lllen, res, str, params, txt_esc;
2926	txt_esc = CSL.getSafeEscape(this.state);
2927	if (!delim) {
2928		delim = "";
2929	}
2930	state = this.state;
2931	ret = "";
2932	ret_last_char = [];
2933	use_delim = "";
2934	len = blobs.length;
2935	if (this.state.tmp.area === "citation" && !this.state.tmp.just_looking && len === 1 && typeof blobs[0] === "object" && parent) {
2936		blobs[0].strings.prefix = parent.strings.prefix + blobs[0].strings.prefix;
2937		blobs[0].strings.suffix = blobs[0].strings.suffix + parent.strings.suffix;
2938		blobs[0].decorations = blobs[0].decorations.concat(parent.decorations);
2939		blobs[0].params = parent.params;
2940		return blobs[0];
2941	}
2942	var start = true;
2943	for (pos = 0; pos < len; pos += 1) {
2944		if (blobs[pos].checkNext) {
2945			blobs[pos].checkNext(blobs[(pos + 1)],start);
2946			start = false;
2947		} else {
2948			start = true;
2949		}
2950	}
2951	var doit = true;
2952	for (pos = blobs.length - 1; pos > 0; pos += -1) {
2953		if (blobs[pos].checkLast) {
2954		if (doit && blobs[pos].checkLast(blobs[pos - 1])) {
2955			doit = false;
2956		}
2957		} else {
2958		doit = true;
2959		}
2960	}
2961	len = blobs.length;
2962	for (pos = 0; pos < len; pos += 1) {
2963		blob = blobs[pos];
2964		if (ret) {
2965			use_delim = delim;
2966		}
2967		if ("string" === typeof blob) {
2968			ret += txt_esc(use_delim);
2969			ret += blob;
2970			if (state.tmp.count_offset_characters) {
2971				state.tmp.offset_characters += (use_delim.length);
2972			}
2973		} else if (blob.status !== CSL.SUPPRESS) {
2974			str = blob.formatter.format(blob.num, blob.gender);
2975			var strlen = str.replace(/<[^>]*>/g, "").length;
2976			this.append(str, "empty", true);
2977			var str_blob = this.pop();
2978			var count_offset_characters = state.tmp.count_offset_characters;
2979			str = this.string(state, [str_blob], false);
2980			state.tmp.count_offset_characters = count_offset_characters;
2981			if (blob.strings["text-case"]) {
2982				str = CSL.Output.Formatters[blob.strings["text-case"]](this.state, str);
2983			}
2984			if (str && this.state.tmp.strip_periods) {
2985				str = str.replace(/\.([^a-z]|$)/g, "$1");
2986			}
2987			if (!state.tmp.suppress_decorations) {
2988				llen = blob.decorations.length;
2989				for (ppos = 0; ppos < llen; ppos += 1) {
2990					params = blob.decorations[ppos];
2991					if (state.normalDecorIsOrphan(blob, params)) {
2992						continue;
2993					}
2994					str = state.fun.decorate[params[0]][params[1]].call(blob, state, str, params[2]);
2995				}
2996			}
2997			str = txt_esc(blob.strings.prefix) + str + txt_esc(blob.strings.suffix);
2998			var addme = "";
2999			if (blob.status === CSL.END) {
3000				addme = txt_esc(blob.range_prefix);
3001			} else if (blob.status === CSL.SUCCESSOR) {
3002				addme = txt_esc(blob.successor_prefix);
3003			} else if (blob.status === CSL.START) {
3004				addme = "";
3005			} else if (blob.status === CSL.SEEN) {
3006				addme = txt_esc(blob.splice_prefix);
3007			}
3008			ret += addme;
3009			ret += str;
3010			if (state.tmp.count_offset_characters) {
3011				state.tmp.offset_characters += (addme.length + blob.strings.prefix.length + strlen + blob.strings.suffix.length);
3012			}
3013		}
3014	}
3015	return ret;
3016};
3017CSL.Output.Queue.purgeEmptyBlobs = function (parent) {
3018	if ("object" !== typeof parent || "object" !== typeof parent.blobs || !parent.blobs.length) {
3019		return;
3020	}
3021	for (var i=parent.blobs.length-1;i>-1;i--) {
3022		CSL.Output.Queue.purgeEmptyBlobs(parent.blobs[i]);
3023		var child = parent.blobs[i];
3024		if (!child || !child.blobs || !child.blobs.length) {
3025			var buf = [];
3026			while ((parent.blobs.length-1) > i) {
3027				buf.push(parent.blobs.pop());
3028			}
3029			parent.blobs.pop();
3030			while (buf.length) {
3031				parent.blobs.push(buf.pop());
3032			}
3033		}
3034	}
3035};
3036CSL.Output.Queue.adjust = function (punctInQuote) {
3037	var NO_SWAP_IN = {
3038		";": true,
3039		":": true
3040	}
3041	var NO_SWAP_OUT = {
3042		".": true,
3043		"!": true,
3044		"?": true
3045	}
3046	this.upward = upward;
3047	this.leftward = leftward;
3048	this.downward = downward;
3049	this.fix = fix;
3050	var LtoR_MAP = {
3051		"!": {
3052			".": "!",
3053			"?": "!?",
3054			":": "!",
3055			",": "!,",
3056			";": "!;"
3057		},
3058		"?": {
3059			"!": "?!",
3060			".": "?",
3061			":": "?",
3062			",": "?,",
3063			";": "?;"
3064		},
3065		".": {
3066			"!": ".!",
3067			"?": ".?",
3068			":": ".:",
3069			",": ".,",
3070			";": ".;"
3071		},
3072		":": {
3073			"!": "!",
3074			"?": "?",
3075			".": ":",
3076			",": ":,",
3077			";": ":;"
3078		},
3079		",": {
3080			"!": ",!",
3081			"?": ",?",
3082			":": ",:",
3083			".": ",.",
3084			";": ",;"
3085		},
3086		";": {
3087			"!": "!",
3088			"?": "?",
3089			":": ";",
3090			",": ";,",
3091			".": ";"
3092		}
3093	}
3094	var SWAP_IN = {};
3095	var SWAP_OUT = {};
3096	var PUNCT = {};
3097	var PUNCT_OR_SPACE = {};
3098	for (var key in LtoR_MAP) {
3099		PUNCT[key] = true;
3100		PUNCT_OR_SPACE[key] = true;
3101		if (!NO_SWAP_IN[key]) {
3102			SWAP_IN[key] = true;
3103		}
3104		if (!NO_SWAP_OUT[key]) {
3105			SWAP_OUT[key] = true;
3106		}
3107	}
3108	PUNCT_OR_SPACE[" "] = true;
3109	PUNCT_OR_SPACE[" "] = true;
3110	var RtoL_MAP = {};
3111	for (var key in LtoR_MAP) {
3112		for (var subkey in LtoR_MAP[key]) {
3113			if (!RtoL_MAP[subkey]) {
3114				RtoL_MAP[subkey] = {};
3115			}
3116			RtoL_MAP[subkey][key] = LtoR_MAP[key][subkey];
3117		}
3118	}
3119	function blobIsNumber(blob) {
3120		return ("number" === typeof blob.num || (blob.blobs && blob.blobs.length === 1 && "number" === typeof blob.blobs[0].num));
3121	};
3122	function blobEndsInNumber(blob) {
3123		if ("number" === typeof blob.num) {
3124			return true;
3125		}
3126		if (!blob.blobs || "object" !==  typeof blob.blobs) return false;
3127		if (blobEndsInNumber(blob.blobs[blob.blobs.length-1])) return true;
3128	}
3129	function blobHasDecorations(blob,includeQuotes) {
3130		var ret = false;
3131		var decorlist = ['@font-style','@font-variant','@font-weight','@text-decoration','@vertical-align'];
3132		if (includeQuotes) {
3133			decorlist.push('@quotes');
3134		}
3135		if (blob.decorations) {
3136			for (var i=0,ilen=blob.decorations.length;i<ilen;i++) {
3137				if (decorlist.indexOf(blob.decorations[i][0]) > -1) {
3138					ret = true;
3139					break;
3140				}
3141			}
3142		}
3143		return ret;
3144	};
3145	function blobHasDescendantQuotes(blob) {
3146		if (blob.decorations) {
3147			for (var i=0,ilen=blob.decorations.length;i<ilen;i++) {
3148				if (blob.decorations[i][0] === '@quotes') {
3149					return true;
3150				}
3151			}
3152		}
3153		if ("object" !== typeof blob.blobs) return false;
3154		if (blobHasDescendantQuotes(blob.blobs[blob.blobs.length-1])) return true;
3155		return false;
3156	}
3157	function blobHasDescendantMergingPunctuation(parentChar,blob) {
3158		var childChar = blob.strings.suffix.slice(-1);
3159		if (!childChar && "string" === typeof blob.blobs) {
3160			childChar = blob.blobs.slice(-1);
3161		}
3162		var mergedChars = RtoL_MAP[parentChar][childChar];
3163		if (mergedChars && mergedChars.length === 1) {
3164			return true;
3165		}
3166		if ("object" !== typeof blob.blobs) return false;
3167		if (blobHasDescendantMergingPunctuation(parentChar,blob.blobs[blob.blobs.length-1])) return true;
3168		return false;
3169	}
3170	function matchLastChar(blob, chr) {
3171		if (!PUNCT[chr]) {
3172			return false;
3173		}
3174		if ("string" === typeof blob.blobs) {
3175			if (blob.blobs.slice(-1) === chr) {
3176				return true;
3177			} else {
3178				return false;
3179			}
3180		} else {
3181			var child = blob.blobs[blob.blobs.length-1];
3182			if (child) {
3183				var childChar = child.strings.suffix.slice(-1);
3184				if (!childChar) {
3185					return matchLastChar(child,chr);
3186				} else if (child.strings.suffix.slice(-1) == chr) {
3187					return true;
3188				} else {
3189					return false;
3190				}
3191			} else {
3192				return false;
3193			}
3194		}
3195	};
3196	function mergeChars (First, first, Second, second, merge_right) {
3197		FirstStrings = "blobs" === first ? First : First.strings;
3198		SecondStrings = "blobs" === second ? Second: Second.strings;
3199		var firstChar = FirstStrings[first].slice(-1);
3200		var secondChar = SecondStrings[second].slice(0,1);
3201		function cullRight () {
3202			SecondStrings[second] = SecondStrings[second].slice(1);
3203		};
3204		function cullLeft () {
3205			FirstStrings[first] = FirstStrings[first].slice(0,-1);
3206		};
3207		function addRight (chr) {
3208			SecondStrings[second] = chr + SecondStrings[second];
3209		}
3210		function addLeft (chr) {
3211			FirstStrings[first] += chr;
3212		}
3213		var cull = merge_right ? cullLeft : cullRight;
3214		function matchOnRight () {
3215			return RtoL_MAP[secondChar];
3216		}
3217		function matchOnLeft () {
3218			return LtoR_MAP[firstChar];
3219		}
3220		var match = merge_right ? matchOnLeft : matchOnRight;
3221		function mergeToRight () {
3222			var chr = LtoR_MAP[firstChar][secondChar];
3223			if ("string" === typeof chr) {
3224				cullLeft();
3225				cullRight();
3226				addRight(chr);
3227			} else {
3228				addRight(firstChar);
3229				cullLeft();
3230			}
3231		}
3232		function mergeToLeft () {
3233			var chr = RtoL_MAP[secondChar][firstChar];
3234			if ("string" === typeof chr) {
3235				cullLeft();
3236				cullRight();
3237				addLeft(chr);
3238			} else {
3239				addLeft(secondChar);
3240				cullRight();
3241			}
3242		}
3243		var merge = merge_right ? mergeToRight: mergeToLeft;
3244		var isDuplicate = firstChar === secondChar;
3245		if (isDuplicate) {
3246			cull();
3247		} else {
3248			if (match()) {
3249				merge();
3250			}
3251		}
3252	};
3253	function upward (parent) {
3254		if (parent.blobs && "string" == typeof parent.blobs) {
3255			if (PUNCT[parent.strings.suffix.slice(0,1)]
3256				&& parent.strings.suffix.slice(0,1) === parent.blobs.slice(-1)) {
3257				parent.strings.suffix = parent.strings.suffix.slice(1);
3258			}
3259			return;
3260		} else if ("object" !== typeof parent || "object" !== typeof parent.blobs || !parent.blobs.length) {
3261			return;
3262		}
3263		var parentDecorations = blobHasDecorations(parent,true);
3264		for (var i=parent.blobs.length-1;i>-1;i--) {
3265			var endFlag = i === (parent.blobs.length-1);
3266			this.upward(parent.blobs[i]);
3267			var parentStrings = parent.strings;
3268			var childStrings = parent.blobs[i].strings;
3269			if (i === 0) {
3270				if (" " === parentStrings.prefix.slice(-1) && " " === childStrings.prefix.slice(0, 1)) {
3271					childStrings.prefix = childStrings.prefix.slice(1);
3272				}
3273				var childChar = childStrings.prefix.slice(0, 1);
3274				if (!parentDecorations && PUNCT_OR_SPACE[childChar] && !parentStrings.prefix) {
3275					parentStrings.prefix += childChar;
3276					childStrings.prefix = childStrings.prefix.slice(1);
3277				}
3278			}
3279			if (i === (parent.blobs.length - 1)) {
3280				var childChar = childStrings.suffix.slice(-1);
3281				if (!parentDecorations && [" "].indexOf(childChar) > -1) {
3282					if (parentStrings.suffix.slice(0,1) !== childChar) {
3283						parentStrings.suffix = childChar + parentStrings.suffix;
3284					}
3285					childStrings.suffix = childStrings.suffix.slice(0, -1);
3286				}
3287			}
3288			if (parentStrings.delimiter && i > 0) {
3289				if (PUNCT_OR_SPACE[parentStrings.delimiter.slice(-1)]
3290					&& parentStrings.delimiter.slice(-1) === childStrings.prefix.slice(0, 1)) {
3291					childStrings.prefix = childStrings.prefix.slice(1);
3292				}
3293			}
3294		}
3295	};
3296	function leftward (parent) {
3297		if ("object" !== typeof parent || "object" !== typeof parent.blobs || !parent.blobs.length) {
3298			return;
3299		}
3300		for (var i=parent.blobs.length-1;i>-1;i--) {
3301			this.leftward(parent.blobs[i]);
3302			if ((i < parent.blobs.length -1) && !parent.strings.delimiter) {
3303				var child = parent.blobs[i];
3304				var childChar = child.strings.suffix.slice(-1);
3305				var sibling = parent.blobs[i+1];
3306				var siblingChar = sibling.strings.prefix.slice(0, 1);
3307				var hasDecorations = blobHasDecorations(child) || blobHasDecorations(sibling);
3308				var hasNumber = "number" === typeof childChar || "number" === typeof siblingChar;
3309				if (!hasDecorations && !hasNumber && PUNCT[siblingChar] && !hasNumber) {
3310					var suffixAndPrefixMatch = siblingChar === child.strings.suffix.slice(-1);
3311					var suffixAndFieldMatch = (!child.strings.suffix && "string" === typeof child.blobs && child.blobs.slice(-1) === siblingChar);
3312					if (!suffixAndPrefixMatch && !suffixAndFieldMatch) {
3313						mergeChars(child, 'suffix', sibling, 'prefix');
3314					} else {
3315						sibling.strings.prefix = sibling.strings.prefix.slice(1);
3316					}
3317				}
3318			}
3319		}
3320	};
3321	function downward (parent, top) {
3322		if (parent.blobs && "string" == typeof parent.blobs) {
3323			if (PUNCT[parent.strings.suffix.slice(0,1)]
3324				&& parent.strings.suffix.slice(0,1) === parent.blobs.slice(-1)) {
3325				parent.strings.suffix = parent.strings.suffix.slice(1);
3326			}
3327			return;
3328		} else if ("object" !== typeof parent || "object" !== typeof parent.blobs || !parent.blobs.length) {
3329			return;
3330		}
3331		var parentStrings = parent.strings;
3332		var someChildrenAreNumbers = false;
3333		for (var i=0,ilen=parent.blobs.length;i<ilen;i++) {
3334			if (blobIsNumber(parent.blobs[i])) {
3335				someChildrenAreNumbers = true;
3336				break;
3337			}
3338		}
3339		if (!someChildrenAreNumbers) {
3340			if (parentStrings.delimiter && PUNCT[parentStrings.delimiter.slice(0, 1)]) {
3341				var delimChar = parentStrings.delimiter.slice(0, 1);
3342				for (var i=parent.blobs.length-2;i>-1;i--) {
3343					var childStrings = parent.blobs[i].strings;
3344					if (childStrings.suffix.slice(-1) !== delimChar) {
3345						childStrings.suffix += delimChar;
3346					}
3347				}
3348				parentStrings.delimiter = parentStrings.delimiter.slice(1);
3349			}
3350		}
3351		var parentDecorations = blobHasDecorations(parent, true);
3352		var parentIsNumber = blobIsNumber(parent);
3353		for (var i=parent.blobs.length-1;i>-1;i--) {
3354			var child = parent.blobs[i];
3355			var childStrings = parent.blobs[i].strings;
3356			var childDecorations = blobHasDecorations(child, true);
3357			var childIsNumber = blobIsNumber(child);
3358			if (i === (parent.blobs.length - 1)) {
3359				if (true || !someChildrenAreNumbers) {
3360					var parentChar = parentStrings.suffix.slice(0, 1);
3361					var allowMigration = blobHasDescendantQuotes(child);
3362					if (!allowMigration && PUNCT[parentChar]) {
3363						allowMigration = blobHasDescendantMergingPunctuation(parentChar,child);
3364					}
3365					if (allowMigration) {
3366						if (PUNCT[parentChar]) {
3367							if (!blobEndsInNumber(child)) {
3368								if ("string" === typeof child.blobs) {
3369									mergeChars(child, 'blobs', parent, 'suffix');
3370								} else {
3371									mergeChars(child, 'suffix', parent, 'suffix');
3372								}
3373								if (parentStrings.suffix.slice(0,1) === ".") {
3374									childStrings.suffix += parentStrings.suffix.slice(0,1);
3375									parentStrings.suffix = parentStrings.suffix.slice(1);
3376								}
3377							}
3378						}
3379					}
3380					if (childStrings.suffix.slice(-1) === " " && parentStrings.suffix.slice(0,1) === " ") {
3381						parentStrings.suffix = parentStrings.suffix.slice(1);
3382					}
3383					if (PUNCT_OR_SPACE[childStrings.suffix.slice(0,1)]) {
3384						if ("string" === typeof child.blobs && child.blobs.slice(-1) === childStrings.suffix.slice(0,1)) {
3385							childStrings.suffix = childStrings.suffix.slice(1);
3386						}
3387						if (childStrings.suffix.slice(-1) === parentStrings.suffix.slice(0, 1)) {
3388							parentStrings.suffix = parentStrings.suffix.slice(0, -1);
3389						}
3390					}
3391				}
3392				if (matchLastChar(parent,parent.strings.suffix.slice(0,1))) {
3393					parent.strings.suffix = parent.strings.suffix.slice(1);
3394				}
3395			} else if (parentStrings.delimiter) {
3396				if (PUNCT_OR_SPACE[parentStrings.delimiter.slice(0,1)]
3397					&& parentStrings.delimiter.slice(0, 1) === childStrings.suffix.slice(-1)) {
3398					parent.blobs[i].strings.suffix = parent.blobs[i].strings.suffix.slice(0, -1);
3399				}
3400			} else {
3401				var siblingStrings = parent.blobs[i+1].strings;
3402				if (!blobIsNumber(child)
3403					&& !childDecorations
3404					&& PUNCT_OR_SPACE[childStrings.suffix.slice(-1)]
3405					&& childStrings.suffix.slice(-1) === siblingStrings.prefix.slice(0, 1)) {
3406					siblingStrings.prefix = siblingStrings.prefix.slice(1);
3407				}
3408			}
3409			if (!childIsNumber && !childDecorations && PUNCT[childStrings.suffix.slice(0,1)]
3410				&& "string" === typeof child.blobs) {
3411				mergeChars(child, 'blobs', child, 'suffix')
3412			}
3413			this.downward(parent.blobs[i]);
3414		}
3415	};
3416	function swapToTheLeft (child) {
vendor: 4,320 bytes, lines 3417-3601
3417		var childChar = child.strings.suffix.slice(0,1);
3418		if ("string" === typeof child.blobs) {
3419			while (SWAP_IN[childChar]) {
3420				mergeChars(child, 'blobs', child, 'suffix');
3421				childChar = child.strings.suffix.slice(0,1);
3422			}
3423		} else {
3424			while (SWAP_IN[childChar]) {
3425				mergeChars(child.blobs[child.blobs.length-1], 'suffix', child, 'suffix');
3426				childChar = child.strings.suffix.slice(0,1);
3427			}
3428		}
3429	}
3430	function swapToTheRight (child) {
3431		if ("string" === typeof child.blobs) {
3432			var childChar = child.blobs.slice(-1);
3433			while (SWAP_OUT[childChar]) {
3434				mergeChars(child, 'blobs', child, 'suffix', true);
3435				childChar = child.blobs.slice(-1);
3436			}
3437		} else {
3438			var childChar = child.blobs[child.blobs.length-1].strings.suffix.slice(-1);
3439			while (SWAP_OUT[childChar]) {
3440				mergeChars(child.blobs[child.blobs.length-1], 'suffix', child, 'suffix', true);
3441				childChar = child.blobs[child.blobs.length-1].strings.suffix.slice(-1);
3442			}
3443		}
3444	}
3445	function fix (parent) {
3446		if ("object" !== typeof parent || "object" !== typeof parent.blobs || !parent.blobs.length) {
3447			return;
3448		}
3449		var lastChar;
3450		for (var i=0,ilen=parent.blobs.length;i<ilen;i++) {
3451			var child = parent.blobs[i];
3452			var quoteSwap = false;
3453			for (var j=0,jlen=child.decorations.length;j<jlen;j++) {
3454				var decoration = child.decorations[j];
3455				if (decoration[0] === "@quotes") {
3456					quoteSwap = true;
3457				}
3458			}
3459			if (quoteSwap) {
3460				if (punctInQuote) {
3461					swapToTheLeft(child);
3462				} else {
3463					swapToTheRight(child);
3464				}
3465			}
3466			lastChar = this.fix(parent.blobs[i]);
3467			if (child.blobs && "string" === typeof child.blobs) {
3468				lastChar = child.blobs.slice(-1);
3469			}
3470		}
3471		return lastChar;
3472	};
3473}
3474CSL.Engine.Opt = function () {
3475	this.has_disambiguate = false;
3476	this.mode = "html";
3477	this.dates = {};
3478	this["locale-sort"] = [];
3479	this["locale-translit"] = [];
3480	this["locale-translat"] = [];
3481	this.citeAffixes = {
3482		persons:{
3483			"locale-orig":{
3484				prefix:"",
3485				suffix:""
3486			},
3487			"locale-translit":{
3488				prefix:"",
3489				suffix:""
3490			},
3491			"locale-translat":{
3492				prefix:"",
3493				suffix:""
3494			}
3495		},
3496		institutions:{
3497			"locale-orig":{
3498				prefix:"",
3499				suffix:""
3500			},
3501			"locale-translit":{
3502				prefix:"",
3503				suffix:""
3504			},
3505			"locale-translat":{
3506				prefix:"",
3507				suffix:""
3508			}
3509		},
3510		titles:{
3511			"locale-orig":{
3512				prefix:"",
3513				suffix:""
3514			},
3515			"locale-translit":{
3516				prefix:"",
3517				suffix:""
3518			},
3519			"locale-translat":{
3520				prefix:"",
3521				suffix:""
3522			}
3523		},
3524		journals:{
3525			"locale-orig":{
3526				prefix:"",
3527				suffix:""
3528			},
3529			"locale-translit":{
3530				prefix:"",
3531				suffix:""
3532			},
3533			"locale-translat":{
3534				prefix:"",
3535				suffix:""
3536			}
3537		},
3538		publishers:{
3539			"locale-orig":{
3540				prefix:"",
3541				suffix:""
3542			},
3543			"locale-translit":{
3544				prefix:"",
3545				suffix:""
3546			},
3547			"locale-translat":{
3548				prefix:"",
3549				suffix:""
3550			}
3551		},
3552		places:{
3553			"locale-orig":{
3554				prefix:"",
3555				suffix:""
3556			},
3557			"locale-translit":{
3558				prefix:"",
3559				suffix:""
3560			},
3561			"locale-translat":{
3562				prefix:"",
3563				suffix:""
3564			}
3565		}
3566	};
3567	this["default-locale"] = [];
3568	this.update_mode = CSL.NONE;
3569	this.bib_mode = CSL.NONE;
3570	this.sort_citations = false;
3571	this["et-al-min"] = 0;
3572	this["et-al-use-first"] = 1;
3573	this["et-al-use-last"] = false;
3574	this["et-al-subsequent-min"] = false;
3575	this["et-al-subsequent-use-first"] = false;
3576	this["demote-non-dropping-particle"] = "display-and-sort";
3577	this["parse-names"] = true;
3578	this.citation_number_slug = false;
3579	this.trigraph = "Aaaa00:AaAa00:AaAA00:AAAA00";
3580	this.nodenames = [];
3581	this.gender = {};
3582	this['cite-lang-prefs'] = {
3583		persons:['orig'],
3584		institutions:['orig'],
3585		titles:['orig','translat'],
3586		journals:['translit'],
3587		publishers:['orig'],
3588		places:['orig'],
3589		number:['translat']
3590	};
3591	this.has_layout_locale = false;
3592	this.development_extensions = {};
3593	this.development_extensions.field_hack = true;
3594	this.development_extensions.locator_date_and_revision = true;
3595	this.development_extensions.locator_parsing_for_plurals = true;
3596	this.development_extensions.locator_label_parse = true;
3597	this.development_extensions.raw_date_parsing = true;
3598	this.development_extensions.clean_up_csl_flaws = true;
3599	this.development_extensions.flip_parentheses_to_braces = true;
3600	this.development_extensions.jurisdiction_subfield = true;
3601	this.development_extensions.static_statute_locator = false;
3602	this.development_extensions.csl_reverse_lookup_support = false;
3603	this.development_extensions.clobber_locator_if_no_statute_section = false;
3604	this.development_extensions.wrap_url_and_doi = false;
3605	this.development_extensions.allow_force_lowercase = false;
3606	this.development_extensions.handle_parallel_articles = false;
3607	this.development_extensions.thin_non_breaking_space_html_hack = false;
3608	this.development_extensions.apply_citation_wrapper = false;
3609	this.development_extensions.main_title_from_short_title = false;
3610	this.development_extensions.uppercase_subtitles = false;
3611	this.development_extensions.normalize_lang_keys_to_lowercase = false;
3612	this.development_extensions.strict_text_case_locales = false;
3613	this.development_extensions.rtl_support = false;
3614	this.development_extensions.strict_page_numbers = false;
3615	this.development_extensions.expect_and_symbol_form = false;
3616	this.development_extensions.require_explicit_legal_case_title_short = false;
3617};
3618CSL.Engine.Tmp = function () {
3619	this.names_max = new CSL.Stack();
3620	this.names_base = new CSL.Stack();
3621	this.givens_base = new CSL.Stack();
3622	this.value = [];
3623	this.namepart_decorations = {};
3624	this.namepart_type = false;
vendor: 4,498 bytes, lines 3625-3764
3625	this.area = "citation";
3626	this.root = "citation";
3627	this.extension = "";
3628	this.can_substitute = new CSL.Stack(0, CSL.LITERAL);
3629	this.element_rendered_ok = false;
3630	this.element_trace = new CSL.Stack("style");
3631	this.nameset_counter = 0;
3632	this.group_context = new CSL.Stack([false, false, false], CSL.LITERAL);
3633	this.term_predecessor = false;
3634	this.jump = new CSL.Stack(0, CSL.LITERAL);
3635	this.decorations = new CSL.Stack();
3636	this.tokenstore_stack = new CSL.Stack();
3637	this.last_suffix_used = "";
3638	this.last_names_used = [];
3639	this.last_years_used = [];
3640	this.years_used = [];
3641	this.names_used = [];
3642	this.taintedItemIDs = {};
3643	this.taintedCitationIDs = {};
3644	this.initialize_with = new CSL.Stack();
3645	this.disambig_request = false;
3646	this["name-as-sort-order"] = false;
3647	this.suppress_decorations = false;
3648	this.disambig_settings = new CSL.AmbigConfig();
3649	this.bib_sort_keys = [];
3650	this.prefix = new CSL.Stack("", CSL.LITERAL);
3651	this.suffix = new CSL.Stack("", CSL.LITERAL);
3652	this.delimiter = new CSL.Stack("", CSL.LITERAL);
3653	this.cite_locales = [];
3654	this.cite_affixes = {
3655		citation: false,
3656		bibliography: false,
3657		citation_sort: false,
3658		bibliography_sort: false
3659	};
3660	this.strip_periods = 0;
3661	this.shadow_numbers = {};
3662};
3663CSL.Engine.Fun = function (state) {
3664	this.match = new CSL.Util.Match;
3665	this.suffixator = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS);
3666	this.romanizer = new CSL.Util.Romanizer();
3667	this.ordinalizer = new CSL.Util.Ordinalizer(state);
3668	this.long_ordinalizer = new CSL.Util.LongOrdinalizer();
3669};
3670CSL.Engine.Build = function () {
3671	this["alternate-term"] = false;
3672	this.in_bibliography = false;
3673	this.in_style = false;
3674	this.skip = false;
3675	this.postponed_macro = false;
3676	this.layout_flag = false;
3677	this.name = false;
3678	this.form = false;
3679	this.term = false;
3680	this.macro = {};
3681	this.macro_stack = [];
3682	this.text = false;
3683	this.lang = false;
3684	this.area = "citation";
3685	this.root = "citation";
3686	this.extension = "";
3687	this.substitute_level = new CSL.Stack(0, CSL.LITERAL);
3688	this.names_level = 0;
3689	this.render_nesting_level = 0;
3690	this.render_seen = false;
3691};
3692CSL.Engine.Configure = function () {
3693	this.fail = [];
3694	this.succeed = [];
3695};
3696CSL.Engine.Citation = function (state) {
3697	this.opt = {};
3698	this.tokens = [];
3699	this.srt = new CSL.Registry.Comparifier(state, "citation_sort");
3700	this.opt.collapse = [];
3701	this.opt["disambiguate-add-names"] = false;
3702	this.opt["disambiguate-add-givenname"] = false;
3703	this.opt["disambiguate-add-year-suffix"] = false;
3704	this.opt["givenname-disambiguation-rule"] = "by-cite";
3705	this.opt["near-note-distance"] = 5;
3706	this.opt.topdecor = [];
3707	this.opt.layout_decorations = [];
3708	this.opt.layout_prefix = "";
3709	this.opt.layout_suffix = "";
3710	this.opt.layout_delimiter = "";
3711	this.opt.sort_locales = [];
3712	this.opt.max_number_of_names = 0;
3713	this.root = "citation";
3714};
3715CSL.Engine.Bibliography = function () {
3716	this.opt = {};
3717	this.tokens = [];
3718	this.opt.collapse = [];
3719	this.opt.topdecor = [];
3720	this.opt.layout_decorations = [];
3721	this.opt.layout_prefix = "";
3722	this.opt.layout_suffix = "";
3723	this.opt.layout_delimiter = "";
3724	this.opt["line-spacing"] = 1;
3725	this.opt["entry-spacing"] = 1;
3726	this.opt.sort_locales = [];
3727	this.opt.max_number_of_names = 0;
3728	this.root = "bibliography";
3729};
3730CSL.Engine.BibliographySort = function () {
3731	this.tokens = [];
3732	this.opt = {};
3733	this.opt.sort_directions = [];
3734	this.keys = [];
3735	this.opt.topdecor = [];
3736	this.root = "bibliography";
3737};
3738CSL.Engine.CitationSort = function () {
3739	this.tokens = [];
3740	this.opt = {};
3741	this.opt.sort_directions = [];
3742	this.keys = [];
3743	this.opt.topdecor = [];
3744	this.root = "citation";
3745};
3746CSL.Engine.prototype.previewCitationCluster = function (citation, citationsPre, citationsPost, newMode) {
3747	var oldMode = this.opt.mode;
3748	this.setOutputFormat(newMode);
3749	var ret = this.processCitationCluster(citation, citationsPre, citationsPost, CSL.PREVIEW);
3750	this.setOutputFormat(oldMode);
3751	return ret[1];
3752};
3753CSL.Engine.prototype.appendCitationCluster = function (citation) {
3754	var citationsPre = [];
3755	var len = this.registry.citationreg.citationByIndex.length;
3756	for (var pos = 0; pos < len; pos += 1) {
3757		var c = this.registry.citationreg.citationByIndex[pos];
3758		citationsPre.push(["" + c.citationID, c.properties.noteIndex]);
3759	}
3760	return this.processCitationCluster(citation, citationsPre, [])[1];
3761};
3762CSL.Engine.prototype.processCitationCluster = function (citation, citationsPre, citationsPost, flag) {
3763	var c, i, ilen, j, jlen, k, klen, n, nlen, key, Item, item, noteCitations, textCitations, m, citationsInNote;
3764	this.debug = false;
3765	this.tmp.citation_errors = [];
3766	var return_data = {"bibchange": false};
3767	this.setCitationId(citation);
3768	var oldCitationList;
3769	var oldItemList;
3770	var oldAmbigs;
3771	if (flag === CSL.PREVIEW) {
3772		oldCitationList = this.registry.citationreg.citationByIndex.slice();
3773		oldItemList = this.registry.reflist.slice();
3774		var newCitationList = citationsPre.concat([["" + citation.citationID, citation.properties.noteIndex]]).concat(citationsPost);
3775		var newItemIds = {};
3776		var newItemIdsList = [];
3777		for (i = 0, ilen = newCitationList.length; i < ilen; i += 1) {
3778			c = this.registry.citationreg.citationById[newCitationList[i][0]];
3779			for (j = 0, jlen = c.citationItems.length; j < jlen; j += 1) {
3780				newItemIds[c.citationItems[j].id] = true;
3781				newItemIdsList.push("" + c.citationItems[j].id);
3782			}
3783		}
3784		oldAmbigs = {};
3785		for (i = 0, ilen = oldItemList.length; i < ilen; i += 1) {
3786			if (!newItemIds[oldItemList[i].id]) {
3787				var oldAkey = this.registry.registry[oldItemList[i].id].ambig;
3788				var ids = this.registry.ambigcites[oldAkey];
3789				if (ids) {
3790					for (j = 0, jlen = ids.length; j < jlen; j += 1) {
3791						oldAmbigs[ids[j]] = CSL.cloneAmbigConfig(this.registry.registry[ids[j]].disambig);
3792					}
3793				}
3794			}
3795		}
3796	}
3797	this.tmp.taintedCitationIDs = {};
3798	var sortedItems = [];
3799	var rerunAkeys = {};
3800	for (i = 0, ilen = citation.citationItems.length; i < ilen; i += 1) {
3801		item = {};
3802		for (key in citation.citationItems[i]) {
3803			item[key] = citation.citationItems[i][key];
3804		}
3805		Item = this.retrieveItem("" + item.id);
3806		if (Item.id) {
3807			this.transform.loadAbbreviation("default", "hereinafter", Item.id);
3808		}
3809		this.remapSectionVariable([[Item,item]]);
3810		if (this.opt.development_extensions.locator_date_and_revision) {
3811			if (item.locator) {
3812				item.locator = "" + item.locator;
3813				var idx = item.locator.indexOf("|");
3814				if (idx > -1) {
3815					var raw_locator = item.locator;
3816					item.locator = raw_locator.slice(0, idx);
3817					raw_locator = raw_locator.slice(idx + 1);
3818					m = raw_locator.match(/^([0-9]{4}-[0-9]{2}-[0-9]{2}).*/);
3819					if (m) {
3820						item["locator-date"] = this.fun.dateparser.parse(m[1]);
3821						raw_locator = raw_locator.slice(m[1].length);
3822					}
3823					item["locator-revision"] = raw_locator.replace(/^\s+/, "").replace(/\s+$/, "");
3824				}
3825			}
3826		}
3827		if (this.opt.development_extensions.locator_label_parse) {
3828			if (item.locator && ["bill","gazette","legislation","treaty"].indexOf(Item.type) === -1 && (!item.label || item.label === 'page')) {
3829				m = CSL.LOCATOR_LABELS_REGEXP.exec(item.locator);
3830				if (m) {
3831					item.label = CSL.LOCATOR_LABELS_MAP[m[2]];
3832					item.locator = m[3];
3833				}
3834			}
3835		}
3836		var newitem = [Item, item];
3837		sortedItems.push(newitem);
3838		citation.citationItems[i].item = Item;
3839	}
3840	citation.sortedItems = sortedItems;
3841	var citationByIndex = [];
3842	for (i = 0, ilen = citationsPre.length; i < ilen; i += 1) {
3843		c = citationsPre[i];
3844		this.registry.citationreg.citationById[c[0]].properties.noteIndex = c[1];
3845		citationByIndex.push(this.registry.citationreg.citationById[c[0]]);
3846	}
3847	citationByIndex.push(citation);
3848	for (i = 0, ilen = citationsPost.length; i < ilen; i += 1) {
3849		c = citationsPost[i];
3850		this.registry.citationreg.citationById[c[0]].properties.noteIndex = c[1];
3851		citationByIndex.push(this.registry.citationreg.citationById[c[0]]);
3852	}
3853	this.registry.citationreg.citationByIndex = citationByIndex;
3854	this.registry.citationreg.citationsByItemId = {};
3855	if (this.opt.update_mode === CSL.POSITION) {
3856		textCitations = [];
3857		noteCitations = [];
3858		citationsInNote = {};
3859	}
3860	var update_items = [];
3861	for (i = 0, ilen = citationByIndex.length; i < ilen; i += 1) {
3862		citationByIndex[i].properties.index = i;
3863		for (j = 0, jlen = citationByIndex[i].sortedItems.length; j < jlen; j += 1) {
3864			item = citationByIndex[i].sortedItems[j];
3865			if (!this.registry.citationreg.citationsByItemId[item[1].id]) {
3866				this.registry.citationreg.citationsByItemId[item[1].id] = [];
3867				update_items.push("" + item[1].id);
3868			}
3869			if (this.registry.citationreg.citationsByItemId[item[1].id].indexOf(citationByIndex[i]) === -1) {
3870				this.registry.citationreg.citationsByItemId[item[1].id].push(citationByIndex[i]);
3871			}
3872		}
3873		if (this.opt.update_mode === CSL.POSITION) {
3874			if (citationByIndex[i].properties.noteIndex) {
3875				noteCitations.push(citationByIndex[i]);
3876			} else {
3877				citationByIndex[i].properties.noteIndex = 0;
3878				textCitations.push(citationByIndex[i]);
3879			}
3880		}
3881	}
3882	if (flag !== CSL.ASSUME_ALL_ITEMS_REGISTERED) {
3883		this.updateItems(update_items);
3884	}
3885	if (!this.opt.citation_number_sort && sortedItems && sortedItems.length > 1 && this.citation_sort.tokens.length > 0) {
3886		for (i = 0, ilen = sortedItems.length; i < ilen; i += 1) {
3887			sortedItems[i][1].sortkeys = CSL.getSortKeys.call(this, sortedItems[i][0], "citation_sort");
3888		}
3889		if (this.opt.grouped_sort &&  !citation.properties.unsorted) {
3890			for (i = 0, ilen = sortedItems.length; i < ilen; i += 1) {
3891				var sortkeys = sortedItems[i][1].sortkeys;
3892				this.tmp.authorstring_request = true;
3893				var mydisambig = this.registry.registry[sortedItems[i][0].id].disambig;
3894				this.tmp.authorstring_request = true;
3895				CSL.getAmbiguousCite.call(this, sortedItems[i][0], mydisambig);
3896				var authorstring = this.registry.authorstrings[sortedItems[i][0].id];
3897				this.tmp.authorstring_request = false;
3898				sortedItems[i][1].sortkeys = [authorstring].concat(sortkeys);
3899			}
3900			sortedItems.sort(this.citation.srt.compareCompositeKeys);
3901			var lastauthor = false;
3902			var thiskey = false;
3903			var thisauthor = false;
3904			for (i = 0, ilen = sortedItems.length; i < ilen; i += 1) {
3905				if (sortedItems[i][1].sortkeys[0] !== lastauthor) {
3906					thisauthor = sortedItems[i][1].sortkeys[0];
3907					thiskey =  sortedItems[i][1].sortkeys[1];
3908				}
3909				sortedItems[i][1].sortkeys[0] = "" + thiskey + i;
3910				lastauthor = thisauthor;
3911			}
3912		}
3913		if (!citation.properties.unsorted) {
3914			sortedItems.sort(this.citation.srt.compareCompositeKeys);
3915		}
3916	}
3917	var citations;
3918	if (this.opt.update_mode === CSL.POSITION) {
3919		for (i = 0; i < 2; i += 1) {
3920			citations = [textCitations, noteCitations][i];
3921			var first_ref = {};
3922			var last_ref = {};
3923			for (j = 0, jlen = citations.length; j < jlen; j += 1) {
3924				var onecitation = citations[j];
3925				if (!citations[j].properties.noteIndex) {
3926					citations[j].properties.noteIndex = 0;
3927				}
3928				citations[j].properties.noteIndex = parseInt(citations[j].properties.noteIndex, 10);
3929				if (j > 0 && citations[j - 1].properties.noteIndex > citations[j].properties.noteIndex) {
3930					citationsInNote = {};
3931					first_ref = {};
3932					last_ref = {};
3933				}
3934				for (k = 0, klen = onecitation.sortedItems.length; k < klen; k += 1) {
3935					if (!this.registry.registry[onecitation.sortedItems[k][1].id].parallel) {
3936						if (!citationsInNote[onecitation.properties.noteIndex]) {
3937							citationsInNote[onecitation.properties.noteIndex] = 1;
3938						} else {
3939							citationsInNote[onecitation.properties.noteIndex] += 1;
3940						}
3941					}
3942				}
3943				for (k = 0, klen = citations[j].sortedItems.length; k < klen; k += 1) {
3944					item = citations[j].sortedItems[k];
3945					var myid = item[0].id;
3946					var mylocator = item[1].locator;
3947					var mylabel = item[1].label;
3948					if (item[0].legislation_id) {
3949						myid = item[0].legislation_id;
3950					}
3951					var incitationid;
3952					if (k > 0) {
3953						if (onecitation.sortedItems[k - 1][0].legislation_id) {
3954							incitationid = onecitation.sortedItems[k - 1][0].legislation_id;
3955						} else {
3956							incitationid = onecitation.sortedItems[k - 1][1].id;
3957						}
3958					}
3959					if (flag === CSL.PREVIEW) {
3960						if (onecitation.citationID != citation.citationID) {
3961							if ("undefined" === typeof first_ref[item[1].id]) {
3962								first_ref[myid] = onecitation.properties.noteIndex;
3963								last_ref[myid] = onecitation.properties.noteIndex;
3964							} else {
3965								last_ref[myid] = onecitation.properties.noteIndex;
3966							}
3967							continue;
3968						}
3969					}
3970					var oldvalue = {};
3971					oldvalue.position = item[1].position;
3972					oldvalue["first-reference-note-number"] = item[1]["first-reference-note-number"];
3973					oldvalue["near-note"] = item[1]["near-note"];
3974					item[1]["first-reference-note-number"] = 0;
3975					item[1]["near-note"] = false;
3976					if (this.registry.citationreg.citationsByItemId[myid]) {
3977						if (this.opt.xclass === 'note' && this.opt.has_disambiguate) {
3978							var oldCount = this.registry.registry[myid]["citation-count"]
3979							var newCount = this.registry.citationreg.citationsByItemId[myid].length;
3980							this.registry.registry[myid]["citation-count"] = this.registry.citationreg.citationsByItemId[myid].length;
3981							if ("number" === typeof oldCount) {
3982								var oldCountCheck = (oldCount < 2);
3983								var newCountCheck = (newCount < 2);
3984								if (oldCountCheck !== newCountCheck) {
3985									for (var l=0,llen=this.registry.citationreg.citationsByItemId[myid].length;l<llen;l++) {
3986										rerunAkeys[this.registry.registry[myid].ambig] = true;
3987										this.tmp.taintedCitationIDs[this.registry.citationreg.citationsByItemId[myid][l].citationID] = true;
3988									}
3989								}
3990							} else {
3991								for (var l=0,llen=this.registry.citationreg.citationsByItemId[myid].length;l<llen;l++) {
3992									rerunAkeys[this.registry.registry[myid].ambig] = true;
3993									this.tmp.taintedCitationIDs[this.registry.citationreg.citationsByItemId[myid][l].citationID] = true;
3994								}
3995							}
3996						}
3997					}
3998					var oldlastid;
3999					if ("undefined" === typeof first_ref[myid]) {
4000						first_ref[myid] = onecitation.properties.noteIndex;
4001						if (this.registry.registry[myid]) {
4002							this.registry.registry[myid]['first-reference-note-number'] = onecitation.properties.noteIndex;
4003						}
4004						last_ref[myid] = onecitation.properties.noteIndex;
4005						item[1].position = CSL.POSITION_FIRST;
4006					} else {
4007						var ibidme = false;
4008						var suprame = false;
4009						if (j > 0) {
4010							oldlastid =  citations[j - 1].sortedItems.slice(-1)[0][1].id;
4011							if (citations[j - 1].sortedItems[0].slice(-1)[0].legislation_id) {
4012								oldlastid = citations[j - 1].sortedItems[0].slice(-1)[0].legislation_id;
4013							}
4014						}
4015						if (j > 0 && parseInt(k, 10) === 0 && citations[j - 1].properties.noteIndex !== citations[j].properties.noteIndex) {
4016							var items = citations[(j - 1)].sortedItems;
4017							var useme = false;
4018							var oldid = citations[j - 1].sortedItems[0][0].id;
4019							if (citations[j - 1].sortedItems[0][0].legislation_id) {
4020								oldid = citations[j - 1].sortedItems[0][0].legislation_id;
4021							}
4022							if ((oldid  == myid && citations[j - 1].properties.noteIndex >= (citations[j].properties.noteIndex - 1)) || citations[j - 1].sortedItems[0][1].id == this.registry.registry[item[1].id].parallel) {
4023								if (citationsInNote[citations[j - 1].properties.noteIndex] === 1 || citations[j - 1].properties.noteIndex === 0) {
4024									useme = true;
4025								}
4026							}
4027							for (n = 0, nlen = items.slice(1).length; n < nlen; n += 1) {
4028								var itmp = items.slice(1)[n];
4029								if (!this.registry.registry[itmp[1].id].parallel || this.registry.registry[itmp[1].id].parallel == this.registry.registry[itmp[1].id]) {
4030									useme = false;
4031								}
4032							}
4033							if (useme) {
4034								ibidme = true;
4035							} else {
4036								suprame = true;
4037							}
4038						} else if (k > 0 && incitationid == myid) {
4039							ibidme = true;
4040						} else if (k === 0 && citations[j - 1].properties.noteIndex == citations[j].properties.noteIndex
4041									 && citations[j - 1].sortedItems.length
4042									 && oldlastid == myid) {
4043							ibidme = true;
4044						} else {
4045							suprame = true;
4046						}
4047						var prev, prev_locator, prev_label, curr_locator, curr_label;
4048						if (ibidme) {
4049							if (k > 0) {
4050								prev = onecitation.sortedItems[(k - 1)][1];
4051							} else {
4052								prev = citations[(j - 1)].sortedItems[0][1];
4053							}
4054							if (prev.locator) {
4055								if (prev.label) {
4056									prev_label = prev.label;
4057								} else {
4058									prev_label = "";
4059								}
4060								prev_locator = "" + prev.locator + prev_label;
4061							} else {
4062								prev_locator = prev.locator;
4063							}
4064							if (mylocator) {
4065								if (mylabel) {
4066									curr_label = mylabel;
4067								} else {
4068									curr_label = "";
4069								}
4070								curr_locator = "" + mylocator + curr_label;
4071							} else {
4072								curr_locator = mylocator;
4073							}
4074						}
4075						if (ibidme && prev_locator && !curr_locator) {
4076							ibidme = false;
4077							suprame = true;
4078						}
4079						if (ibidme) {
4080							if (!prev_locator && curr_locator) {
4081								item[1].position = CSL.POSITION_IBID_WITH_LOCATOR;
4082							} else if (!prev_locator && !curr_locator) {
4083								item[1].position = CSL.POSITION_IBID;
4084							} else if (prev_locator && curr_locator === prev_locator) {
4085								item[1].position = CSL.POSITION_IBID;
4086							} else if (prev_locator && curr_locator && curr_locator !== prev_locator) {
4087								item[1].position = CSL.POSITION_IBID_WITH_LOCATOR;
4088							} else {
4089								ibidme = false; // just to be clear
4090								suprame = true;
4091							}
4092						}
4093						if (suprame) {
4094							item[1].position = CSL.POSITION_SUBSEQUENT;
4095						}
4096						if (suprame || ibidme) {
4097							if (first_ref[myid] != onecitation.properties.noteIndex) {
4098								item[1]["first-reference-note-number"] = first_ref[myid];
4099								if (this.registry.registry[myid]) {
4100									var oldFirst = this.registry.citationreg.citationsByItemId[myid][0].properties.noteIndex;
4101									var newFirst = onecitation.properties.noteIndex;
4102									this.registry.registry[myid]['first-reference-note-number'] = newFirst < oldFirst ? newFirst: oldFirst;
4103								}
4104							}
4105						}
4106					}
4107					if (onecitation.properties.noteIndex) {
4108						var note_distance = parseInt(onecitation.properties.noteIndex, 10) - parseInt(last_ref[myid], 10);
4109						if (item[1].position !== CSL.POSITION_FIRST
4110							&& note_distance <= this.citation.opt["near-note-distance"]) {
4111							item[1]["near-note"] = true;
4112						}
4113						last_ref[myid] = onecitation.properties.noteIndex;
4114					}
4115					if (onecitation.citationID != citation.citationID) {
4116						for (n = 0, nlen = CSL.POSITION_TEST_VARS.length; n < nlen; n += 1) {
4117							var param = CSL.POSITION_TEST_VARS[n];
4118							if (item[1][param] !== oldvalue[param]) {
4119								if (param === 'first-reference-note-number') {
4120									rerunAkeys[this.registry.registry[myid].ambig] = true;
4121								}
4122								this.tmp.taintedCitationIDs[onecitation.citationID] = true;
4123								if (param === 'first-reference-note-number') {
4124									this.tmp.taintedItemIDs[myid] = true;
4125								}
4126							}
4127						}
4128					}
4129					if (this.sys.variableWrapper) {
4130						item[1].index = onecitation.properties.index;
4131						item[1].noteIndex = onecitation.properties.noteIndex;
4132					}
4133				}
4134			}
4135		}
4136	}
4137	if (this.opt.citation_number_sort && sortedItems && sortedItems.length > 1 && this.citation_sort.tokens.length > 0) {
4138		for (i = 0, ilen = sortedItems.length; i < ilen; i += 1) {
4139			sortedItems[i][1].sortkeys = CSL.getSortKeys.call(this, sortedItems[i][0], "citation_sort");
4140		}
4141		if (!citation.properties.unsorted) {
4142			sortedItems.sort(this.citation.srt.compareCompositeKeys);
4143		}
4144	}
4145	for (key in this.tmp.taintedItemIDs) {
4146		if (this.tmp.taintedItemIDs.hasOwnProperty(key)) {
4147			citations = this.registry.citationreg.citationsByItemId[key];
4148			if (citations) {
4149				for (i = 0, ilen = citations.length; i < ilen; i += 1) {
4150					this.tmp.taintedCitationIDs[citations[i].citationID] = true;
4151				}
4152			}
4153		}
4154	}
4155	var ret = [];
4156	if (flag === CSL.PREVIEW) {
4157		try {
4158			ret = this.process_CitationCluster.call(this, citation.sortedItems, citation.citationID);
4159		} catch (e) {
4160			CSL.error("Error running CSL processor for preview: "+e);
4161		}
4162		this.registry.citationreg.citationByIndex = oldCitationList;
4163		this.registry.citationreg.citationById = {};
4164		for (i = 0, ilen = oldCitationList.length; i < ilen; i += 1) {
4165			this.registry.citationreg.citationById[oldCitationList[i].citationID] = oldCitationList[i];
4166		}
4167		var oldItemIds = [];
4168		for (i = 0, ilen = oldItemList.length; i < ilen; i += 1) {
4169			oldItemIds.push("" + oldItemList[i].id);
4170		}
4171		this.updateItems(oldItemIds);
4172		for (key in oldAmbigs) {
4173			if (oldAmbigs.hasOwnProperty(key)) {
4174				this.registry.registry[key].disambig = oldAmbigs[key];
4175			}
4176		}
4177	} else {
4178		for (var rerunAkey in rerunAkeys) {
4179			this.disambiguate.run(rerunAkey, citation);
4180		}
4181		var obj;
4182		for (key in this.tmp.taintedCitationIDs) {
4183			if (key == citation.citationID) {
4184				continue;
4185			}
4186			var mycitation = this.registry.citationreg.citationById[key];
4187			this.tmp.citation_pos = mycitation.properties.index;
4188			this.tmp.citation_note_index = mycitation.properties.noteIndex;
4189			this.tmp.citation_id = "" + mycitation.citationID;
4190			obj = [];
4191			obj.push(mycitation.properties.index);
4192			obj.push(this.process_CitationCluster.call(this, mycitation.sortedItems, mycitation.citationID));
4193			ret.push(obj);
4194		}
4195		this.tmp.taintedItemIDs = {};
4196		this.tmp.taintedCitationIDs = {};
4197		this.tmp.citation_pos = citation.properties.index;
4198		this.tmp.citation_note_index = citation.properties.noteIndex;
4199		this.tmp.citation_id = "" + citation.citationID;
4200		obj = [];
4201		obj.push(citationsPre.length);
4202		obj.push(this.process_CitationCluster.call(this, sortedItems, citation.citationID));
4203		ret.push(obj);
4204		ret.sort(function (a, b) {
4205			if (a[0] > b[0]) {
4206				return 1;
4207			} else if (a[0] < b[0]) {
4208				return -1;
4209			} else {
4210				return 0;
4211			}
4212		});
4213	}
4214	return_data.citation_errors = this.tmp.citation_errors.slice();
4215	return [return_data, ret];
4216};
4217CSL.Engine.prototype.process_CitationCluster = function (sortedItems, citationID) {
4218	var str;
4219	this.parallel.StartCitation(sortedItems);
4220	str = CSL.getCitationCluster.call(this, sortedItems, citationID);
4221	return str;
4222};
4223CSL.Engine.prototype.makeCitationCluster = function (rawList) {
4224	var inputList, newitem, str, pos, len, item, Item;
4225	inputList = [];
4226	len = rawList.length;
4227	for (pos = 0; pos < len; pos += 1) {
4228		item = {};
4229		for (var key in rawList[pos]) {
4230			item[key] = rawList[pos][key];
4231		}
4232		Item = this.retrieveItem("" + item.id);
4233		if (this.opt.development_extensions.locator_label_parse) {
4234			if (item.locator && ["bill","gazette","legislation","treaty"].indexOf(Item.type) === -1 && (!item.label || item.label === 'page')) {
4235				var m = CSL.LOCATOR_LABELS_REGEXP.exec(item.locator);
4236				if (m) {
4237					item.label = CSL.LOCATOR_LABELS_MAP[m[2]];
4238					item.locator = m[3];
4239				}
4240			}
4241		}
4242		newitem = [Item, item];
4243		inputList.push(newitem);
4244	}
4245	this.remapSectionVariable(inputList);
4246	if (inputList && inputList.length > 1 && this.citation_sort.tokens.length > 0) {
4247		len = inputList.length;
4248		for (pos = 0; pos < len; pos += 1) {
4249			inputList[pos][1].sortkeys = CSL.getSortKeys.call(this, inputList[pos][0], "citation_sort");
4250		}
4251		inputList.sort(this.citation.srt.compareCompositeKeys);
4252	}
4253	this.tmp.citation_errors = [];
4254	this.parallel.StartCitation(inputList);
4255	str = CSL.getCitationCluster.call(this, inputList);
4256	return str;
4257};
4258CSL.getAmbiguousCite = function (Item, disambig, visualForm) {
4259	var use_parallels, ret;
4260	var oldTermSiblingLayer = this.tmp.group_context.value().slice();
4261	if (disambig) {
4262		this.tmp.disambig_request = disambig;
4263	} else {
4264		this.tmp.disambig_request = false;
4265	}
4266	var itemSupp = {
4267		position: 1
4268	};
4269	if (this.registry.registry[Item.id]
4270		&& this.registry.citationreg.citationsByItemId
4271		&& this.registry.citationreg.citationsByItemId[Item.id]
4272		&& this.registry.citationreg.citationsByItemId[Item.id].length
4273		&& visualForm) {
4274		if (this.citation.opt["givenname-disambiguation-rule"] === "by-cite") {
4275			itemSupp['first-reference-note-number'] = this.registry.registry[Item.id]['first-reference-note-number'];
4276		}
4277	}
4278	this.tmp.area = "citation";
4279	use_parallels = this.parallel.use_parallels;
4280	this.parallel.use_parallels = false;
4281	this.tmp.suppress_decorations = true;
4282	this.tmp.just_looking = true;
4283	CSL.getCite.call(this, Item, itemSupp);
4284	for (var i=0,ilen=this.output.queue.length;i<ilen;i+=1) {
4285		CSL.Output.Queue.purgeEmptyBlobs(this.output.queue[i]);
4286	}
4287	if (this.opt.development_extensions.clean_up_csl_flaws) {
4288		for (var j=0,jlen=this.output.queue.length;j<jlen;j+=1) {
4289			this.output.adjust.upward(this.output.queue[j]);
4290			this.output.adjust.leftward(this.output.queue[j]);
4291			this.output.adjust.downward(this.output.queue[j]);
4292			this.output.adjust.fix(this.output.queue[j]);
4293		}
4294	}
4295	ret = this.output.string(this, this.output.queue);
4296	this.tmp.just_looking = false;
4297	this.tmp.suppress_decorations = false;
4298	this.parallel.use_parallels = use_parallels;
4299	this.tmp.group_context.replace(oldTermSiblingLayer, "literal");
4300	return ret;
4301};
4302CSL.getSpliceDelimiter = function (last_collapsed, pos) {
4303	if (last_collapsed && ! this.tmp.have_collapsed && "string" === typeof this.citation.opt["after-collapse-delimiter"]) {
4304		this.tmp.splice_delimiter = this.citation.opt["after-collapse-delimiter"];
4305	} else if (this.tmp.have_collapsed && this.opt.xclass === "in-text" && this.opt.update_mode !== CSL.NUMERIC) {
4306		this.tmp.splice_delimiter = ", ";
4307	} else if (this.tmp.use_cite_group_delimiter) {
4308		this.tmp.splice_delimiter = this.citation.opt.cite_group_delimiter;
4309	} else if (this.tmp.cite_locales[pos - 1]) {
4310		var alt_affixes = this.tmp.cite_affixes[this.tmp.area][this.tmp.cite_locales[pos - 1]];
4311		if (alt_affixes && alt_affixes.delimiter) {
4312			this.tmp.splice_delimiter = alt_affixes.delimiter;
4313		}
4314	}
4315	if (!this.tmp.splice_delimiter) {
4316		this.tmp.splice_delimiter = "";
4317	}
4318	return this.tmp.splice_delimiter;
4319};
4320CSL.getCitationCluster = function (inputList, citationID) {
4321	var result, objects, myparams, len, pos, item, last_collapsed, params, empties, composite, compie, myblobs, Item, llen, ppos, obj, preceding_item, txt_esc, error_object;
4322	this.tmp.last_primary_names_string = false;
vendor: 1,374 bytes, lines 4323-4368
4323	this.tmp.nestedBraces = false;
4324	txt_esc = CSL.getSafeEscape(this);
4325	this.tmp.area = "citation";
4326	result = "";
4327	objects = [];
4328	this.tmp.last_suffix_used = "";
4329	this.tmp.last_names_used = [];
4330	this.tmp.last_years_used = [];
4331	this.tmp.backref_index = [];
4332	this.tmp.cite_locales = [];
4333	var suppressTrailingPunctuation = false;
4334	if (this.opt.xclass === "note" && this.citation.opt.suppressTrailingPunctuation) {
4335		suppressTrailingPunctuation = true;
4336	}
4337	if (citationID) {
4338		if (this.registry.citationreg.citationById[citationID].properties["suppress-trailing-punctuation"]) {
4339			suppressTrailingPunctuation = true;
4340		}
4341	}
4342	if (this.opt.xclass === "note") {
4343		var parasets = [];
4344		var lastTitle = false;
4345		var lastPosition = false;
4346		var lastID = false;
4347		var lst = [];
4348		for (var i=0, ilen = inputList.length; i < ilen; i += 1) {
4349			var type = inputList[i][0].type;
4350			var title = inputList[i][0].title;
4351			var position = inputList[i][1].position;
4352			var id = inputList[i][0].id;
4353			if (title && type === "legal_case" && id !== lastID && position) {
4354				if (title !== lastTitle || parasets.length === 0) {
4355					lst = [];
4356					parasets.push(lst);
4357				}
4358				lst.push(inputList[i][1]);
4359			}
4360			lastTitle = title;
4361			lastPosition = position;
4362			lastID = id;
4363		}
4364		for (i=0, ilen=parasets.length; i < ilen; i += 1) {
4365			lst = parasets[i];
4366			if (lst.length < 2) {
4367				continue;
4368			}
4369			var locatorInLastPosition = lst.slice(-1)[0].locator;
4370			if (locatorInLastPosition) {
4371				for (var j=0, jlen=lst.length - 1; j < jlen; j += 1) {
4372					if (lst[j].locator) {
4373						locatorInLastPosition = false;
4374					}
4375				}
4376			}
4377			if (locatorInLastPosition) {
4378				lst[0].locator = locatorInLastPosition;
4379				delete lst.slice(-1)[0].locator;
4380				lst[0].label = lst.slice(-1)[0].label;
4381				if (lst.slice(-1)[0].label) {
4382					delete lst.slice(-1)[0].label;
4383				}
4384			}
4385		 }
4386	}
4387	myparams = [];
4388	len = inputList.length;
4389	for (pos = 0; pos < len; pos += 1) {
4390		Item = inputList[pos][0];
4391		item = inputList[pos][1];
4392		last_collapsed = this.tmp.have_collapsed;
4393		params = {};
4394		if (pos > 0) {
4395			CSL.getCite.call(this, Item, item, "" + inputList[(pos - 1)][0].id);
4396		} else {
4397			this.tmp.term_predecessor = false;
4398			CSL.getCite.call(this, Item, item);
4399		}
4400		if (!this.tmp.cite_renders_content) {
4401			error_object = {
4402				citationID: "" + this.tmp.citation_id,
4403				index: this.tmp.citation_pos,
4404				noteIndex: this.tmp.citation_note_index,
4405				itemID: "" + Item.id,
4406				citationItems_pos: pos,
4407				error_code: CSL.ERROR_NO_RENDERED_FORM
4408			};
4409			this.tmp.citation_errors.push(error_object);
4410		}
4411		if (pos === (inputList.length - 1)) {
4412			this.parallel.ComposeSet();
4413		}
4414		params.splice_delimiter = CSL.getSpliceDelimiter.call(this, last_collapsed, pos);
4415		if (item && item["author-only"]) {
4416			this.tmp.suppress_decorations = true;
4417		}
4418		if (pos > 0) {
4419			preceding_item = inputList[pos - 1][1];
4420			var precedingEndsInPeriod = preceding_item.suffix && preceding_item.suffix.slice(-1) === ".";
4421			var currentStartsWithPeriod = !preceding_item.suffix && item.prefix && item.prefix.slice(0, 1) === ".";
4422			if (precedingEndsInPeriod || currentStartsWithPeriod) {
4423				var spaceidx = params.splice_delimiter.indexOf(" ");
4424				if (spaceidx > -1 && !currentStartsWithPeriod) {
4425					params.splice_delimiter = params.splice_delimiter.slice(spaceidx);
4426				} else {
4427					params.splice_delimiter = "";
4428				}
4429			}
4430		}
4431		params.suppress_decorations = this.tmp.suppress_decorations;
4432		params.have_collapsed = this.tmp.have_collapsed;
4433		myparams.push(params);
4434	}
4435	this.tmp.has_purged_parallel = false;
4436	this.parallel.PruneOutputQueue(this);
4437	empties = 0;
4438	myblobs = this.output.queue.slice();
4439	var fakeblob = {
4440		strings: {
4441			suffix: this.citation.opt.layout_suffix,
4442			delimiter: this.citation.opt.layout_delimiter
4443		}
4444	};
4445	var suffix = this.citation.opt.layout_suffix;
4446	var last_locale = this.tmp.cite_locales[this.tmp.cite_locales.length - 1];
4447	if (last_locale && this.tmp.cite_affixes[this.tmp.area][last_locale] && this.tmp.cite_affixes[this.tmp.area][last_locale].suffix) {
4448		suffix = this.tmp.cite_affixes[this.tmp.area][last_locale].suffix;
4449	}
4450	if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(suffix.slice(0, 1)) > -1) {
4451		suffix = suffix.slice(0, 1);
4452	}
4453	var delimiter = this.citation.opt.layout_delimiter;
4454	if (!delimiter) {
4455		delimiter = "";
4456	}
4457	if (CSL.TERMINAL_PUNCTUATION.slice(0, -1).indexOf(delimiter.slice(0, 1)) > -1) {
4458		delimiter = delimiter.slice(0, 1);
4459	}
4460	var use_layout_suffix = suffix;
4461	for (var i=0,ilen=this.output.queue.length;i<ilen;i+=1) {
4462		CSL.Output.Queue.purgeEmptyBlobs(this.output.queue[i]);
4463	}
4464	if (!this.tmp.suppress_decorations && this.output.queue.length) {
4465		if (!(this.opt.development_extensions.apply_citation_wrapper
4466				&& this.sys.wrapCitationEntry
4467				&& !this.tmp.just_looking
4468				&& this.tmp.area === "citation")) {
4469			if (!suppressTrailingPunctuation) {
4470				this.output.queue[this.output.queue.length - 1].strings.suffix = use_layout_suffix;
4471			}
4472			this.output.queue[0].strings.prefix = this.citation.opt.layout_prefix;
4473		}
4474	}
4475	if (this.opt.development_extensions.clean_up_csl_flaws) {
4476		for (var j=0,jlen=this.output.queue.length;j<jlen;j+=1) {
4477			this.output.adjust.upward(this.output.queue[j]);
4478			this.output.adjust.leftward(this.output.queue[j]);
4479			this.output.adjust.downward(this.output.queue[j]);
4480			this.tmp.last_chr = this.output.adjust.fix(this.output.queue[j]);
4481		}
4482	}
4483	for (pos = 0, len = myblobs.length; pos < len; pos += 1) {
4484		this.output.queue = [myblobs[pos]];
4485		this.tmp.suppress_decorations = myparams[pos].suppress_decorations;
4486		this.tmp.splice_delimiter = myparams[pos].splice_delimiter;
4487		if (myblobs[pos].parallel_delimiter) {
4488			this.tmp.splice_delimiter = myblobs[pos].parallel_delimiter;
4489		}
4490		this.tmp.have_collapsed = myparams[pos].have_collapsed;
4491		composite = this.output.string(this, this.output.queue);
4492		this.tmp.suppress_decorations = false;
4493		if ("string" === typeof composite) {
4494			this.tmp.suppress_decorations = false;
4495			return composite;
4496		}
4497		if ("object" === typeof composite && composite.length === 0 && !item["suppress-author"]) {
4498			if (this.tmp.has_purged_parallel) {
4499				composite.push("");
4500			} else {
4501				var errStr = "[CSL STYLE ERROR: reference with no printed form.]";
4502				var preStr = pos === 0 ? txt_esc(this.citation.opt.layout_prefix) : "";
4503				var sufStr = pos === (myblobs.length - 1) ? txt_esc(this.citation.opt.layout_suffix) : "";
4504				composite.push(preStr + errStr + sufStr);
4505			}
4506		}
4507		if (objects.length && "string" === typeof composite[0]) {
4508			composite.reverse();
4509			var tmpstr = composite.pop();
4510			if (tmpstr && tmpstr.slice(0, 1) === ",") {
4511				objects.push(tmpstr);
4512			} else if ("string" == typeof objects.slice(-1)[0] && objects.slice(-1)[0].slice(-1) === ",") {
4513				objects.push(" " + tmpstr);
4514			} else if (tmpstr) {
4515				objects.push(txt_esc(this.tmp.splice_delimiter) + tmpstr);
4516			}
4517		} else {
4518			composite.reverse();
4519			compie = composite.pop();
4520			if ("undefined" !== typeof compie) {
4521				if (objects.length && "string" === typeof objects[objects.length - 1]) {
4522					objects[objects.length - 1] += compie.successor_prefix;
4523				}
4524				objects.push(compie);
4525			}
4526		}
4527		llen = composite.length;
4528		for (ppos = 0; ppos < llen; ppos += 1) {
4529			obj = composite[ppos];
4530			if ("string" === typeof obj) {
4531				objects.push(txt_esc(this.tmp.splice_delimiter) + obj);
4532				continue;
4533			}
4534			compie = composite.pop();
4535			if ("undefined" !== typeof compie) {
4536				objects.push(compie);
4537			}
4538		}
4539		if (objects.length === 0 && !inputList[pos][1]["suppress-author"]) {
4540			empties += 1;
4541		}
4542	}
4543	result += this.output.renderBlobs(objects);
4544	if (result) {
4545		this.output.nestedBraces = false;
4546		if (!this.tmp.suppress_decorations) {
4547			len = this.citation.opt.layout_decorations.length;
4548			for (pos = 0; pos < len; pos += 1) {
4549				params = this.citation.opt.layout_decorations[pos];
4550				if (params[1] === "normal") {
4551					continue;
4552				}
4553				result = this.fun.decorate[params[0]][params[1]](this, result);
4554			}
4555		}
4556	}
4557	this.tmp.suppress_decorations = false;
4558	return result;
4559};
4560CSL.getCite = function (Item, item, prevItemID) {
4561	var next, error_object;
4562	this.tmp.cite_renders_content = false;
4563	this.parallel.StartCite(Item, item, prevItemID);
4564	CSL.citeStart.call(this, Item, item);
4565	next = 0;
4566	this.nameOutput = new CSL.NameOutput(this, Item, item);
4567	while (next < this[this.tmp.area].tokens.length) {
4568		next = CSL.tokenExec.call(this, this[this.tmp.area].tokens[next], Item, item);
4569	}
4570	CSL.citeEnd.call(this, Item, item);
4571	this.parallel.CloseCite(this);
4572	if (!this.tmp.cite_renders_content && !this.tmp.just_looking) {
4573		if (this.tmp.area === "bibliography") {
4574			error_object = {
4575				index: this.tmp.bibliography_pos,
4576				itemID: "" + Item.id,
4577				error_code: CSL.ERROR_NO_RENDERED_FORM
4578			};
4579			this.tmp.bibliography_errors.push(error_object);
4580		}
4581	}
4582	return "" + Item.id;
4583};
4584CSL.citeStart = function (Item, item) {
4585	this.tmp.disambiguate_count = 0;
4586	this.tmp.disambiguate_maxMax = 0;
4587	this.tmp.same_author_as_previous_cite = false;
4588	if (!this.tmp.suppress_decorations) {
4589		this.tmp.subsequent_author_substitute_ok = true;
4590	} else {
4591		this.tmp.subsequent_author_substitute_ok = false;
4592	}
4593	this.tmp.lastchr = "";
4594	if (this.tmp.area === "citation" && this.citation.opt.collapse && this.citation.opt.collapse.length) {
4595		this.tmp.have_collapsed = true;
4596	} else {
4597		this.tmp.have_collapsed = false;
4598	}
4599	this.tmp.render_seen = false;
4600	if (this.tmp.disambig_request  && ! this.tmp.disambig_override) {
4601		this.tmp.disambig_settings = this.tmp.disambig_request;
4602	} else if (this.registry.registry[Item.id] && ! this.tmp.disambig_override) {
4603		this.tmp.disambig_request = this.registry.registry[Item.id].disambig;
4604		this.tmp.disambig_settings = this.registry.registry[Item.id].disambig;
4605	} else {
4606		this.tmp.disambig_settings = new CSL.AmbigConfig();
4607	}
4608	if (this.tmp.area !== 'citation' && this.registry.registry[Item.id]) {
4609		this.tmp.disambig_restore = CSL.cloneAmbigConfig(this.registry.registry[Item.id].disambig);
4610		if (this.tmp.area === 'bibliography' && this.tmp.disambig_settings && this.tmp.disambig_override) {
4611			if (this.opt["disambiguate-add-names"]) {
4612				this.tmp.disambig_settings.names = this.registry.registry[Item.id].disambig.names.slice();
4613				this.tmp.disambig_request.names = this.registry.registry[Item.id].disambig.names.slice();
4614			}
4615			if (this.opt["disambiguate-add-givenname"]) {
4616				this.tmp.disambig_request = this.tmp.disambig_settings;
4617				this.tmp.disambig_settings.givens = this.registry.registry[Item.id].disambig.givens.slice();
4618				this.tmp.disambig_request.givens = this.registry.registry[Item.id].disambig.givens.slice();
4619				for (var i=0,ilen=this.tmp.disambig_settings.givens.length;i<ilen;i+=1) {
4620					this.tmp.disambig_settings.givens[i] = this.registry.registry[Item.id].disambig.givens[i].slice();
4621				}
4622				for (var i=0,ilen=this.tmp.disambig_request.givens.length;i<ilen;i+=1) {
4623					this.tmp.disambig_request.givens[i] = this.registry.registry[Item.id].disambig.givens[i].slice();
4624				}
4625			}
4626		}
4627	}
4628	this.tmp.names_used = [];
4629	this.tmp.nameset_counter = 0;
4630	this.tmp.years_used = [];
4631	this.tmp.names_max.clear();
4632	this.tmp.splice_delimiter = this[this.tmp.area].opt.layout_delimiter;
4633	this.bibliography_sort.keys = [];
4634	this.citation_sort.keys = [];
4635	this.tmp.has_done_year_suffix = false;
4636	this.tmp.last_cite_locale = false;
4637	if (!this.tmp.just_looking && item && !item.position && this.registry.registry[Item.id]) {
4638		this.tmp.disambig_restore = CSL.cloneAmbigConfig(this.registry.registry[Item.id].disambig);
4639	}
4640	this.tmp.shadow_numbers = {};
4641	this.setNumberLabels(Item);
4642	this.tmp.first_name_string = false;
4643	if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.prefix) {
4644		var openBrace = CSL.checkNestedBraceOpen.exec(item.prefix);
4645		var closeBrace = CSL.checkNestedBraceClose.exec(item.prefix);
4646		if (openBrace) {
4647			if (!closeBrace) {
4648				this.output.nestedBraces = CSL.NestedBraces;
4649			} else if (closeBrace[0].length < openBrace[0].length) {
4650				this.output.nestedBraces = CSL.NestedBraces;
4651			} else {
4652				this.output.nestedBraces = false;
4653			}
4654		} else if (closeBrace) {
4655			this.output.nestedBraces = false;
4656		}
4657	}
4658};
4659CSL.citeEnd = function (Item, item) {
4660	if (this.tmp.disambig_restore) {
4661		this.registry.registry[Item.id].disambig.names = this.tmp.disambig_restore.names.slice();
4662		this.registry.registry[Item.id].disambig.givens = this.tmp.disambig_restore.givens.slice();
4663		for (var i=0,ilen=this.registry.registry[Item.id].disambig.givens.length;i<ilen;i+=1) {
4664			this.registry.registry[Item.id].disambig.givens[i] = this.tmp.disambig_restore.givens[i].slice();
4665		}
4666	}
4667	this.tmp.disambig_restore = false;
4668	if (item && item.suffix) {
4669		this.tmp.last_suffix_used = item.suffix;
4670	} else {
4671		this.tmp.last_suffix_used = "";
4672	}
4673	this.tmp.last_years_used = this.tmp.years_used.slice();
4674	this.tmp.last_names_used = this.tmp.names_used.slice();
4675	this.tmp.cut_var = false;
4676	this.tmp.disambig_request = false;
4677	this.tmp.cite_locales.push(this.tmp.last_cite_locale);
4678	if (this.tmp.issued_date && this.tmp.renders_collection_number) {
4679		var buf = [];
4680		for (var i = this.tmp.issued_date.list.length - 1; i > this.tmp.issued_date.pos; i += -1) {
4681			buf.push(this.tmp.issued_date.list.pop());
4682		}
4683		this.tmp.issued_date.list.pop();
4684		for (i = buf.length - 1; i > -1; i += -1) {
4685			this.tmp.issued_date.list.push(buf.pop());
4686		}
4687		if (this.parallel.use_parallels) {
4688			this.parallel.cite["issued"] = false;
4689		}
4690	}
4691	this.tmp.issued_date = false;
4692	this.tmp.renders_collection_number = false;
4693	if (this.opt.development_extensions.flip_parentheses_to_braces && item && item.suffix) {
4694		var openBrace = CSL.checkNestedBraceOpen.exec(item.suffix);
4695		var closeBrace = CSL.checkNestedBraceClose.exec(item.suffix);
4696		if (closeBrace) {
4697			if (!openBrace) {
4698				this.output.nestedBraces = false;
4699			} else if (openBrace[0].length < closeBrace[0].length) {
4700				this.output.nestedBraces = false;
4701			} else {
4702				this.output.nestedBraces = CSL.NestedBraces;
4703			}
4704		} else if (openBrace) {
4705			this.output.nestedBraces = CSL.NestedBraces;
4706		}
4707	}
4708};
4709CSL.Engine.prototype.makeBibliography = function (bibsection) {
4710	var debug, ret, params, maxoffset, item, len, pos, tok, tokk, tokkk, entry_ids, entry_strings, bibliography_errors;
4711	debug = false;
4712	if (!this.bibliography.tokens.length) {
4713		return false;
4714	}
4715	if ("string" === typeof bibsection) {
4716		this.opt.citation_number_slug = bibsection;
4717		bibsection = false;
4718	}
4719	ret = CSL.getBibliographyEntries.call(this, bibsection);
4720	entry_ids = ret[0];
4721	entry_strings = ret[1];
4722	var done = ret[2];
4723	params = {
4724		"maxoffset": 0,
4725		"entryspacing": this.bibliography.opt["entry-spacing"],
4726		"linespacing": this.bibliography.opt["line-spacing"],
4727		"second-field-align": false,
4728		"entry_ids": entry_ids,
4729		"bibliography_errors": this.tmp.bibliography_errors.slice(),
4730		"done": done
4731	};
4732	if (this.bibliography.opt["second-field-align"]) {
4733		params["second-field-align"] = this.bibliography.opt["second-field-align"];
4734	}
4735	maxoffset = 0;
4736	len = this.registry.reflist.length;
4737	for (pos = 0; pos < len; pos += 1) {
4738		item = this.registry.reflist[pos];
4739		if (item.offset > params.maxoffset) {
4740			params.maxoffset = item.offset;
4741		}
4742	}
4743	if (this.bibliography.opt.hangingindent) {
4744		params.hangingindent = this.bibliography.opt.hangingindent;
4745	}
4746	params.bibstart = this.fun.decorate.bibstart;
4747	params.bibend = this.fun.decorate.bibend;
4748	this.opt.citation_number_slug = false;
4749	return [params, entry_strings];
4750};
4751CSL.getBibliographyEntries = function (bibsection) {
4752	var ret, input, include, anymatch, allmatch, bib_entry, res, len, pos, item, llen, ppos, spec, lllen, pppos, bib_layout, topblobs, all_item_ids, entry_item_ids, debug, collapse_parallel, i, ilen, siblings, skips, sortedItems, eyetem, chr, entry_item_data, j, jlen, newIDs, originalIDs;
4753	ret = [];
4754	entry_item_data = [];
4755	this.tmp.area = "bibliography";
4756	this.tmp.last_rendered_name = false;
4757	this.tmp.bibliography_errors = [];
4758	this.tmp.bibliography_pos = 0;
4759	if (bibsection && bibsection.page_start && bibsection.page_length) {
4760		input = this.registry.getSortedIds();
4761	} else {
4762		input = this.retrieveItems(this.registry.getSortedIds());
4763	}
4764	this.tmp.disambig_override = true;
4765	function eval_string(a, b) {
4766		if (a === b) {
4767			return true;
4768		}
4769		return false;
4770	}
4771	function eval_list(a, lst) {
4772		lllen = lst.length;
4773		for (pppos = 0; pppos < lllen; pppos += 1) {
4774			if (eval_string(a, lst[pppos])) {
4775				return true;
4776			}
4777		}
4778		return false;
4779	}
4780	function eval_spec(a, b) {
4781		if ((a === "none" || !a) && !b) {
4782			return true;
4783		}
4784		if ("string" === typeof b) {
4785			return eval_string(a, b);
4786		} else if (!b) {
4787			return false;
4788		} else {
4789			return eval_list(a, b);
4790		}
4791	}
4792	skips = {};
4793	var page_item_count;
4794	if (bibsection && bibsection.page_start && bibsection.page_length) {
4795		page_item_count = 0;
4796		if (bibsection.page_start !== true) {
4797			for (i = 0, ilen = input.length; i < ilen; i += 1) {
4798				skips[input[i]] = true;
4799				if (bibsection.page_start == input[i]) {
4800					break;
4801				}
4802			}
4803		}
4804	}
4805	var processed_item_ids = [];
4806	for (i = 0, ilen = input.length; i < ilen; i += 1) {
4807		if (bibsection && bibsection.page_start && bibsection.page_length) {
4808			if (skips[input[i]]) {
4809				continue;
4810			}
4811			item = this.retrieveItem(input[i]);
4812			if (page_item_count === bibsection.page_length) {
4813				break;
4814			}
4815		} else {
4816			item = input[i];
4817			if (skips[item.id]) {
4818				continue;
4819			}
4820		}
4821		if (bibsection) {
4822			include = true;
4823			if (bibsection.include) {
4824				include = false;
4825				for (j = 0, jlen = bibsection.include.length; j < jlen; j += 1) {
4826					spec = bibsection.include[j];
4827					if (eval_spec(spec.value, item[spec.field])) {
4828						include = true;
4829						break;
4830					}
4831				}
4832			} else if (bibsection.exclude) {
4833				anymatch = false;
4834				for (j = 0, jlen = bibsection.exclude.length; j < jlen; j += 1) {
4835					spec = bibsection.exclude[j];
4836					if (eval_spec(spec.value, item[spec.field])) {
4837						anymatch = true;
4838						break;
4839					}
4840				}
4841				if (anymatch) {
4842					include = false;
4843				}
4844			} else if (bibsection.select) {
4845				include = false;
4846				allmatch = true;
4847				for (j = 0, jlen = bibsection.select.length; j < jlen; j += 1) {
4848					spec = bibsection.select[j];
4849					if (!eval_spec(spec.value, item[spec.field])) {
4850						allmatch = false;
4851					}
4852				}
4853				if (allmatch) {
4854					include = true;
4855				}
4856			}
4857			if (bibsection.quash) {
4858				allmatch = true;
4859				for (j = 0, jlen = bibsection.quash.length; j < jlen; j += 1) {
4860					spec = bibsection.quash[j];
4861					if (!eval_spec(spec.value, item[spec.field])) {
4862						allmatch = false;
4863					}
4864				}
4865				if (allmatch) {
4866					include = false;
4867				}
4868			}
4869			if (!include) {
4870				continue;
4871			}
4872		}
4873		bib_entry = new CSL.Token("group", CSL.START);
4874		bib_entry.decorations = [["@bibliography", "entry"]].concat(this.bibliography.opt.layout_decorations);
4875		this.output.startTag("bib_entry", bib_entry);
4876		if (item.system_id && this.sys.embedBibliographyEntry) {
4877			this.output.current.value().item_id = item.system_id;
4878		} else {
4879			this.output.current.value().system_id = item.id;
4880		}
4881		sortedItems = [[{id: "" + item.id}, item]];
4882		entry_item_ids = [];
4883		if (this.registry.registry[item.id].master
4884			&& !(bibsection && bibsection.page_start && bibsection.page_length)) {
4885			collapse_parallel = true;
4886			this.parallel.StartCitation(sortedItems);
4887			this.output.queue[0].strings.delimiter = ", ";
4888			this.tmp.term_predecessor = false;
4889			entry_item_ids.push("" + CSL.getCite.call(this, item));
4890			skips[item.id] = true;
4891			siblings = this.registry.registry[item.id].siblings;
4892			for (j = 0, jlen = siblings.length; j < jlen; j += 1) {
4893				var k = this.registry.registry[item.id].siblings[j];
4894				eyetem = this.retrieveItem(k);
4895				entry_item_ids.push("" + CSL.getCite.call(this, eyetem));
4896				skips[eyetem.id] = true;
4897			}
4898			this.parallel.ComposeSet();
4899			this.parallel.PruneOutputQueue();
4900		} else if (!this.registry.registry[item.id].siblings) {
4901			this.parallel.StartCitation(sortedItems);
4902			this.tmp.term_predecessor = false;
4903			entry_item_ids.push("" + CSL.getCite.call(this, item));
4904			if (bibsection && bibsection.page_start && bibsection.page_length) {
4905				page_item_count += 1;
4906			}
4907		}
4908		entry_item_data.push("");
4909		this.tmp.bibliography_pos += 1;
4910		processed_item_ids.push(entry_item_ids);
4911		this.output.endTag("bib_entry");
4912		if (this.output.queue[0].blobs.length && this.output.queue[0].blobs[0].blobs.length) {
4913			if (collapse_parallel || !this.output.queue[0].blobs[0].blobs[0].strings) {
4914				topblobs = this.output.queue[0].blobs;
4915				collapse_parallel = false;
4916			} else {
4917				topblobs = this.output.queue[0].blobs[0].blobs;
4918			}
4919			for (j  = topblobs.length - 1; j > -1; j += -1) {
4920				if (topblobs[j].blobs && topblobs[j].blobs.length !== 0) {
4921					var last_locale = this.tmp.cite_locales[this.tmp.cite_locales.length - 1];
4922					var suffix;
4923					if (this.tmp.cite_affixes[this.tmp.area][last_locale]) {
4924						suffix = this.tmp.cite_affixes[this.tmp.area][last_locale].suffix;
4925					} else {
4926						suffix = this.bibliography.opt.layout_suffix;
4927					}
4928					chr = suffix.slice(0, 1);
4929					if (chr && topblobs[j].strings.suffix.slice(-1) === chr) {
4930						topblobs[j].strings.suffix = topblobs[j].strings.suffix.slice(0, -1);
4931					}
4932					topblobs[j].strings.suffix += suffix;
4933					break;
4934				}
4935			}
4936			topblobs[0].strings.prefix = this.bibliography.opt.layout_prefix + topblobs[0].strings.prefix;
4937		}
4938		for (var j=0,jlen=this.output.queue.length;j<jlen;j+=1) {
4939			CSL.Output.Queue.purgeEmptyBlobs(this.output.queue[j]);
4940		}
4941		for (var j=0,jlen=this.output.queue.length;j<jlen;j+=1) {
4942			this.output.adjust.upward(this.output.queue[j]);
4943			this.output.adjust.leftward(this.output.queue[j]);
4944			this.output.adjust.downward(this.output.queue[j],true);
4945			this.output.adjust.fix(this.output.queue[j]);
4946		}
4947		res = this.output.string(this, this.output.queue)[0];
4948		if (!res) {
4949			res = "\n[CSL STYLE ERROR: reference with no printed form.]\n";
4950		}
4951		ret.push(res);
4952	}
4953	var done = false;
4954	if (bibsection && bibsection.page_start && bibsection.page_length) {
4955		var last_expected_id = input.slice(-1)[0];
4956		var last_seen_id = processed_item_ids.slice(-1)[0];
4957		if (!last_expected_id || !last_seen_id || last_expected_id == last_seen_id) {
4958			done = true;
4959		}
4960	}
4961	this.tmp.disambig_override = false;
4962	return [processed_item_ids, ret, done];
4963};
4964CSL.Engine.prototype.setCitationId = function (citation, force) {
4965	var ret, id, direction;
4966	ret = false;
vendor: 9,032 bytes, lines 4967-5247
4967	if (!citation.citationID || force) {
4968		id = Math.floor(Math.random() * 100000000000000);
4969		while (true) {
4970			direction = 0;
4971			if (!this.registry.citationreg.citationById[id]) {
4972				citation.citationID = id.toString(32);
4973				break;
4974			} else if (!direction && id < 50000000000000) {
4975				direction = 1;
4976			} else {
4977				direction = -1;
4978			}
4979			if (direction === 1) {
4980				id += 1;
4981			} else {
4982				id += -1;
4983			}
4984		}
4985		ret = "" + id;
4986	}
4987	this.registry.citationreg.citationById[citation.citationID] = citation;
4988	return ret;
4989};
4990CSL.Engine.prototype.rebuildProcessorState = function (citations, mode, uncitedItemIDs) {
4991	if (!citations) {
4992		citations = [];
4993	}
4994	if (!mode) {
4995		mode = 'html';
4996	}
4997	var doneIDs = {};
4998	var itemIDs = [];
4999	for (var i=0,ilen=citations.length;i<ilen;i+=1) {
5000		for (var j=0,jlen=citations[i].citationItems.length;j<jlen;j+=1) {
5001			var itemID = "" + citations[i].citationItems[j].id;
5002			if (!doneIDs[itemID]) {
5003				itemIDs.push(itemID);
5004			}
5005			doneIDs[itemID] = true;
5006		}
5007	}
5008	this.updateItems(itemIDs);
5009	var pre = [];
5010	var post = [];
5011	var ret = [];
5012	var oldMode = this.opt.mode;
5013	this.setOutputFormat(mode);
5014	for (var i=0,ilen=citations.length;i<ilen;i+=1) {
5015		var res = this.processCitationCluster(citations[i],pre,post,CSL.ASSUME_ALL_ITEMS_REGISTERED);
5016		pre.push([citations[i].citationID,citations[i].properties.noteIndex]);
5017		for (var j=0,jlen=res[1].length;j<jlen;j+=1) {
5018			var index = res[1][j][0];
5019			ret[index] = [
5020				pre[index][0],
5021				pre[index][1],
5022				res[1][j][1]
5023			];
5024		}
5025	}
5026	this.updateUncitedItems(uncitedItemIDs);
5027	this.setOutputFormat(oldMode);
5028	return ret;
5029}
5030CSL.Engine.prototype.restoreProcessorState = function (citations) {
5031	var i, ilen, j, jlen, item, Item, newitem, citationList, itemList, sortedItems;
5032	citationList = [];
5033	itemList = [];
5034	if (!citations) {
5035		citations = [];
5036	}
5037	var indexNumbers = [];
5038	var citationIds = {};
5039	for (i = 0, ilen = citations.length; i < ilen; i += 1) {
5040		if (citationIds[citations[i].citationID]) {
5041			this.setCitationId(citations[i], true);
5042		}
5043		citationIds[citations[i].citationID] = true;
5044		indexNumbers.push(citations[i].properties.index);
5045	}
5046	var oldCitations = citations.slice();
5047	oldCitations.sort(
5048		function (a,b) {
5049			if (a.properties.index < b.properties.index) {
5050				return -1;
5051			} else if (a.properties.index > b.properties.index) {
5052				return 1;
5053			} else {
5054				return 0;
5055			}
5056		}
5057	);
5058	for (i = 0, ilen = oldCitations.length; i < ilen; i += 1) {
5059		oldCitations[i].properties.index = i;
5060	}
5061	for (i = 0, ilen = oldCitations.length; i < ilen; i += 1) {
5062		sortedItems = [];
5063		for (j = 0, jlen = oldCitations[i].citationItems.length; j < jlen; j += 1) {
5064			item = oldCitations[i].citationItems[j];
5065			if ("undefined" === typeof item.sortkeys) {
5066				item.sortkeys = [];
5067			}
5068			Item = this.retrieveItem("" + item.id);
5069			newitem = [Item, item];
5070			sortedItems.push(newitem);
5071			oldCitations[i].citationItems[j].item = Item;
5072			itemList.push("" + item.id);
5073		}
5074		if (!oldCitations[i].properties.unsorted) {
5075			sortedItems.sort(this.citation.srt.compareCompositeKeys);
5076		}
5077		oldCitations[i].sortedItems = sortedItems;
5078		this.registry.citationreg.citationById[oldCitations[i].citationID] = oldCitations[i];
5079	}
5080	this.updateItems(itemList);
5081	for (i = 0, ilen = citations.length; i < ilen; i += 1) {
5082		citationList.push(["" + citations[i].citationID, citations[i].properties.noteIndex]);
5083	}
5084	var ret = [];
5085	if (citations && citations.length) {
5086		ret = this.processCitationCluster(citations[0], [], citationList.slice(1));
5087	} else {
5088		this.registry = new CSL.Registry(this);
5089		this.tmp = new CSL.Engine.Tmp();
5090		this.disambiguate = new CSL.Disambiguation(this);
5091	}
5092	return ret;
5093};
5094CSL.Engine.prototype.updateItems = function (idList, nosort, rerun_ambigs) {
5095	var debug = false;
5096	var oldArea = this.tmp.area;
5097	this.registry.init(idList);
5098	if (rerun_ambigs) {
5099		for (var ambig in this.registry.ambigcites) {
5100			this.registry.ambigsTouched[ambig] = true;
5101		}
5102	}
5103	this.registry.dodeletes(this.registry.myhash);
5104	this.registry.doinserts(this.registry.mylist);
5105	this.registry.dorefreshes();
5106	this.registry.rebuildlist();
5107	this.registry.setsortkeys();
5108	this.registry.setdisambigs();
5109	if (!nosort) {
5110		this.registry.sorttokens();
5111	}
5112	this.registry.renumber();
5113	this.tmp.area = oldArea;
5114	return this.registry.getSortedIds();
5115};
5116CSL.Engine.prototype.updateUncitedItems = function (idList, nosort) {
5117	var debug = false;
5118	if (!idList) {
5119		idList = [];
5120	}
5121	if ("object" == typeof idList) {
5122		if ("undefined" == typeof idList.length) {
5123			var idHash = idList;
5124			idList = [];
5125			for (var key in idHash) {
5126				idList.push(key);
5127			}
5128		} else if ("number" == typeof idList.length) {
5129			var idHash = {};
5130			for (var i=0,ilen=idList.length;i<ilen;i+=1) {
5131				idHash[idList[i]] = true;
5132			}
5133		}
5134	}
5135	this.registry.init(idList, true);
5136	this.registry.dopurge(idHash);
5137	this.registry.doinserts(this.registry.mylist);
5138	this.registry.dorefreshes();
5139	this.registry.rebuildlist();
5140	this.registry.setsortkeys();
5141	this.registry.setdisambigs();
5142	if (!nosort) {
5143		this.registry.sorttokens();
5144	}
5145	this.registry.renumber();
5146	return this.registry.getSortedIds();
5147};
5148CSL.localeResolve = function (langstr, defaultLocale) {
5149	var ret, langlst;
5150	if (!defaultLocale) {
5151		defaultLocale = "en-US";
5152	}
5153	if (!langstr) {
5154		langstr = defaultLocale;
5155	}
5156	ret = {};
5157	langlst = langstr.split(/[\-_]/);
5158	ret.base = CSL.LANG_BASES[langlst[0]];
5159	if ("undefined" === typeof ret.base) {
5160		CSL.debug("Warning: unknown locale "+langstr+", setting fallback to "+defaultLocale);
5161		return {base:defaultLocale, best:langstr, bare:langlst[0]};
5162	}
5163	if (langlst.length === 1) {
5164		ret.generic = true;
5165	}
5166	if (langlst.length === 1 || langlst[1] === "x") {
5167		ret.best = ret.base.replace("_", "-");
5168	} else {
5169		ret.best = langlst.slice(0, 2).join("-");
5170	}
5171	ret.base = ret.base.replace("_", "-");
5172	ret.bare = langlst[0];
5173	return ret;
5174};
5175CSL.Engine.prototype.localeConfigure = function (langspec, beShy) {
5176	var localexml;
5177	if (this.opt.development_extensions.normalize_lang_keys_to_lowercase) {
5178		langspec.best = langspec.best.toLowerCase();
5179		langspec.bare = langspec.bare.toLowerCase();
5180		langspec.base = langspec.base.toLowerCase();
5181	}
5182	if (beShy && this.locale[langspec.best]) {
5183		return;
5184	}
5185	localexml = this.sys.xml.makeXml(this.sys.retrieveLocale("en-US"));
5186	this.localeSet(localexml, "en-US", langspec.best);
5187	if (langspec.best !== "en-US") {
5188		if (langspec.base !== langspec.best) {
5189			localexml = this.sys.xml.makeXml(this.sys.retrieveLocale(langspec.base));
5190			this.localeSet(localexml, langspec.base, langspec.best);
5191		}
5192		localexml = this.sys.xml.makeXml(this.sys.retrieveLocale(langspec.best));
5193		this.localeSet(localexml, langspec.best, langspec.best);
5194	}
5195	this.localeSet(this.cslXml, "", langspec.best);
5196	this.localeSet(this.cslXml, langspec.bare, langspec.best);
5197	if (langspec.base !== langspec.best) {
5198		this.localeSet(this.cslXml, langspec.base, langspec.best);
5199	}
5200	this.localeSet(this.cslXml, langspec.best, langspec.best);
5201	if ("undefined" === typeof this.locale[langspec.best].terms["page-range-delimiter"]) {
5202		if (["fr", "pt"].indexOf(langspec.best.slice(0, 2).toLowerCase()) > -1) {
5203			this.locale[langspec.best].terms["page-range-delimiter"] = "-";
5204		} else {
5205			this.locale[langspec.best].terms["page-range-delimiter"] = "\u2013";
5206		}
5207	}
5208	if ("undefined" === typeof this.locale[langspec.best].terms["year-range-delimiter"]) {
5209		this.locale[langspec.best].terms["year-range-delimiter"] = "\u2013";
5210	}
5211	if ("undefined" === typeof this.locale[langspec.best].terms["citation-range-delimiter"]) {
5212		this.locale[langspec.best].terms["citation-range-delimiter"] = "\u2013";
5213	}
5214	if (this.opt.development_extensions.normalize_lang_keys_to_lowercase) {
5215		var localeLists = ["default-locale","locale-sort","locale-translit","locale-translat"];
5216		for (var i=0,ilen=localeLists.length;i<ilen;i+=1) {
5217			for (var j=0,jlen=this.opt[localeLists[i]].length;j<jlen;j+=1) {
5218				this.opt[localeLists[i]][j] = this.opt[localeLists[i]][j].toLowerCase();
5219			}
5220		}
5221		this.opt.lang = this.opt.lang.toLowerCase();
5222	}
5223};
5224CSL.Engine.prototype.localeSet = function (myxml, lang_in, lang_out) {
5225	var blob, locale, nodes, attributes, pos, ppos, term, form, termname, styleopts, attr, date, attrname, len, genderform, target, i, ilen;
5226	lang_in = lang_in.replace("_", "-");
5227	lang_out = lang_out.replace("_", "-");
5228	if (this.opt.development_extensions.normalize_lang_keys_to_lowercase) {
5229		lang_in = lang_in.toLowerCase();
5230		lang_out = lang_out.toLowerCase();
5231	}
5232	if (!this.locale[lang_out]) {
5233		this.locale[lang_out] = {};
5234		this.locale[lang_out].terms = {};
5235		this.locale[lang_out].opts = {};
5236		this.locale[lang_out].opts["skip-words"] = CSL.SKIP_WORDS;
5237		if (!this.locale[lang_out].opts["leading-noise-words"]) {
5238			this.locale[lang_out].opts["leading-noise-words"] = [];
5239		}
5240		this.locale[lang_out].dates = {};
5241		this.locale[lang_out].ord = {'1.0.1':false,keys:{}};
5242		this.locale[lang_out]["noun-genders"] = {};
5243	}
5244	locale = this.sys.xml.makeXml();
5245	if (this.sys.xml.nodeNameIs(myxml, 'locale')) {
5246		locale = myxml;
5247	} else {
5248		nodes = this.sys.xml.getNodesByName(myxml, "locale");
5249		for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
5250			blob = nodes[pos];
5251			if (this.sys.xml.getAttributeValue(blob, 'lang', 'xml') === lang_in) {
5252				locale = blob;
5253				break;
5254			}
5255		}
5256	}
5257	nodes = this.sys.xml.getNodesByName(locale, 'type');
5258	for (i = 0, ilen = this.sys.xml.numberofnodes(nodes); i < ilen; i += 1) {
5259		var typenode = nodes[i];
5260		var type = this.sys.xml.getAttributeValue(typenode, 'name');
5261		var gender = this.sys.xml.getAttributeValue(typenode, 'gender');
5262		this.opt.gender[type] = gender;
5263	}
5264	var hasCslOrdinals101 = this.sys.xml.getNodesByName(locale, 'term', 'ordinal').length;
5265	if (hasCslOrdinals101) {
5266		for (var key in this.locale[lang_out].ord.keys) {
5267			delete this.locale[lang_out].terms[key];
5268		}
5269		this.locale[lang_out].ord = {"1.0.1":false,keys:{}};
5270	}
5271	nodes = this.sys.xml.getNodesByName(locale, 'term');
5272	var ordinals101 = {"last-digit":{},"last-two-digits":{},"whole-number":{}};
5273	var ordinals101_toggle = false;
5274	var genderized_terms = {};
5275	for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
5276		term = nodes[pos];
5277		termname = this.sys.xml.getAttributeValue(term, 'name');
5278		if (termname === "sub verbo") {
5279			termname = "sub-verbo";
5280		}
5281		if (termname.slice(0,7) === "ordinal") {
5282			var termstring = this.sys.xml.getNodeValue(term);
5283			if (termname === "ordinal") {
5284				ordinals101_toggle = true;
5285			} else {
5286				var match = this.sys.xml.getAttributeValue(term, 'match');
5287				var termstub = termname.slice(8);
5288				var genderform = this.sys.xml.getAttributeValue(term, 'gender-form');
5289				if (!genderform) {
5290					genderform = "neuter";
5291				}
5292				if (!match) {
5293					match = "last-two-digits";
5294					if (termstub.slice(0,1) === "0") {
5295						match = "last-digit";
5296					}
5297				}
5298				if (termstub.slice(0,1) === "0") {
5299					termstub = termstub.slice(1);
5300				}
5301				if (!ordinals101[match][termstub]) {
5302					ordinals101[match][termstub] = {};
5303				}
5304				ordinals101[match][termstub][genderform] = termname;
5305			}
5306			this.locale[lang_out].ord.keys[termname] = true;
5307		}
5308		if ("undefined" === typeof this.locale[lang_out].terms[termname]) {
5309			this.locale[lang_out].terms[termname] = {};
5310		}
5311		form = "long";
5312		genderform = false;
5313		if (this.sys.xml.getAttributeValue(term, 'form')) {
5314			form = this.sys.xml.getAttributeValue(term, 'form');
5315		}
5316		if (this.sys.xml.getAttributeValue(term, 'gender-form')) {
5317			genderform = this.sys.xml.getAttributeValue(term, 'gender-form');
5318		}
5319		if (this.sys.xml.getAttributeValue(term, 'gender')) {
5320			this.locale[lang_out]["noun-genders"][termname] = this.sys.xml.getAttributeValue(term, 'gender');
5321		}
5322		if (genderform) {
5323			this.locale[lang_out].terms[termname][genderform] = {};
5324			this.locale[lang_out].terms[termname][genderform][form] = [];
5325			target = this.locale[lang_out].terms[termname][genderform];
5326			genderized_terms[termname] = true;
5327		} else {
5328			this.locale[lang_out].terms[termname][form] = [];
5329			target = this.locale[lang_out].terms[termname];
5330		}
5331		if (this.sys.xml.numberofnodes(this.sys.xml.getNodesByName(term, 'multiple'))) {
5332			target[form][0] = this.sys.xml.getNodeValue(term, 'single');
5333			target[form][1] = this.sys.xml.getNodeValue(term, 'multiple');
5334		} else {
5335			target[form] = this.sys.xml.getNodeValue(term);
5336		}
5337	}
5338	if (ordinals101_toggle) {
5339		for (var ikey in genderized_terms) {
5340			var gender_segments = {};
5341			var form_segments = 0;
5342			for (var jkey in this.locale[lang_out].terms[ikey]) {
5343				if (["masculine","feminine"].indexOf(jkey) > -1) {
5344					gender_segments[jkey] = this.locale[lang_out].terms[ikey][jkey];
5345				} else {
5346					form_segments += 1;
5347				}
5348			}
5349			if (!form_segments) {
5350				if (gender_segments.feminine) {
5351					for (var jkey in gender_segments.feminine) {
5352						this.locale[lang_out].terms[ikey][jkey] = gender_segments.feminine[jkey];
5353					}
5354				} else if (gender_segments.masculine) {
5355					for (var jkey in gender_segments.masculine) {
5356						this.locale[lang_out].terms[ikey][jkey] = gender_segments.masculine[jkey];
5357					}
5358				}
5359			}
5360		}
5361		this.locale[lang_out].ord['1.0.1'] = ordinals101;
5362	}
5363	for (termname in this.locale[lang_out].terms) {
5364		for (i = 0, ilen = 2; i < ilen; i += 1) {
5365			genderform = CSL.GENDERS[i];
5366			if (this.locale[lang_out].terms[termname][genderform]) {
5367				for (form in this.locale[lang_out].terms[termname]) {
5368					if (!this.locale[lang_out].terms[termname][genderform][form]) {
5369						this.locale[lang_out].terms[termname][genderform][form] = this.locale[lang_out].terms[termname][form];
5370					}
5371				}
5372			}
5373		}
5374	}
5375	nodes = this.sys.xml.getNodesByName(locale, 'style-options');
5376	for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
5377		if (true) {
5378			styleopts = nodes[pos];
5379			attributes = this.sys.xml.attributes(styleopts);
5380			for (attrname in attributes) {
5381				if (attributes.hasOwnProperty(attrname)) {
5382					if (attrname === "@punctuation-in-quote" || attrname === "@limit-day-ordinals-to-day-1") {
5383						if (attributes[attrname] === "true") {
5384							this.locale[lang_out].opts[attrname.slice(1)] = true;
5385						} else {
5386							this.locale[lang_out].opts[attrname.slice(1)] = false;
5387						}
5388					} else if (attrname === "@skip-words") {
5389						var skip_words = attributes[attrname].split(/\s*,\s*/);
5390						this.locale[lang_out].opts[attrname.slice(1)] = skip_words;
5391					} else if (attrname === "@leading-noise-words" && lang_in === lang_out) {
5392						var val = attributes[attrname].split(/\s*,\s*/);
5393						this.locale[lang_out].opts["leading-noise-words"] = val;
5394					} else if (attrname === "@name-as-sort-order") {
5395						this.locale[lang_out].opts["name-as-sort-order"] = {};
5396						var lst = attributes[attrname].split(/\s+/);
5397						for (var i=0,ilen=lst.length;i<ilen;i+=1) {
5398							this.locale[lang_out].opts["name-as-sort-order"][lst[i]] = true;
5399						}
5400					} else if (attrname === "@name-as-reverse-order") {
5401						this.locale[lang_out].opts["name-as-reverse-order"] = {};
5402						var lst = attributes[attrname].split(/\s+/);
5403						for (var i=0,ilen=lst.length;i<ilen;i+=1) {
5404							this.locale[lang_out].opts["name-as-reverse-order"][lst[i]] = true;
5405						}
5406					} else if (attrname === "@name-never-short") {
5407						this.locale[lang_out].opts["name-never-short"] = {};
5408						var lst = attributes[attrname].split(/\s+/);
5409						for (var i=0,ilen=lst.length;i<ilen;i+=1) {
5410							this.locale[lang_out].opts["name-never-short"][lst[i]] = true;
5411						}
5412					}
5413				}
5414			}
5415		}
5416	}
5417	nodes = this.sys.xml.getNodesByName(locale, 'date');
5418	for (pos = 0, len = this.sys.xml.numberofnodes(nodes); pos < len; pos += 1) {
5419		if (true) {
5420			date = nodes[pos];
5421			this.locale[lang_out].dates[this.sys.xml.getAttributeValue(date, "form")] = date;
5422		}
5423	}
5424};
5425CSL.Node = {};
5426CSL.Node.bibliography = {
5427	build: function (state, target) {
5428		if (this.tokentype === CSL.START) {
5429			state.build.area = "bibliography";
5430			state.build.root = "bibliography";
5431			state.fixOpt(this, "names-delimiter", "delimiter");
5432			state.fixOpt(this, "name-delimiter", "delimiter");
5433			state.fixOpt(this, "name-form", "form");
5434			state.fixOpt(this, "and", "and");
5435			state.fixOpt(this, "delimiter-precedes-last", "delimiter-precedes-last");
5436			state.fixOpt(this, "delimiter-precedes-et-al", "delimiter-precedes-et-al");
5437			state.fixOpt(this, "initialize-with", "initialize-with");
5438			state.fixOpt(this, "initialize", "initialize");
5439			state.fixOpt(this, "name-as-sort-order", "name-as-sort-order");
5440			state.fixOpt(this, "sort-separator", "sort-separator");
5441			state.fixOpt(this, "and", "and");
5442			state.fixOpt(this, "et-al-min", "et-al-min");
5443			state.fixOpt(this, "et-al-use-first", "et-al-use-first");
5444			state.fixOpt(this, "et-al-use-last", "et-al-use-last");
5445			state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min");
5446			state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first");
5447		}
5448		target.push(this);
5449	}
5450};
5451CSL.Node.choose = {
5452	build: function (state, target) {
5453		var func;
5454		if (this.tokentype === CSL.START) {
5455			func = function (state, Item) {
5456				state.tmp.jump.push(undefined, CSL.LITERAL);
5457			};
5458		}
5459		if (this.tokentype === CSL.END) {
5460			func = function (state, Item) {
5461				state.tmp.jump.pop();
5462			};
5463		}
5464		this.execs.push(func);
5465		target.push(this);
5466	},
5467	configure: function (state, pos) {
5468		if (this.tokentype === CSL.END) {
5469			state.configure.fail.push((pos));
5470			state.configure.succeed.push((pos));
5471		} else {
5472			state.configure.fail.pop();
5473			state.configure.succeed.pop();
5474		}
5475	}
5476};
5477CSL.Node.citation = {
5478	build: function (state, target) {
5479		if (this.tokentype === CSL.START) {
5480			state.fixOpt(this, "names-delimiter", "delimiter");
5481			state.fixOpt(this, "name-delimiter", "delimiter");
5482			state.fixOpt(this, "name-form", "form");
5483			state.fixOpt(this, "and", "and");
5484			state.fixOpt(this, "delimiter-precedes-last", "delimiter-precedes-last");
5485			state.fixOpt(this, "delimiter-precedes-et-al", "delimiter-precedes-et-al");
5486			state.fixOpt(this, "initialize-with", "initialize-with");
5487			state.fixOpt(this, "initialize", "initialize");
5488			state.fixOpt(this, "name-as-sort-order", "name-as-sort-order");
5489			state.fixOpt(this, "sort-separator", "sort-separator");
5490			state.fixOpt(this, "and", "and");
5491			state.fixOpt(this, "et-al-min", "et-al-min");
5492			state.fixOpt(this, "et-al-use-first", "et-al-use-first");
5493			state.fixOpt(this, "et-al-use-last", "et-al-use-last");
5494			state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min");
5495			state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first");
5496			state.build.area = "citation";
5497		}
5498		if (this.tokentype === CSL.END) {
5499			state.opt.grouped_sort = state.opt.xclass === "in-text"
5500				&& (state.citation.opt.collapse
5501					&& state.citation.opt.collapse.length)
5502				|| (state.citation.opt.cite_group_delimiter
5503					&& state.citation.opt.cite_group_delimiter.length)
5504				&& state.opt.update_mode !== CSL.POSITION
5505				&& state.opt.update_mode !== CSL.NUMERIC;
5506			if (state.opt.grouped_sort
5507				&& state.citation_sort.opt.sort_directions.length) {
5508				var firstkey = state.citation_sort.opt.sort_directions[0].slice();
5509				state.citation_sort.opt.sort_directions = [firstkey].concat(state.citation_sort.opt.sort_directions);
5510			}
5511			state.citation.srt = new CSL.Registry.Comparifier(state, "citation_sort");
5512		}
5513	}
5514};
5515CSL.Node["#comment"] = {
5516		 build: function (state, target) {
5517		 }
5518};
5519CSL.Node.date = {
5520	build: function (state, target) {
5521		var func, date_obj, tok, len, pos, part, dpx, parts, mypos, start, end;
5522		if (this.tokentype === CSL.START || this.tokentype === CSL.SINGLETON) {
5523			state.build.date_parts = [];
5524			state.build.date_variables = this.variables;
5525			if (!state.build.extension) {
5526				CSL.Util.substituteStart.call(this, state, target);
5527			}
5528			if (state.build.extension) {
5529				func = CSL.dateMacroAsSortKey;
5530			} else {
5531				func = function (state, Item, item) {
5532					var key, dp;
5533					state.tmp.element_rendered_ok = false;
5534					state.tmp.donesies = [];
5535					state.tmp.dateparts = [];
5536					dp = [];
5537					if (this.variables.length
5538						&& !(state.tmp.just_looking
5539							 && this.variables[0] !== "issued")) {
5540						state.parallel.StartVariable(this.variables[0]);
5541						date_obj = Item[this.variables[0]];
5542						if ("undefined" === typeof date_obj) {
5543							date_obj = {"date-parts": [[0]] };
5544							if (state.opt.development_extensions.locator_date_and_revision) {
5545								if (item && this.variables[0] === "locator-date" && item["locator-date"]) {
5546									date_obj = item["locator-date"];
5547								}
5548							}
5549						}
5550						state.tmp.date_object = date_obj;
5551						len = this.dateparts.length;
5552						for (pos = 0; pos < len; pos += 1) {
5553							part = this.dateparts[pos];
5554							if ("undefined" !== typeof state.tmp.date_object[(part +  "_end")]) {
5555								dp.push(part);
5556							} else if (part === "month" && "undefined" !== typeof state.tmp.date_object.season_end) {
5557								dp.push(part);
5558							}
5559						}
5560						dpx = [];
5561						parts = ["year", "month", "day"];
5562						len = parts.length;
5563						for (pos = 0; pos < len; pos += 1) {
5564							if (dp.indexOf(parts[pos]) > -1) {
5565								dpx.push(parts[pos]);
5566							}
5567						}
5568						dp = dpx.slice();
5569						mypos = 2;
5570						len = dp.length;
5571						for (pos = 0; pos < len; pos += 1) {
5572							part = dp[pos];
5573							start = state.tmp.date_object[part];
5574							end = state.tmp.date_object[(part + "_end")];
5575							if (start !== end) {
5576								mypos = pos;
5577								break;
5578							}
5579						}
5580						state.tmp.date_collapse_at = dp.slice(mypos);
5581					} else {
5582						state.tmp.date_object = false;
5583					}
5584				};
5585			}
5586			this.execs.push(func);
5587			func = function (state, Item) {
5588				state.output.startTag("date", this);
5589				if (this.variables[0] === "issued"
5590					&& Item.type === "legal_case"
5591					&& !state.tmp.extension
5592					&& "" + Item["collection-number"] === "" + state.tmp.date_object.year
5593					&& this.dateparts.length === 1
5594					&& this.dateparts[0] === "year") {
5595					for (var key in state.tmp.date_object) {
5596						if (state.tmp.date_object.hasOwnProperty(key)) {
5597							if (key.slice(0, 4) === "year") {
5598								state.tmp.issued_date = {};
5599								var lst = state.output.current.mystack.slice(-2)[0].blobs;
5600								state.tmp.issued_date.list = lst;
5601								state.tmp.issued_date.pos = lst.length - 1;
5602							}
5603						}
5604					}
5605				}
5606			};
5607			this.execs.push(func);
5608		}
5609		if (!state.build.extension && (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON)) {
5610			func = function (state, Item) {
5611				state.output.endTag();
5612				state.parallel.CloseVariable("date");
5613			};
5614			this.execs.push(func);
5615		}
5616		target.push(this);
5617		if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) {
5618			if (!state.build.extension) {
5619				CSL.Util.substituteEnd.call(this, state, target);
5620			}
5621		}
5622	}
5623};
5624CSL.Node["date-part"] = {
5625	build: function (state, target) {
5626		var func, pos, len, decor, first_date, value, value_end, real, have_collapsed, invoked, precondition, known_year, bc, ad, bc_end, ad_end, ready, curr, dcurr, number, num, formatter, item, i, ilen;
5627		if (!this.strings.form) {
5628			this.strings.form = "long";
5629		}
5630		state.build.date_parts.push(this.strings.name);
5631		var date_variable = state.build.date_variables[0];
5632		func = function (state, Item) {
5633			if (!state.tmp.date_object) {
5634				return;
5635			}
5636			first_date = true;
5637			value = "";
5638			value_end = "";
5639			state.tmp.donesies.push(this.strings.name);
5640			if (state.tmp.date_object.literal && "year" === this.strings.name) {
5641				state.parallel.AppendToVariable(state.tmp.date_object.literal);
5642				state.output.append(state.tmp.date_object.literal, this);
5643			}
5644			if (state.tmp.date_object) {
5645				value = state.tmp.date_object[this.strings.name];
5646				value_end = state.tmp.date_object[(this.strings.name + "_end")];
5647			}
5648			if ("year" === this.strings.name && value === 0 && !state.tmp.suppress_decorations) {
5649				value = false;
5650			}
5651			real = !state.tmp.suppress_decorations;
5652			have_collapsed = state.tmp.have_collapsed;
5653			invoked = state[state.tmp.area].opt.collapse === "year-suffix" || state[state.tmp.area].opt.collapse === "year-suffix-ranged";
5654			precondition = state.opt["disambiguate-add-year-suffix"];
5655			if (real && precondition && invoked) {
5656				state.tmp.years_used.push(value);
5657				known_year = state.tmp.last_years_used.length >= state.tmp.years_used.length;
5658				if (known_year && have_collapsed) {
5659					if (state.tmp.last_years_used[(state.tmp.years_used.length - 1)] === value) {
5660						value = false;
5661					}
5662				}
5663			}
5664			if ("undefined" !== typeof value) {
5665				bc = false;
5666				ad = false;
5667				bc_end = false;
5668				ad_end = false;
5669				if ("year" === this.strings.name) {
5670					if (parseInt(value, 10) < 500 && parseInt(value, 10) > 0) {
5671						ad = state.getTerm("ad");
5672					}
5673					if (parseInt(value, 10) < 0) {
5674						bc = state.getTerm("bc");
5675						value = (parseInt(value, 10) * -1);
5676					}
5677					if (value_end) {
5678						if (parseInt(value_end, 10) < 500 && parseInt(value_end, 10) > 0) {
5679							ad_end = state.getTerm("ad");
5680						}
5681						if (parseInt(value_end, 10) < 0) {
5682							bc_end = state.getTerm("bc");
5683							value_end = (parseInt(value_end, 10) * -1);
5684						}
5685					}
5686				}
5687				state.parallel.AppendToVariable(value);
5688				var monthnameid = ""+state.tmp.date_object.month;
5689				while (monthnameid.length < 2) {
5690					monthnameid = "0"+monthnameid;
5691				}
5692				monthnameid = "month-"+monthnameid;
5693				var gender = state.locale[state.opt.lang]["noun-genders"][monthnameid];
5694				if (this.strings.form) {
5695					var myform = this.strings.form;
5696					if (this.strings.name === "day") {
5697						if (myform === "ordinal"
5698							&& state.locale[state.opt.lang].opts["limit-day-ordinals-to-day-1"]
5699							&& ("" + value) !== "1") {
5700							myform = "numeric";
5701						}
5702					}
5703					value = CSL.Util.Dates[this.strings.name][myform](state, value, gender, ("accessed" === date_variable));
5704					if ("month" === this.strings.name) {
5705						if (state.tmp.strip_periods) {
5706							value = value.replace(/\./g, "");
5707						} else {
5708							for (i = 0, ilen = this.decorations.length; i < ilen; i += 1) {
5709								if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) {
5710									value = value.replace(/\./g, "");
5711									break;
5712								}
5713							}
5714						}
5715					}
5716					if (value_end) {
5717						value_end = CSL.Util.Dates[this.strings.name][myform](state, value_end, gender, ("accessed" === date_variable), "_end");
5718						if (state.tmp.strip_periods) {
5719							value_end = value_end.replace(/\./g, "");
5720						} else {
5721							for (i = 0, ilen = this.decorations.length; i < ilen; i += 1) {
5722								if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) {
5723									value_end = value_end.replace(/\./g, "");
5724									break;
5725								}
5726							}
5727						}
5728					}
5729				}
5730				state.output.openLevel("empty");
5731				if (state.tmp.date_collapse_at.length) {
5732					ready = true;
5733					len = state.tmp.date_collapse_at.length;
5734					for (pos = 0; pos < len; pos += 1) {
5735						item = state.tmp.date_collapse_at[pos];
5736						if (state.tmp.donesies.indexOf(item) === -1) {
5737							ready = false;
5738							break;
5739						}
5740					}
5741					if (ready) {
5742						if ("" + value_end !== "0") {
5743							if (state.dateput.queue.length === 0) {
5744								first_date = true;
5745							}
5746							if (state.opt["year-range-format"]
5747								&& state.opt["year-range-format"] !== "expanded"
5748								&& !state.tmp.date_object.day
5749								&& !state.tmp.date_object.month
5750								&& !state.tmp.date_object.season
5751								&& this.strings.name === "year"
5752								&& value && value_end) {
5753								value_end = state.fun.year_mangler(value + "-" + value_end, true);
5754								var range_delimiter = state.getTerm("year-range-delimiter");
5755								value_end = value_end.slice(value_end.indexOf(range_delimiter) + 1);
5756							}
5757							state.dateput.append(value_end, this);
5758							if (first_date) {
5759								state.dateput.current.value()[0].strings.prefix = "";
5760							}
5761						}
5762						state.output.append(value, this);
5763						curr = state.output.current.value();
5764						curr.blobs[(curr.blobs.length - 1)].strings.suffix = "";
5765						state.output.append(state.getTerm("year-range-delimiter"), "empty");
5766						dcurr = state.dateput.current.value();
5767						curr.blobs = curr.blobs.concat(dcurr);
5768						state.dateput.string(state, state.dateput.queue);
5769						state.tmp.date_collapse_at = [];
5770					} else {
5771						state.output.append(value, this);
5772						if (state.tmp.date_collapse_at.indexOf(this.strings.name) > -1) {
5773							if ("" + value_end !== "0") {
5774								if (state.dateput.queue.length === 0) {
5775									first_date = true;
5776								}
5777								state.dateput.openLevel("empty");
5778								state.dateput.append(value_end, this);
5779								if (first_date) {
5780									state.dateput.current.value().blobs[0].strings.prefix = "";
5781								}
5782								if (bc) {
5783									state.dateput.append(bc);
5784								}
5785								if (ad) {
5786									state.dateput.append(ad);
5787								}
5788								state.dateput.closeLevel();
5789							}
5790						}
5791					}
5792				} else {
5793					state.output.append(value, this);
5794				}
5795				if (bc) {
5796					state.output.append(bc);
5797				}
5798				if (ad) {
5799					state.output.append(ad);
5800				}
5801				state.output.closeLevel();
5802			} else if ("month" === this.strings.name) {
5803				if (state.tmp.date_object.season) {
5804					value = "" + state.tmp.date_object.season;
5805					if (value && value.match(/^[1-4]$/)) {
5806						state.tmp.group_context.replace([false, false, true]);
5807						state.output.append(state.getTerm(("season-0" + value)), this);
5808					} else if (value) {
5809						state.output.append(value, this);
5810					}
5811				}
5812			}
5813			state.tmp.value = [];
5814			if ((value || state.tmp.have_collapsed) && !state.opt.has_year_suffix && "year" === this.strings.name && !state.tmp.just_looking) {
5815				if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false && !state.tmp.has_done_year_suffix) {
5816					state.tmp.has_done_year_suffix = true;
5817					num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10);
5818					number = new CSL.NumericBlob(num, this, Item.id);
5819					this.successor_prefix = state[state.build.area].opt.layout_delimiter;
5820					this.splice_prefix = state[state.build.area].opt.layout_delimiter;
5821					formatter = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS);
5822					number.setFormatter(formatter);
5823					if (state[state.tmp.area].opt.collapse === "year-suffix-ranged") {
5824						number.range_prefix = state.getTerm("citation-range-delimiter");
5825					}
5826					if (state[state.tmp.area].opt["year-suffix-delimiter"]) {
5827						number.successor_prefix = state[state.tmp.area].opt["year-suffix-delimiter"];
5828					} else {
5829						number.successor_prefix = state[state.tmp.area].opt.layout_delimiter;
5830					}
5831					number.UGLY_DELIMITER_SUPPRESS_HACK = true;
5832					state.output.append(number, "literal");
5833				}
5834			}
5835		};
5836		this.execs.push(func);
5837		target.push(this);
5838	}
5839};
5840CSL.Node["else-if"] = {
5841	build: function (state, target) {
5842		CSL.Conditions.TopNode.call(this, state, target);
5843		target.push(this);
5844	},
5845	configure: function (state, pos) {
5846		CSL.Conditions.Configure.call(this, state, pos);
5847	}
5848};
5849CSL.Node["else"] = {
5850	build: function (state, target) {
5851		target.push(this);
5852	},
5853	configure: function (state, pos) {
5854		if (this.tokentype === CSL.START) {
5855			state.configure.fail[(state.configure.fail.length - 1)] = pos;
5856		}
5857	}
5858};
5859CSL.Node["et-al"] = {
5860	build: function (state, target) {
5861		if (state.build.area === "citation" || state.build.area === "bibliography") {
5862			var func = function (state, Item, item) {
5863				state.tmp.etal_node = this;
5864				if ("string" === typeof this.strings.term) {
5865					state.tmp.etal_term = this.strings.term;
5866				}
5867			}
5868			this.execs.push(func);
5869		}
5870		target.push(this);
5871	}
5872};
5873CSL.Node.group = {
5874	build: function (state, target) {
5875		var func, execs;
5876		if (this.tokentype === CSL.START) {
5877			CSL.Util.substituteStart.call(this, state, target);
5878			if (state.build.substitute_level.value()) {
5879				state.build.substitute_level.replace((state.build.substitute_level.value() + 1));
5880			}
5881			func = function (state, Item) {
5882				state.output.startTag("group", this);
5883				if (state.tmp.group_context.mystack.length) {
5884					state.output.current.value().parent = state.tmp.group_context.value()[4];
5885				}
5886				var label_form = state.tmp.group_context.value()[5];
5887				if (!label_form && this.strings.label_form_override) {
5888					label_form = this.strings.label_form_override;
5889				}
5890				state.tmp.group_context.push([false, false, false, false, state.output.current.value(), label_form, this.strings.set_parallel_condition], CSL.LITERAL);
5891				if (this.strings.oops) {
5892					state.tmp.group_context.value()[3] = this.strings.oops;
5893				}
5894			};
5895			execs = [];
5896			execs.push(func);
5897			this.execs = execs.concat(this.execs);
5898			if (this.strings["has-publisher-and-publisher-place"]) {
5899				state.build["publisher-special"] = true;
5900				func = function (state, Item) {
5901					if (this.strings["subgroup-delimiter"]
5902						&& Item.publisher && Item["publisher-place"]) {
5903						var publisher_lst = Item.publisher.split(/;\s*/);
5904						var publisher_place_lst = Item["publisher-place"].split(/;\s*/);
5905						if (publisher_lst.length > 1
5906							&& publisher_lst.length === publisher_place_lst.length) {
5907							state.publisherOutput = new CSL.PublisherOutput(state, this);
5908							state.publisherOutput["publisher-list"] = publisher_lst;
5909							state.publisherOutput["publisher-place-list"] = publisher_place_lst;
5910						}
5911					}
5912				};
5913				this.execs.push(func);
5914			}
5915		} else {
5916			if (state.build["publisher-special"]) {
5917				state.build["publisher-special"] = false;
5918				if ("string" === typeof state[state.build.root].opt["name-delimiter"]) {
5919					func = function (state, Item) {
5920						if (state.publisherOutput) {
5921							state.publisherOutput.render();
5922							state.publisherOutput = false;
5923						}
5924					};
5925					this.execs.push(func);
5926				}
5927			}
5928			func = function (state, Item) {
5929				var flag = state.tmp.group_context.pop();
5930				state.output.endTag();
5931				var upperflag = state.tmp.group_context.value();
5932				if (flag[1]) {
5933					state.tmp.group_context.value()[1] = true;
5934				}
5935				if (flag[2] || (flag[0] && !flag[1])) {
5936					state.tmp.group_context.value()[2] = true;
5937					var blobs = state.output.current.value().blobs;
5938					var pos = state.output.current.value().blobs.length - 1;
5939					if (!state.tmp.just_looking && "undefined" !== typeof flag[6]) {
5940						var parallel_condition_object = {
5941							blobs: blobs,
5942							conditions: flag[6],
5943							id: Item.id,
5944							pos: pos
5945						};
5946						state.parallel.parallel_conditional_blobs_list.push(parallel_condition_object);
5947					}
5948				} else {
5949					if (state.output.current.value().blobs) {
5950						state.output.current.value().blobs.pop();
5951					}
5952					if (state.tmp.group_context.value()[3]) {
5953						state.output.current.mystack[state.output.current.mystack.length - 2].strings.delimiter = state.tmp.group_context.value()[3];
5954					}
5955				}
5956			};
5957			this.execs.push(func);
5958		}
5959		target.push(this);
5960		if (this.tokentype === CSL.END) {
5961			if (state.build.substitute_level.value()) {
5962				state.build.substitute_level.replace((state.build.substitute_level.value() - 1));
5963			}
5964			CSL.Util.substituteEnd.call(this, state, target);
5965		}
5966	}
5967};
5968CSL.Node["if"] = {
5969	build: function (state, target) {
5970		CSL.Conditions.TopNode.call(this, state, target);
5971		target.push(this);
5972	},
5973	configure: function (state, pos) {
5974		CSL.Conditions.Configure.call(this, state, pos);
5975	}
5976};
5977CSL.Node["conditions"] = {
5978	build: function (state, target) {
5979		if (this.tokentype === CSL.START) {
5980			state.tmp.conditions.addMatch(this.match);
5981		}
5982		if (this.tokentype === CSL.END) {
5983			state.tmp.conditions.matchCombine();
5984		}
5985	}
5986};
5987CSL.Node["condition"] = {
5988	build: function (state, target) {
5989		if (this.tokentype === CSL.SINGLETON) {
5990			var test = state.fun.match[this.match](this, state, this.tests);
5991			state.tmp.conditions.addTest(test);
5992		}
5993	}
5994};
5995CSL.Conditions = {};
5996CSL.Conditions.TopNode = function (state, target) {
5997	var func;
5998	if (this.tokentype === CSL.START || this.tokentype === CSL.SINGLETON) {
5999		if (this.locale) {
6000			state.opt.lang = this.locale;
6001		}
6002		if (!this.tests || !this.tests.length) {
6003			state.tmp.conditions = new CSL.Conditions.Engine(state, this);
6004		} else {
6005			this.test = state.fun.match[this.match](this, state, this.tests);
6006		}
6007	}
6008	if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) {
6009		func = function (state, Item) {
6010			if (this.locale_default) {
6011				state.output.current.value().old_locale = this.locale_default;
6012				state.output.closeLevel("empty");
6013				state.opt.lang = this.locale_default;
6014			}
6015			var next = this[state.tmp.jump.value()];
6016			return next;
6017		};
6018		this.execs.push(func);
6019		if (this.locale_default) {
6020			state.opt.lang = this.locale_default;
6021		}
6022	}
6023};
6024CSL.Conditions.Configure = function (state, pos) {
6025	if (this.tokentype === CSL.START) {
6026		this.fail = state.configure.fail.slice(-1)[0];
6027		this.succeed = this.next;
6028		state.configure.fail[(state.configure.fail.length - 1)] = pos;
6029	} else if (this.tokentype === CSL.SINGLETON) {
6030		this.fail = this.next;
6031		this.succeed = state.configure.succeed.slice(-1)[0];
6032		state.configure.fail[(state.configure.fail.length - 1)] = pos;
6033	} else {
6034		this.succeed = state.configure.succeed.slice(-1)[0];
6035		this.fail = this.next;
6036	}
6037};
6038CSL.Conditions.Engine = function (state, token) {
6039	this.token = token;
6040	this.state = state;
6041};
6042CSL.Conditions.Engine.prototype.addTest = function (test) {
6043	this.token.tests.push(test);
6044};
6045CSL.Conditions.Engine.prototype.addMatch = function (match) {
6046	this.token.match = match;
6047};
6048CSL.Conditions.Engine.prototype.matchCombine = function () {
6049	this.token.test = this.state.fun.match[this.token.match](this.token, this.state, this.token.tests);
6050};
6051CSL.Node.info = {
6052	build: function (state, target) {
6053		if (this.tokentype === CSL.START) {
6054			state.build.skip = "info";
6055		} else {
6056			state.build.skip = false;
6057		}
6058	}
6059};
6060CSL.Node.institution = {
6061	build: function (state, target) {
6062		if ([CSL.SINGLETON, CSL.START].indexOf(this.tokentype) > -1) {
6063			var func = function (state, Item) {
6064				if ("string" === typeof state.build.name_delimiter && !this.strings.delimiter) {
6065					this.strings.delimiter = state.tmp.name_delimiter;
6066				}
6067				var myand, and_default_prefix, and_suffix;
6068				if ("text" === this.strings.and) {
6069					this.and_term = state.getTerm("and", "long", 0);
6070				} else if ("symbol" === this.strings.and) {
6071					if (state.opt.development_extensions.expect_and_symbol_form) {
6072						this.and_term = state.getTerm("and", "symbol", 0);
6073					} else {
6074						this.and_term = "&";
6075					}
6076				} else if ("none" === this.strings.and) {
6077					this.and_term = this.strings.delimiter;
6078				}
6079				if ("undefined" === typeof this.and_term && state.tmp.and_term) {
6080					this.and_term = state.getTerm("and", "long", 0);
6081				}
6082				if (CSL.STARTSWITH_ROMANESQUE_REGEXP.test(this.and_term)) {
6083					this.and_prefix_single = " ";
6084					this.and_prefix_multiple = ", ";
6085					if ("string" === typeof this.strings.delimiter) {
6086						this.and_prefix_multiple = this.strings.delimiter;
6087					}
6088					this.and_suffix = " ";
6089				} else {
6090					this.and_prefix_single = "";
6091					this.and_prefix_multiple = "";
6092					this.and_suffix = "";
6093				}
6094				if (this.strings["delimiter-precedes-last"] === "always") {
6095					this.and_prefix_single = this.strings.delimiter;
6096				} else if (this.strings["delimiter-precedes-last"] === "never") {
6097					if (this.and_prefix_multiple) {
6098						this.and_prefix_multiple = " ";
6099					}
6100				}
6101				this.and = {};
6102				if ("undefined" !== typeof this.and_term) {
6103					state.output.append(this.and_term, "empty", true);
6104					this.and.single = state.output.pop();
6105					this.and.single.strings.prefix = this.and_prefix_single;
6106					this.and.single.strings.suffix = this.and_suffix;
6107					state.output.append(this.and_term, "empty", true);
6108					this.and.multiple = state.output.pop();
6109					this.and.multiple.strings.prefix = this.and_prefix_multiple;
6110					this.and.multiple.strings.suffix = this.and_suffix;
6111				} else if ("undefined" !== this.strings.delimiter) {
6112					this.and.single = new CSL.Blob(this.strings.delimiter);
6113					this.and.single.strings.prefix = "";
6114					this.and.single.strings.suffix = "";
6115					this.and.multiple = new CSL.Blob(this.strings.delimiter);
6116					this.and.multiple.strings.prefix = "";
6117					this.and.multiple.strings.suffix = "";
6118				}
6119				state.nameOutput.institution = this;
6120			};
6121			this.execs.push(func);
6122		}
6123		target.push(this);
6124	},
6125	configure: function (state, pos) {
6126		if ([CSL.SINGLETON, CSL.START].indexOf(this.tokentype) > -1) {
6127			state.build.has_institution = true;
6128		}
6129	}
6130};
6131CSL.Node["institution-part"] = {
6132	build: function (state, target) {
6133		var func;
6134		if ("long" === this.strings.name) {
6135			if (this.strings["if-short"]) {
6136				func = function (state, Item) {
6137					state.nameOutput.institutionpart["long-with-short"] = this;
6138				};
6139			} else {
6140				func = function (state, Item) {
6141					state.nameOutput.institutionpart["long"] = this;
6142				};
6143			}
6144		} else if ("short" === this.strings.name) {
6145			func = function (state, Item) {
6146				state.nameOutput.institutionpart["short"] = this;
6147			};
6148		}
6149		this.execs.push(func);
6150		target.push(this);
6151	}
6152};
6153CSL.Node.key = {
6154	build: function (state, target) {
6155		var func, i, ilen;
6156		var debug = false;
6157		var start_key = new CSL.Token("key", CSL.START);
6158		start_key.strings["et-al-min"] = this.strings["et-al-min"];
6159		start_key.strings["et-al-use-first"] = this.strings["et-al-use-first"];
6160		start_key.strings["et-al-use-last"] = this.strings["et-al-use-last"];
6161		func = function (state, Item) {
6162			state.tmp.done_vars = [];
6163		};
6164		start_key.execs.push(func);
6165		state.opt.citation_number_sort_direction = this.strings.sort_direction;
6166		func = function (state, Item) {
6167			state.output.openLevel("empty");
6168		};
6169		start_key.execs.push(func);
6170		var sort_direction = [];
6171		if (this.strings.sort_direction === CSL.DESCENDING) {
6172			sort_direction.push(1);
6173			sort_direction.push(-1);
6174		} else {
6175			sort_direction.push(-1);
6176			sort_direction.push(1);
6177		}
6178		state[state.build.area].opt.sort_directions.push(sort_direction);
6179		if (CSL.DATE_VARIABLES.indexOf(this.variables[0]) > -1) {
6180			state.build.date_key = true;
6181		}
6182		func = function (state, Item) {
6183			state.tmp.sort_key_flag = true;
6184			if (this.strings["et-al-min"]) {
6185				state.tmp["et-al-min"] = this.strings["et-al-min"];
6186			}
6187			if (this.strings["et-al-use-first"]) {
6188				state.tmp["et-al-use-first"] = this.strings["et-al-use-first"];
6189			}
6190			if ("boolean" === typeof this.strings["et-al-use-last"]) {
6191				state.tmp["et-al-use-last"] = this.strings["et-al-use-last"];
6192			}
6193		};
6194		start_key.execs.push(func);
6195		target.push(start_key);
6196		if (this.variables.length) {
6197			var variable = this.variables[0];
6198			if (variable === "citation-number") {
6199				if (state.build.area === "citation_sort") {
6200					state.opt.citation_number_sort = true;
6201				}
6202				if (state.build.area === "bibliography_sort") {
6203					state.opt.citation_number_sort_used = true;
6204				}
6205			}
6206			if (CSL.CREATORS.indexOf(variable) > -1) {
6207				var names_start_token = new CSL.Token("names", CSL.START);
6208				names_start_token.tokentype = CSL.START;
6209				names_start_token.variables = this.variables;
6210				CSL.Node.names.build.call(names_start_token, state, target);
6211				var name_token = new CSL.Token("name", CSL.SINGLETON);
6212				name_token.tokentype = CSL.SINGLETON;
6213				name_token.strings["name-as-sort-order"] = "all";
6214				name_token.strings["sort-separator"] = " ";
6215				name_token.strings["et-al-use-last"] = this.strings["et-al-use-last"];
6216				name_token.strings["et-al-min"] = this.strings["et-al-min"];
6217				name_token.strings["et-al-use-first"] = this.strings["et-al-use-first"];
6218				CSL.Node.name.build.call(name_token, state, target);
6219				var institution_token = new CSL.Token("institution", CSL.SINGLETON);
6220				institution_token.tokentype = CSL.SINGLETON;
6221				CSL.Node.institution.build.call(institution_token, state, target);
6222				var names_end_token = new CSL.Token("names", CSL.END);
6223				names_end_token.tokentype = CSL.END;
6224				CSL.Node.names.build.call(names_end_token, state, target);
6225			} else {
6226				var single_text = new CSL.Token("text", CSL.SINGLETON);
6227				single_text.dateparts = this.dateparts;
6228				if (CSL.NUMERIC_VARIABLES.indexOf(variable) > -1) {
6229					func = function (state, Item) {
6230						var num, m;
6231						num = false;
6232						if ("citation-number" === variable) {
6233							num = state.registry.registry[Item.id].seq.toString();
6234						} else {
6235							num = Item[variable];
6236						}
6237						if (num) {
6238							num = CSL.Util.padding(num);
6239						}
6240						state.output.append(num, this);
6241					};
6242				} else if (variable === "citation-label") {
6243					func = function (state, Item) {
6244						var trigraph = state.getCitationLabel(Item);
6245						state.output.append(trigraph, this);
6246					};
6247				} else if (CSL.DATE_VARIABLES.indexOf(variable) > -1) {
6248					func = CSL.dateAsSortKey;
6249					single_text.variables = this.variables;
6250				} else if ("title" === variable) {
6251					var abbrevfam = "title";
6252					var abbrfall = false;
6253					var altvar = false;
6254					var transfall = true;
6255					func = state.transform.getOutputFunction(this.variables, abbrevfam, abbrfall, altvar, transfall);
6256				} else {
6257					func = function (state, Item) {
6258						var varval = Item[variable];
6259						state.output.append(varval, "empty");
6260					};
6261				}
6262				single_text.execs.push(func);
6263				target.push(single_text);
6264			}
6265		} else { // macro
6266			var token = new CSL.Token("text", CSL.SINGLETON);
6267			token.postponed_macro = this.postponed_macro;
6268			CSL.expandMacro.call(state, token);
6269		}
6270		var end_key = new CSL.Token("key", CSL.END);
6271		func = function (state, Item) {
6272			var keystring = state.output.string(state, state.output.queue);
6273			if (state.sys.normalizeUnicode) {
6274				keystring = state.sys.normalizeUnicode(keystring);
6275			}
6276			if ("" === keystring) {
6277				keystring = undefined;
6278			}
6279			if ("string" !== typeof keystring || state.tmp.empty_date) {
6280				keystring = undefined;
6281				state.tmp.empty_date = false;
6282			}
6283			state[state.tmp.area].keys.push(keystring);
6284			state.tmp.value = [];
6285		};
6286		end_key.execs.push(func);
6287		if (state.build.date_key) {
6288			if (state.build.area === "citation_sort") {
6289				state[state.build.area].opt.sort_directions.push([-1,1]);
6290				func = function (state, Item) {
6291					var year_suffix = state.registry.registry[Item.id].disambig.year_suffix;
6292					if (!year_suffix) {
6293						year_suffix = 0;
6294					}
6295					var key = CSL.Util.padding("" + year_suffix);
6296					state[state.tmp.area].keys.push(key);
6297				}
6298				end_key.execs.push(func);
6299			}
6300			state.build.date_key = false;
6301		}
6302		func = function (state, Item) {
6303			state.tmp["et-al-min"] = undefined;
6304			state.tmp["et-al-use-first"] = undefined;
6305			state.tmp["et-al-use-last"] = undefined;
6306			state.tmp.sort_key_flag = false;
6307		};
6308		end_key.execs.push(func);
6309		target.push(end_key);
6310	}
6311};
6312CSL.Node.label = {
6313	build: function (state, target) {
6314		var debug = false;
6315		if (this.strings.term) {
6316			var plural = false;
6317			if (!this.strings.form) {
6318				this.strings.form = "long";
6319			}
6320			var func = function (state, Item, item) {
6321				var termtxt = CSL.evaluateLabel(this, state, Item, item);
6322				if (item && this.strings.term === "locator") {
6323					state.parallel.StartVariable("label");
6324					state.parallel.AppendToVariable(item.label);
6325					item.section_form_override = this.strings.form;
6326				}
6327				state.output.append(termtxt, this);
6328				if (item && this.strings.term === "locator") {
6329					state.parallel.CloseVariable();
6330				}
6331			};
6332			this.execs.push(func);
6333		} else {
6334			var namevars = state.build.names_variables.slice(-1)[0];
6335			if (!state.build.name_label) {
6336				state.build.name_label = {};
6337			}
6338			for (var i = 0, ilen = namevars.length; i < ilen; i += 1) {
6339				if (!state.build.name_label[namevars[i]]) {
6340					state.build.name_label[namevars[i]] = {};
6341				}
6342			}
6343			if (!state.build.name_flag) {
6344				for (var i = 0, ilen = namevars.length; i < ilen; i += 1) {
6345					state.build.name_label[namevars[i]].before = this;
6346				}
6347			} else {
6348				for (var i = 0, ilen = namevars.length; i < ilen; i += 1) {
6349					state.build.name_label[namevars[i]].after = this;
6350				}
6351			}
6352		}
6353		target.push(this);
6354	}
6355};
6356CSL.Node.layout = {
6357	build: function (state, target) {
6358		var func, prefix_token, suffix_token, tok;
6359		if (this.tokentype === CSL.START) {
6360			func = function (state, Item, item) {
6361				if (state.opt.development_extensions.apply_citation_wrapper
6362					&& state.sys.wrapCitationEntry
6363					&& !state.tmp.just_looking
6364					&& Item.system_id
6365					&& state.tmp.area === "citation") {
6366					cite_entry = new CSL.Token("group", CSL.START);
6367					cite_entry.decorations = [["@cite", "entry"]];
6368					state.output.startTag("cite_entry", cite_entry);
6369					state.output.current.value().item_id = Item.system_id;
6370					if (item) {
6371						state.output.current.value().locator_txt = item.locator_txt;
6372						state.output.current.value().suffix_txt = item.suffix_txt;
6373					}
6374				}
6375			}
6376			this.execs.push(func);
6377		}
6378		if (this.tokentype === CSL.START && !state.tmp.cite_affixes[state.build.area]) {
6379			func = function (state, Item) {
6380				state.tmp.done_vars = [];
6381				if (!state.tmp.just_looking && state.registry.registry[Item.id].parallel) {
6382					state.tmp.done_vars.push("first-reference-note-number");
6383				}
6384				state.tmp.rendered_name = false;
6385				state.tmp.name_node = {};
6386			};
6387			this.execs.push(func);
6388			func = function (state, Item) {
6389				state.tmp.sort_key_flag = false;
6390			};
6391			this.execs.push(func);
6392			func = function (state, Item) {
6393				state.tmp.nameset_counter = 0;
6394			};
6395			this.execs.push(func);
6396			func = function (state, Item) {
6397				var tok = "empty";
6398				if (state.opt.development_extensions.rtl_support) {
6399					if (["ar", "he", "fa", "ur", "yi", "ps", "syr"].indexOf(Item.language) > -1) {
6400						tok = new CSL.Token();
6401						tok.strings.prefix = "\u202b";
6402						tok.strings.suffix = "\u202c";
6403					}
6404				}
6405				state.output.openLevel(tok);
6406			}
6407			this.execs.push(func);
6408			target.push(this);
6409			if (state.opt.development_extensions.rtl_support && false) {
6410				this.strings.prefix = this.strings.prefix.replace(/\((.|$)/g,"(\u200e$1");
6411				this.strings.suffix = this.strings.suffix.replace(/\)(.|$)/g,")\u200e$1");
6412			}
6413			if (state.build.area === "citation") {
6414				prefix_token = new CSL.Token("text", CSL.SINGLETON);
6415				func = function (state, Item, item) {
6416					var sp;
6417					if (item && item.prefix) {
6418						sp = "";
6419						var test_prefix = item.prefix.replace(/<[^>]+>/g, "").replace(/["'\u201d\u2019\u00bb\u202f\u00a0 ]+$/g,"");
6420						var test_char = test_prefix.slice(-1);
6421						if (test_prefix.match(CSL.ENDSWITH_ROMANESQUE_REGEXP)) {
6422							sp = " ";
6423						} else if (CSL.TERMINAL_PUNCTUATION.slice(0,-1).indexOf(test_char) > -1) {
6424							sp = " ";
6425						} else if (test_char.match(/[\)\],0-9]/)) {
6426							sp = " ";
6427						}
6428						var ignorePredecessor = false;
6429						if (CSL.TERMINAL_PUNCTUATION.slice(0,-1).indexOf(test_char) > -1 && item.prefix.indexOf(" ") > -1) {
6430							state.tmp.term_predecessor = false;
6431							ignorePredecessor = true;
6432						}
6433						prefix = (item.prefix + sp).replace(/\s+/g, " ");
6434						state.output.append(prefix, this, false, ignorePredecessor);
6435					}
6436				};
6437				prefix_token.execs.push(func);
6438				target.push(prefix_token);
6439			}
6440		}
6441		var my_tok;
6442		if (this.locale_raw) {
6443			my_tok = new CSL.Token("dummy", CSL.START);
6444			my_tok.locale = this.locale_raw;
6445			my_tok.strings.delimiter = this.strings.delimiter;
6446			my_tok.strings.suffix = this.strings.suffix;
6447			if (!state.tmp.cite_affixes[state.build.area]) {
6448				state.tmp.cite_affixes[state.build.area] = {};
6449			}
6450		}
6451		if (this.tokentype === CSL.START) {
6452			state.build.layout_flag = true;
6453			if (!this.locale_raw) {
6454				state[state.tmp.area].opt.topdecor = [this.decorations];
6455				state[(state.tmp.area + "_sort")].opt.topdecor = [this.decorations];
6456				state[state.build.area].opt.layout_prefix = this.strings.prefix;
6457				state[state.build.area].opt.layout_suffix = this.strings.suffix;
6458				state[state.build.area].opt.layout_delimiter = this.strings.delimiter;
6459				state[state.build.area].opt.layout_decorations = this.decorations;
6460				if (state.tmp.cite_affixes[state.build.area]) {
6461					tok = new CSL.Token("else", CSL.START);
6462					CSL.Node["else"].build.call(tok, state, target);
6463				}
6464			} // !this.locale_raw
6465			if (this.locale_raw) {
6466				if (!state.build.layout_locale_flag) {
6467					var choose_tok = new CSL.Token("choose", CSL.START);
6468					CSL.Node.choose.build.call(choose_tok, state, target);
6469					my_tok.name = "if";
6470					CSL.Attributes["@locale-internal"].call(my_tok, state, this.locale_raw);
6471					CSL.Node["if"].build.call(my_tok, state, target);
6472				} else {
6473					my_tok.name = "else-if";
6474					CSL.Attributes["@locale-internal"].call(my_tok, state, this.locale_raw);
6475					CSL.Node["else-if"].build.call(my_tok, state, target);
6476				}
6477				state.tmp.cite_affixes[state.build.area][my_tok.locale] = {};
6478				state.tmp.cite_affixes[state.build.area][my_tok.locale].delimiter = this.strings.delimiter;
6479				state.tmp.cite_affixes[state.build.area][my_tok.locale].suffix = this.strings.suffix;
6480			}
6481		}
6482		if (this.tokentype === CSL.END) {
6483			if (this.locale_raw) {
6484				if (!state.build.layout_locale_flag) {
6485					my_tok.name = "if";
6486					my_tok.tokentype = CSL.END;
6487					CSL.Attributes["@locale-internal"].call(my_tok, state, this.locale_raw);
6488					CSL.Node["if"].build.call(my_tok, state, target);
6489					state.build.layout_locale_flag = true;
6490				} else {
6491					my_tok.name = "else-if";
6492					my_tok.tokentype = CSL.END;
6493					CSL.Attributes["@locale-internal"].call(my_tok, state, this.locale_raw);
6494					CSL.Node["else-if"].build.call(my_tok, state, target);
6495				}
6496			}
6497			if (!this.locale_raw) {
6498				if (state.tmp.cite_affixes[state.build.area]) {
6499					if (state.build.layout_locale_flag) {
6500						tok = new CSL.Token("else", CSL.END);
6501						CSL.Node["else"].build.call(tok, state, target);
6502						tok = new CSL.Token("choose", CSL.END);
6503						CSL.Node.choose.build.call(tok, state, target);
6504					}
6505				}
6506				state.build_layout_locale_flag = true;
6507				if (state.build.area === "citation") {
6508					suffix_token = new CSL.Token("text", CSL.SINGLETON);
6509					func = function (state, Item, item) {
6510						var sp;
6511						if (item && item.suffix) {
6512							sp = "";
6513							if (item.suffix.match(CSL.STARTSWITH_ROMANESQUE_REGEXP)
6514								|| ['[','('].indexOf(item.suffix.slice(0,1)) > -1) {
6515								sp = " ";
6516							}
6517							state.output.append((sp + item.suffix), this);
6518						}
6519					};
6520					suffix_token.execs.push(func);
6521					target.push(suffix_token);
6522				}
6523				func = function (state, Item) {
6524					if (state.tmp.area === "bibliography") {
6525						if (state.bibliography.opt["second-field-align"]) {
6526							state.output.endTag();
6527						}
6528					}
6529					state.output.closeLevel();
6530				};
6531				this.execs.push(func);
6532				func = function (state, Item) {
6533					if (state.opt.development_extensions.apply_citation_wrapper
6534						&& state.sys.wrapCitationEntry
6535						&& !state.tmp.just_looking
6536						&& Item.system_id
6537						&& state.tmp.area === "citation") {
6538						state.output.endTag();
6538 // closes citation link wrapper
6539					}
6540				}
6541				this.execs.push(func);
6542				target.push(this);
6543				state.build.layout_flag = false;
6544				state.build.layout_locale_flag = false;
6545			} // !this.layout_raw
6546		}
6547	}
6548};
6549CSL.Node.macro = {
6550	build: function (state, target) {}
6551};
6552CSL.NameOutput = function(state, Item, item, variables) {
6553	this.debug = false;
6554	this.state = state;
6555	this.Item = Item;
6556	this.item = item;
6557	this.nameset_base = 0;
6558	this.etal_spec = {};
6559	this._first_creator_variable = false;
6560	this._please_chop = false;
6561};
6562CSL.NameOutput.prototype.init = function (names) {
6563	if (this.state.tmp.term_predecessor) {
6564		this.state.tmp.subsequent_author_substitute_ok = false;
6565	}
6566	if (this.nameset_offset) {
6567		this.nameset_base = this.nameset_base + this.nameset_offset;
6568	}
6569	this.nameset_offset = 0;
6570	this.names = names;
6571	this.variables = names.variables;
6572	this.state.tmp.value = [];
6573	this.state.tmp.rendered_name = [];
6574	this.state.tmp.label_blob = false;
6575	this.state.tmp.etal_node = false;
6576	this.state.tmp.etal_term = false;
6577	for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) {
6578		if (this.Item[this.variables[i]] && this.Item[this.variables[i]].length) {
6579			this.state.tmp.value = this.state.tmp.value.concat(this.Item[this.variables[i]]);
6580		}
6581	}
6582	this["et-al"] = undefined;
6583	this["with"] = undefined;
6584	this.name = undefined;
6585	this.institutionpart = {};
6586	this.state.tmp.group_context.value()[1] = true;
6587	if (!this.state.tmp.value.length) {
6588		return;
6589	}
6590};
6591CSL.NameOutput.prototype.reinit = function (names) {
6592	if (this.state.tmp.can_substitute.value()) {
6593		this.nameset_offset = 0;
6594		this.variables = names.variables;
6595		var oldval = this.state.tmp.value.slice();
6596		this.state.tmp.value = [];
6597		for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) {
6598			if (this.Item[this.variables[i]] && this.Item[this.variables[i]].length) {
6599				this.state.tmp.value = this.state.tmp.value.concat(this.Item[this.variables[i]]);
6600			}
6601		}
6602		if (this.state.tmp.value.length) {
6603			this.state.tmp.can_substitute.replace(false, CSL.LITERAL);
6604		}
6605		this.state.tmp.value = oldval;
6606	}
6607};
6608CSL.NameOutput.prototype.outputNames = function () {
6609	var i, ilen;
6610	var variables = this.variables;
6611	if (this.institution.and) {
6612		if (!this.institution.and.single.blobs || !this.institution.and.single.blobs.length) {
6613			this.institution.and.single.blobs = this.name.and.single.blobs;
6614		}
6615		if (!this.institution.and.multiple.blobs || !this.institution.and.multiple.blobs.length) {
6616			this.institution.and.multiple.blobs = this.name.and.multiple.blobs;
6617		}
6618	}
6619	this.variable_offset = {};
6620	if (this.family) {
6621		this.family_decor = CSL.Util.cloneToken(this.family);
6622		this.family_decor.strings.prefix = "";
6623		this.family_decor.strings.suffix = "";
6624		for (i = 0, ilen = this.family.execs.length; i < ilen; i += 1) {
6625			this.family.execs[i].call(this.family_decor, this.state, this.Item);
6626		}
6627	} else {
6628		this.family_decor = false;
6629	}
6630	if (this.given) {
6631		this.given_decor = CSL.Util.cloneToken(this.given);
6632		this.given_decor.strings.prefix = "";
6633		this.given_decor.strings.suffix = "";
6634		for (i = 0, ilen = this.given.execs.length; i < ilen; i += 1) {
6635			this.given.execs[i].call(this.given_decor, this.state, this.Item);
6636		}
6637	} else {
6638		this.given_decor = false;
6639	}
6640	this.getEtAlConfig();
6641	this.divideAndTransliterateNames();
6642	this.truncatePersonalNameLists();
6643	this.disambigNames();
6644	this.constrainNames();
6645	if (this.name.strings.form === "count") {
6646		if (this.state.tmp.extension || this.names_count != 0) {
6647			this.state.output.append(this.names_count, "empty");
6648			this.state.tmp.group_context.value()[2] = true;
6649		}
6650		return;
6651	}
6652	this.setEtAlParameters();
6653	this.setCommonTerm();
6654	this.state.tmp.name_node = {};
6655	this.state.tmp.name_node.children = [];
6656	this.renderAllNames();
6657	var blob_list = [];
6658	for (i = 0, ilen = variables.length; i < ilen; i += 1) {
6659		var v = variables[i];
6660		var institution_sets = [];
6661		var institutions = false;
6662		for (var j = 0, jlen = this.institutions[v].length; j < jlen; j += 1) {
6663			institution_sets.push(this.joinPersonsAndInstitutions([this.persons[v][j], this.institutions[v][j]]));
6664		}
6665		if (this.institutions[v].length) {
6666			var pos = this.nameset_base + this.variable_offset[v];
6667			if (this.freeters[v].length) {
6668				pos += 1;
6669			}
6670			institutions = this.joinInstitutionSets(institution_sets, pos);
6671		}
6672		var varblob = this.joinFreetersAndInstitutionSets([this.freeters[v], institutions]);
6673		if (varblob) {
6674			if (this.state.tmp.area.slice(-5) !== "_sort") {
6675				varblob = this._applyLabels(varblob, v);
6676			}
6677			blob_list.push(varblob);
6678		}
6679		if (this.common_term) {
6680			break;
6681		}
6682	}
6683	this.state.output.openLevel("empty");
6684	this.state.output.current.value().strings.delimiter = this.names.strings.delimiter;
6685	for (i = 0, ilen = blob_list.length; i < ilen; i += 1) {
6686		this.state.output.append(blob_list[i], "literal", true);
6687	}
6688	this.state.output.closeLevel("empty");
6689	var blob = this.state.output.pop();
6690	this.state.output.append(blob, this.names);
6691	if (this.state.tmp.term_predecessor_name) {
6692		this.state.tmp.term_predecessor = true;
6693	}
6694	this.state.tmp.name_node.top = this.state.output.current.value();
6695	if (variables[0] !== "authority") {
6696		var name_node_string = [];
6697		var nameobjs = this.Item[variables[0]];
6698		if (nameobjs) {
6699			for (var i = 0, ilen = nameobjs.length; i < ilen; i += 1) {
6700				substring = CSL.Util.Names.getRawName(nameobjs[i]);
6701				if (substring) {
6702					name_node_string.push(substring);
6703				}
6704			}
6705		}
6706		name_node_string = name_node_string.join(", ");
6707		if (name_node_string) {
6708			this.state.tmp.name_node.string = name_node_string;
6709		}
6710	}
6711	if (this.state.tmp.name_node.string && !this.state.tmp.first_name_string) {
6712		this.state.tmp.first_name_string = this.state.tmp.name_node.string;
6713	}
6714	if ("classic" === this.Item.type) {
6715		var author_title = [];
6716		if (this.state.tmp.first_name_string) {
6717			author_title.push(this.state.tmp.first_name_string);
6718		}
6719		if (this.Item.title) {
6720			author_title.push(this.Item.title);
6721		}
6722		author_title = author_title.join(", ");
6723		if (author_title && this.state.sys.getAbbreviation) {
6724			this.state.transform.loadAbbreviation("default", "classic", author_title);
6725			if (this.state.transform.abbrevs["default"].classic[author_title]) {
6726				this.state.tmp.done_vars.push("title");
6727				this.state.output.append(this.state.transform.abbrevs["default"].classic[author_title], "empty", true);
6728				blob = this.state.output.pop();
6729				this.state.tmp.name_node.top.blobs.pop();
6730				this.state.tmp.name_node.top.blobs.push(blob);
6731			}
6732		}
6733	}
6734	this._collapseAuthor();
6735	this.variables = [];
6736};
6737CSL.NameOutput.prototype._applyLabels = function (blob, v) {
6738	var txt;
6739	if (!this.label || !this.label[v]) {
6740		return blob;
6741	}
6742	var plural = 0;
6743	var num = this.freeters_count[v] + this.institutions_count[v];
6744	if (num > 1) {
6745		plural = 1;
6746	} else {
6747		for (var i = 0, ilen = this.persons[v].length; i < ilen; i += 1) {
6748			num += this.persons_count[v][i];
6749		}
6750		if (num > 1) {
6751			plural = 1;
6752		}
6753	}
6754	if (this.label[v].before) {
6755		if ("number" === typeof this.label[v].before.strings.plural) {
6756			plural = this.label[v].before.strings.plural;
6757		}
6758		txt = this._buildLabel(v, plural, "before", v);
6759		this.state.output.openLevel("empty");
6760		this.state.output.append(txt, this.label[v].before, true);
6761		this.state.output.append(blob, "literal", true);
6762		this.state.output.closeLevel("empty");
6763		blob = this.state.output.pop();
6764	}
6765	if (this.label[v].after) {
6766		if ("number" === typeof this.label[v].after.strings.plural) {
6767			plural = this.label[v].after.strings.plural;
6768		}
6769		txt = this._buildLabel(v, plural, "after", v);
6770		this.state.output.openLevel("empty");
6771		this.state.output.append(blob, "literal", true);
6772		this.state.output.append(txt, this.label[v].after, true);
6773		this.state.tmp.label_blob = this.state.output.pop();
6774		this.state.output.append(this.state.tmp.label_blob,"literal",true);
6775		this.state.output.closeLevel("empty");
6776		blob = this.state.output.pop();
6777	}
6778	return blob;
6779};
6780CSL.NameOutput.prototype._buildLabel = function (term, plural, position, v) {
6781	if (this.common_term) {
6782		term = this.common_term;
6783	}
6784	var ret = false;
6785	var node = this.label[v][position];
6786	if (node) {
6787		ret = CSL.castLabel(this.state, node, term, plural, CSL.TOLERANT);
6788	}
6789	return ret;
6790};
6791CSL.NameOutput.prototype._collapseAuthor = function () {
6792	var myqueue, mystr, oldchars;
6793	if (this.nameset_base === 0 && this.Item[this.variables[0]] && !this._first_creator_variable) {
6794		this._first_creator_variable = this.variables[0];
6795	}
6796	if ((this.item && this.item["suppress-author"] && this._first_creator_variable == this.variables[0])
6797		|| (this.state[this.state.tmp.area].opt.collapse
6798			&& this.state[this.state.tmp.area].opt.collapse.length)
6799		|| (this.state[this.state.tmp.area].opt.cite_group_delimiter
6800			&& this.state[this.state.tmp.area].opt.cite_group_delimiter.length)) {
6801		if (this.state.tmp.authorstring_request) {
6802			mystr = "";
6803			myqueue = this.state.tmp.name_node.top.blobs.slice(-1)[0].blobs;
6804			oldchars = this.state.tmp.offset_characters;
6805			if (myqueue) {
6806				mystr = this.state.output.string(this.state, myqueue, false);
6807			}
6808			this.state.tmp.offset_characters = oldchars;
6809			this.state.registry.authorstrings[this.Item.id] = mystr;
6810		} else if (!this.state.tmp.just_looking
6811					 && !this.state.tmp.suppress_decorations && (this.item["suppress-author"] || (this.state[this.state.tmp.area].opt.collapse && this.state[this.state.tmp.area].opt.collapse.length) || this.state[this.state.tmp.area].opt.cite_group_delimiter && this.state[this.state.tmp.area].opt.cite_group_delimiter)) {
6812			mystr = "";
6813			myqueue = this.state.tmp.name_node.top.blobs.slice(-1)[0].blobs;
6814			oldchars = this.state.tmp.offset_characters;
6815			if (myqueue) {
6816				mystr = this.state.output.string(this.state, myqueue, false);
6817			}
6818			if (mystr === this.state.tmp.last_primary_names_string) {
6819				if (this.item["suppress-author"] || (this.state[this.state.tmp.area].opt.collapse && this.state[this.state.tmp.area].opt.collapse.length)) {
6820					this.state.tmp.name_node.top.blobs.pop();
6821					this.state.tmp.name_node.children = [];
6822					this.state.tmp.offset_characters = oldchars;
6823				}
6824				if (this.state[this.state.tmp.area].opt.cite_group_delimiter && this.state[this.state.tmp.area].opt.cite_group_delimiter) {
6825					this.state.tmp.use_cite_group_delimiter = true;
6826				}
6827			} else {
6828				this.state.tmp.last_primary_names_string = mystr;
6829				if (this.variables.indexOf(this._first_creator_variable) > -1 && this.item && this.item["suppress-author"] && this.Item.type !== "legal_case") {
6830					this.state.tmp.name_node.top.blobs.pop();
6831					this.state.tmp.name_node.children = [];
6832					this.state.tmp.offset_characters = oldchars;
6833					this.state.tmp.term_predecessor = false;
6834				}
6835				this.state.tmp.have_collapsed = false;
6836				if (this.state[this.state.tmp.area].opt.cite_group_delimiter && this.state[this.state.tmp.area].opt.cite_group_delimiter) {
6837					this.state.tmp.use_cite_group_delimiter = false;
6838				}
6839			}
6840		}
6841	}
6842};
6843CSL.NameOutput.prototype.isPerson = function (value) {
6844	if (value.literal
6845		|| (!value.given && value.family && value.isInstitution)) {
6846		return false;
6847	} else {
6848		return true;
6849	}
6850};
6851CSL.NameOutput.prototype.truncatePersonalNameLists = function () {
6852	var v, i, ilen, j, jlen, chopvar, values;
6853	this.freeters_count = {};
6854	this.persons_count = {};
6855	this.institutions_count = {};
6856	for (v in this.freeters) {
6857		if (this.freeters.hasOwnProperty(v)) {
6858			this.freeters_count[v] = this.freeters[v].length;
6859			this.freeters[v] = this._truncateNameList(this.freeters, v);
6860		}
6861	}
6862	for (v in this.persons) {
6863		if (this.persons.hasOwnProperty(v)) {
6864			this.institutions_count[v] = this.institutions[v].length;
6865			this._truncateNameList(this.institutions, v);
6866			this.persons[v] = this.persons[v].slice(0, this.institutions[v].length);
6867			this.persons_count[v] = [];
6868			for (j = 0, jlen = this.persons[v].length; j < jlen; j += 1) {
6869				this.persons_count[v][j] = this.persons[v][j].length;
6870				this.persons[v][j] = this._truncateNameList(this.persons, v, j);
6871			}
6872		}
6873	}
6874	if (this.etal_min === 1 && this.etal_use_first === 1
6875		&& !(this.state.tmp.extension
6876			 || this.state.tmp.just_looking)) {
6877		chopvar = v;
6878	} else {
6879		chopvar = false;
6880	}
6881	if (chopvar || this._please_chop) {
6882		for (i = 0, ilen = this.variables.length; i < ilen; i += 1) {
6883			v = this.variables[i];
6884			if (this.freeters[v].length) {
6885				if (this._please_chop === v) {
6886					this.freeters[v] = this.freeters[v].slice(1);
6887					this.freeters_count[v] += -1;
6888					this._please_chop = false;
6889				} else if (chopvar && !this._please_chop) {
6890					this.freeters[v] = this.freeters[v].slice(0, 1);
6891					this.freeters_count[v] = 1;
6892					this.institutions[v] = [];
6893					this.persons[v] = [];
6894					this._please_chop = chopvar;
6895				}
6896			}
6897			for (i = 0, ilen = this.persons[v].length; i < ilen; i += 1) {
6898				if (this.persons[v][i].length) {
6899					if (this._please_chop === v) {
6900						this.persons[v][i] = this.persons[v][i].slice(1);
6901						this.persons_count[v][i] += -1;
6902						this._please_chop = false;
6903						break;
6904					} else if (chopvar && !this._please_chop) {
6905						this.freeters[v] = this.persons[v][i].slice(0, 1);
6906						this.freeters_count[v] = 1;
6907						this.institutions[v] = [];
6908						this.persons[v] = [];
6909						values = [];
6910						this._please_chop = chopvar;
6911						break;
6912					}
6913				}
6914			}
6915			if (this.institutions[v].length) {
6916				if (this._please_chop === v) {
6917					this.institutions[v] = this.institutions[v].slice(1);
6918					this.institutions_count[v] += -1;
6919					this._please_chop = false;
6920				} else if (chopvar && !this._please_chop) {
6921					this.institutions[v] = this.institutions[v].slice(0, 1);
6922					this.institutions_count[v] = 1;
6923					values = [];
6924					this._please_chop = chopvar;
6925				}
6926			}
6927		}
6928	}
6929	for (i = 0, ilen = this.variables.length; i < ilen; i += 1) {
6930		if (this.institutions[v].length) {
6931			this.nameset_offset += 1;
6932		}
6933		for (i = 0, ilen = this.persons[v].length; i < ilen; i += 1) {
6934			if (this.persons[v][i].length) {
6935				this.nameset_offset += 1;
6936			}
6937		}
6938	}
6939};
6940CSL.NameOutput.prototype._truncateNameList = function (container, variable, index) {
6941	var lst;
6942	if ("undefined" === typeof index) {
6943		lst = container[variable];
6944	} else {
6945		lst = container[variable][index];
6946	}
6947	if (this.state[this.state[this.state.tmp.area].root].opt.max_number_of_names
6948		&& lst.length > 50
6949		&& lst.length > (this.state[this.state[this.state.tmp.area].root].opt.max_number_of_names + 2)) {
6950		lst = lst.slice(0, this.state[this.state[this.state.tmp.area].root].opt.max_number_of_names + 2);
6951	}
6952	return lst;
6953};
6954CSL.NameOutput.prototype.divideAndTransliterateNames = function () {
6955	var i, ilen, j, jlen;
6956	var Item = this.Item;
6957	var variables = this.variables;
6958	this.varnames = variables.slice();
6959	this.freeters = {};
6960	this.persons = {};
6961	this.institutions = {};
6962	for (i = 0, ilen = variables.length; i < ilen; i += 1) {
6963		var v = variables[i];
6964		this.variable_offset[v] = this.nameset_offset;
6965		var values = this._normalizeVariableValue(Item, v);
6966		if (this.name.strings["suppress-min"] && values.length >= this.name.strings["suppress-min"]) {
6967			values = [];
6968		}
6969		if (this.name.strings["suppress-max"] && values.length <= this.name.strings["suppress-max"]) {
6970			values = [];
6971		}
6972		this._getFreeters(v, values);
6973		this._getPersonsAndInstitutions(v, values);
6974		if (this.name.strings["suppress-min"] === 0) {
6975			this.freeters[v] = [];
6976			for (j = 0, jlen = this.persons[v].length; j < jlen; j += 1) {
6977				this.persons[v][j] = [];
6978			}
6979		} else if (this.institution.strings["suppress-min"] === 0) {
6980			this.institutions[v] = [];
6981			this.freeters[v] = this.freeters[v].concat(this.persons[v]);
6982			for (j = 0, jlen = this.persons[v].length; j < jlen; j += 1) {
6983				for (var k = 0, klen = this.persons[v][j].length; k < klen; k += 1) {
6984					this.freeters[v].push(this.persons[v][j][k]);
6985				}
6986			}
6987			this.persons[v] = [];
6988		}
6989	}
6990};
6991CSL.NameOutput.prototype._normalizeVariableValue = function (Item, variable) {
6992	var names, name, i, ilen;
6993	if ("string" === typeof Item[variable]) {
6994		names = [{literal: Item[variable]}];
6995	} else if (!Item[variable]) {
6996		names = [];
6997	} else {
6998		names = Item[variable].slice();
6999	}
7000	return names;
7001};
7002CSL.NameOutput.prototype._getFreeters = function (v, values) {
7003	this.freeters[v] = [];
7004	for (var i = values.length - 1; i > -1; i += -1) {
7005		if (this.isPerson(values[i])) {
7006			var value = this._checkNickname(values.pop());
7007			if (value) {
7008				this.freeters[v].push(value);
7009			}
7010		} else {
7011			break;
7012		}
7013	}
7014	this.freeters[v].reverse();
7015	if (this.freeters[v].length) {
7016		this.nameset_offset += 1;
7017	}
7018};
7019CSL.NameOutput.prototype._getPersonsAndInstitutions = function (v, values) {
7020	this.persons[v] = [];
7021	this.institutions[v] = [];
7022	var persons = [];
7023	var has_affiliates = false;
7024	var first = true;
7025	for (var i = values.length - 1; i > -1; i += -1) {
7026		if (this.isPerson(values[i])) {
7027			var value = this._checkNickname(values[i]);
7028			if (value) {
7029				persons.push(value);
7030			}
7031		} else {
7032			has_affiliates = true;
7033			this.institutions[v].push(values[i]);
7034			if (!first) {
7035				persons.reverse();
7036				this.persons[v].push(persons);
7037				persons = [];
7038			}
7039			first = false;
7040		}
7041	}
7042	if (has_affiliates) {
7043		persons.reverse();
7044		this.persons[v].push(persons);
7045		this.persons[v].reverse();
7046		this.institutions[v].reverse();
7047	}
7048};
7049CSL.NameOutput.prototype._clearValues = function (values) {
7050	for (var i = values.length - 1; i > -1; i += -1) {
7051		values.pop();
7052	}
7053};
7054CSL.NameOutput.prototype._checkNickname = function (name) {
7055	if (["interview", "personal_communication"].indexOf(this.Item.type) > -1) {
7056		var author = "";
7057		author = CSL.Util.Names.getRawName(name);
7058		if (author && this.state.sys.getAbbreviation && !(this.item && this.item["suppress-author"])) {
7059			this.state.transform.loadAbbreviation("default", "nickname", author);
7060			var myLocalName = this.state.transform.abbrevs["default"].nickname[author];
7061			if (myLocalName) {
7062				if (myLocalName === "!here>>>") {
7063					name = false;
7064				} else {
7065					name = {family:myLocalName,given:''};
7066				}
7067			}
7068		}
7069	}
7070	return name;
7071};
7072CSL.NameOutput.prototype.joinPersons = function (blobs, pos, j) {
7073	var ret;
7074	if ("undefined" === typeof j) {
7075		if (this.etal_spec[pos].freeters === 1) {
7076			ret = this._joinEtAl(blobs, "name");
7077		} else if (this.etal_spec[pos].freeters === 2) {
7078			ret = this._joinEllipsis(blobs, "name");
7079		} else if (!this.state.tmp.sort_key_flag) {
7080			ret = this._joinAnd(blobs, "name");
7081		} else {
7082			ret = this._join(blobs, " ");
7083		}
7084	} else {
7085		if (this.etal_spec[pos].persons[j] === 1) {
7086			ret = this._joinEtAl(blobs, "name");
7087		} else if (this.etal_spec[pos].persons[j] === 2) {
7088			ret = this._joinEllipsis(blobs, "name");
7089		} else if (!this.state.tmp.sort_key_flag) {
7090			ret = this._joinAnd(blobs, "name");
7091		} else {
7092			ret = this._join(blobs, " ");
7093		}
7094	}
7095	return ret;
7096};
7097CSL.NameOutput.prototype.joinInstitutionSets = function (blobs, pos) {
7098	var ret;
7099	if (this.etal_spec[pos].institutions === 1) {
7100		ret = this._joinEtAl(blobs, "institution");
7101	} else if (this.etal_spec[pos].institutions === 2) {
7102		ret = this._joinEllipsis(blobs, "institution");
7103	} else {
7104		ret = this._joinAnd(blobs, "institution");
7105	}
7106	return ret;
7107};
7108CSL.NameOutput.prototype.joinPersonsAndInstitutions = function (blobs) {
7109	return this._join(blobs, this.name.strings.delimiter);
7110};
7111CSL.NameOutput.prototype.joinFreetersAndInstitutionSets = function (blobs) {
7112	var ret = this._join(blobs, "[never here]", this["with"].single, this["with"].multiple);
7113	return ret;
7114};
7115CSL.NameOutput.prototype._joinEtAl = function (blobs, tokenname) {
7116	var blob = this._join(blobs, this.name.strings.delimiter);
7117	this.state.output.openLevel(this._getToken(tokenname));
7118	this.state.output.current.value().strings.delimiter = "";
7119	this.state.output.append(blob, "literal", true);
7120	if (blobs.length > 1) {
7121		this.state.output.append(this["et-al"].multiple, "literal", true);
7122	} else if (blobs.length === 1) {
7123		this.state.output.append(this["et-al"].single, "literal", true);
7124	}
7125	this.state.output.closeLevel();
7126	return this.state.output.pop();
7127};
7128CSL.NameOutput.prototype._joinEllipsis = function (blobs, tokenname) {
7129	return this._join(blobs, this.name.strings.delimiter, this.name.ellipsis.single, this.name.ellipsis.multiple, tokenname);
7130};
7131CSL.NameOutput.prototype._joinAnd = function (blobs, tokenname) {
7132	return this._join(blobs, this[tokenname].strings.delimiter, this[tokenname].and.single, this[tokenname].and.multiple, tokenname);
7133};
7134CSL.NameOutput.prototype._join = function (blobs, delimiter, single, multiple, tokenname) {
7135	var i, ilen;
7136	if (!blobs) {
7137		return false;
7138	}
7139	for (i = blobs.length - 1; i > -1; i += -1) {
7140		if (!blobs[i] || blobs[i].length === 0 || !blobs[i].blobs.length) {
7141			blobs = blobs.slice(0, i).concat(blobs.slice(i + 1));
7142		}
7143	}
7144	if (!blobs.length) {
7145		return false;
7146	} else if (single && blobs.length === 2) {
7147		if (single) {
7148			single = new CSL.Blob(single.blobs,single);
7149		}
7150		blobs = [blobs[0], single, blobs[1]];
7151	} else {
7152		var delimiter_offset;
7153		if (multiple) {
7154			delimiter_offset = 2;
7155		} else {
7156			delimiter_offset = 1;
7157		}
7158		for (i = 0, ilen = blobs.length - delimiter_offset; i < ilen; i += 1) {
7159			blobs[i].strings.suffix += delimiter;
7160		}
7161		if (blobs.length > 1) {
7162			var blob = blobs.pop();
7163			if (multiple) {
7164				multiple = new CSL.Blob(multiple.blobs,multiple);
7165				blobs.push(multiple);
7166			} else {
7167				if (single) {
7168					single = new CSL.Blob(single.blobs,single);
7169				}
7170				blobs.push(single);
7171			}
7172			blobs.push(blob);
7173		}
7174	}
7175	this.state.output.openLevel(this._getToken(tokenname));
7176	if (single && multiple) {
vendor: 13,049 bytes, lines 7177-7544
7177		this.state.output.current.value().strings.delimiter = "";
7178	}
7179	for (i = 0, ilen = blobs.length; i < ilen; i += 1) {
7180		this.state.output.append(blobs[i], false, true);
7181	}
7182	this.state.output.closeLevel();
7183	return this.state.output.pop();
7184};
7185CSL.NameOutput.prototype._getToken = function (tokenname) {
7186	var token = this[tokenname];
7187	if (tokenname === "institution") {
7188		var newtoken = new CSL.Token();
7189		return newtoken;
7190	}
7191	return token;
7192};
7193CSL.NameOutput.prototype.setCommonTerm = function () {
7194	var variables = this.variables;
7195	var varnames = variables.slice();
7196	varnames.sort();
7197	this.common_term = varnames.join("");
7198	if (!this.common_term) {
7199		return false;
7200	}
7201	var has_term = false;
7202	if (this.label && this.label[this.variables[0]]) {
7203		if (this.label[this.variables[0]].before) {
7204			has_term = this.state.getTerm(this.common_term, this.label[this.variables[0]].before.strings.form, 0);
7205		} else if (this.label[this.variables[0]].after) {
7206			has_term = this.state.getTerm(this.common_term, this.label[this.variables[0]].after.strings.form, 0);
7207		}
7208	}
7209	if (!this.state.locale[this.state.opt.lang].terms[this.common_term]
7210		|| !has_term
7211		|| this.variables.length < 2) {
7212		this.common_term = false;
7213		return;
7214	}
7215	var freeters_offset = 0;
7216	for (var i = 0, ilen = this.variables.length - 1; i < ilen; i += 1) {
7217		var v = this.variables[i];
7218		var vv = this.variables[i + 1];
7219		if (this.freeters[v].length || this.freeters[vv].length) {
7220			if (this.etal_spec[v].freeters !== this.etal_spec[vv].freeters
7221				|| !this._compareNamesets(this.freeters[v], this.freeters[vv])) {
7222				this.common_term = false;
7223				return;
7224			}
7225			freeters_offset += 1;
7226		}
7227		if (this.persons[v].length !== this.persons[vv].length) {
7228			this.common_term = false;
7229			return;
7230		}
7231		for (var j = 0, jlen = this.persons[v].length; j < jlen; j += 1) {
7232			if (this.etal_spec[v].persons[j] !== this.etal_spec[vv].persons[j]
7233				|| !this._compareNamesets(this.persons[v][j], this.persons[vv][j])) {
7234				this.common_term = false;
7235				return;
7236			}
7237		}
7238	}
7239};
7240CSL.NameOutput.prototype._compareNamesets = function (base_nameset, nameset) {
7241	if (base_nameset.length !== nameset.length) {
7242		return false;
7243	}
7244	for (var i = 0, ilen = nameset.length; i < ilen; i += 1) {
7245		var name = nameset[i];
7246		for (var j = 0, jlen = CSL.NAME_PARTS.length; j < jlen; j += 1) {
7247			var part = CSL.NAME_PARTS[j];
7248			if (!base_nameset[i] || base_nameset[i][part] != nameset[i][part]) {
7249				return false;
7250			}
7251		}
7252	}
7253	return true;
7254};
7255CSL.NameOutput.prototype.constrainNames = function () {
7256	this.names_count = 0;
7257	var pos;
7258	for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) {
7259		var v = this.variables[i];
7260		pos = this.nameset_base + i;
7261		if (this.freeters[v].length) {
7262			this.state.tmp.names_max.push(this.freeters[v].length, "literal");
7263			this._imposeNameConstraints(this.freeters, this.freeters_count, v, pos);
7264			this.names_count += this.freeters[v].length;
7265		}
7266		if (this.institutions[v].length) {
7267			this.state.tmp.names_max.push(this.institutions[v].length, "literal");
7268			this._imposeNameConstraints(this.institutions, this.institutions_count, v, pos);
7269			this.persons[v] = this.persons[v].slice(0, this.institutions[v].length);
7270			this.names_count += this.institutions[v].length;
7271		}
7272		for (var j = 0, jlen = this.persons[v].length; j < jlen; j += 1) {
7273			if (this.persons[v][j].length) {
7274				this.state.tmp.names_max.push(this.persons[v][j].length, "literal");
7275				this._imposeNameConstraints(this.persons[v], this.persons_count[v], j, pos);
7276				this.names_count += this.persons[v][j].length;
7277			}
7278		}
7279	}
7280};
7281CSL.NameOutput.prototype._imposeNameConstraints = function (lst, count, key, pos) {
7282	var display_names = lst[key];
7283	var discretionary_names_length = this.state.tmp["et-al-min"];
7284	if (this.state.tmp.suppress_decorations) {
7285		if (this.state.tmp.disambig_request && this.state.tmp.disambig_request.names[pos]) {
7286			discretionary_names_length = this.state.tmp.disambig_request.names[pos];
7287		} else if (count[key] >= this.etal_min) {
7288			discretionary_names_length = this.etal_use_first;
7289		}
7290	} else {
7291		if (this.state.tmp.disambig_request
7292			&& this.state.tmp.disambig_request.names[pos] > this.etal_use_first) {
7293			if (count[key] < this.etal_min) {
7294				discretionary_names_length = count[key];
7295			} else {
7296				discretionary_names_length = this.state.tmp.disambig_request.names[pos];
7297			}
7298		} else if (count[key] >= this.etal_min) {
7299			discretionary_names_length = this.etal_use_first;
7300		}
7301		if (this.etal_use_last && discretionary_names_length > (this.etal_min - 2)) {
7302			discretionary_names_length = this.etal_min - 2;
7303		}
7304	}
7305	var sane = this.etal_min >= this.etal_use_first;
7306	var overlength = count[key] > discretionary_names_length;
7307	if (discretionary_names_length > count[key]) {
7308		discretionary_names_length = display_names.length;
7309	}
7310	if (sane && overlength) {
7311		if (this.etal_use_last) {
7312			lst[key] = display_names.slice(0, discretionary_names_length).concat(display_names.slice(-1));
7313		} else {
7314			lst[key] = display_names.slice(0, discretionary_names_length);
7315		}
7316	}
7317	this.state.tmp.disambig_settings.names[pos] = lst[key].length;
7318	this.state.disambiguate.padBase(this.state.tmp.disambig_settings);
7319};
7320CSL.NameOutput.prototype.disambigNames = function () {
7321	var pos;
7322	for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) {
7323		var v = this.variables[i];
7324		pos = this.nameset_base + i;
7325		if (this.freeters[v].length) {
7326			this._runDisambigNames(this.freeters[v], pos);
7327		}
7328		if (this.institutions[v].length) {
7329			if ("undefined" === typeof this.state.tmp.disambig_settings.givens[pos]) {
7330				this.state.tmp.disambig_settings.givens[pos] = [];
7331			}
7332			for (var j=0,jlen=this.institutions[v].length;j<jlen;j+=1) {
7333				if ("undefined" === typeof this.state.tmp.disambig_settings.givens[pos][j]) {
7334					this.state.tmp.disambig_settings.givens[pos].push(2);
7335				}
7336			}
7337		}
7338		for (var j = 0, jlen = this.persons[v].length; j < jlen; j += 1) {
7339			if (this.persons[v][j].length) {
7340				this._runDisambigNames(this.persons[v][j], pos);
7341			}
7342		}
7343	}
7344};
7345CSL.NameOutput.prototype._runDisambigNames = function (lst, pos) {
7346	var chk, myform, myinitials, param, i, ilen, paramx;
7347	for (i = 0, ilen = lst.length; i < ilen; i += 1) {
7348		if (!lst[i].given && !lst[i].family) {
7349			continue;
7350		}
7351		myinitials = this.name.strings["initialize-with"];
7352		this.state.registry.namereg.addname("" + this.Item.id, lst[i], i);
7353		chk = this.state.tmp.disambig_settings.givens[pos];
7354		if ("undefined" === typeof chk) {
7355			for (var j = 0, jlen = pos + 1; j < jlen; j += 1) {
7356				if (!this.state.tmp.disambig_settings.givens[j]) {
7357					this.state.tmp.disambig_settings.givens[j] = [];
7358				}
7359			}
7360		}
7361		chk = this.state.tmp.disambig_settings.givens[pos][i];
7362		if ("undefined" === typeof chk) {
7363			myform = this.name.strings.form;
7364			param = this.state.registry.namereg.evalname("" + this.Item.id, lst[i], i, 0, myform, myinitials);
7365			this.state.tmp.disambig_settings.givens[pos].push(param);
7366		}
7367		myform = this.name.strings.form;
7368		paramx = this.state.registry.namereg.evalname("" + this.Item.id, lst[i], i, 0, myform, myinitials);
7369		if (this.state.tmp.disambig_request) {
7370			var val = this.state.tmp.disambig_settings.givens[pos][i];
7371			if (val === 1 &&
7372				this.state.citation.opt["givenname-disambiguation-rule"] === "by-cite" &&
7373				("undefined" === typeof this.name.strings["initialize-with"]
7374				 || "undefined" === typeof lst[i].given)) {
7375				val = 2;
7376			}
7377			param = val;
7378			if (this.state.opt["disambiguate-add-givenname"] && lst[i].given) {
7379				param = this.state.registry.namereg.evalname("" + this.Item.id, lst[i], i, param, this.name.strings.form, this.name.strings["initialize-with"]);
7380			}
7381		} else {
7382			param = paramx;
7383		}
7384		if (!this.state.tmp.just_looking && this.item && this.item.position === CSL.POSITION_FIRST) {
7385			if (paramx > param) {
7386				param = paramx;
7387			}
7388		}
7389		if (!this.state.tmp.sort_key_flag) {
7390			this.state.tmp.disambig_settings.givens[pos][i] = param;
7391			if ("string" === typeof myinitials
7392				&& ("undefined" === typeof this.name.strings["initialize"]
7393					|| true === this.name.strings["initialize"])) {
7394				this.state.tmp.disambig_settings.use_initials = true;
7395			}
7396		}
7397	}
7398};
7399CSL.NameOutput.prototype.getEtAlConfig = function () {
7400	var item = this.item;
7401	this["et-al"] = {};
7402	this.state.output.append(this.etal_term, this.etal_style, true);
7403	this["et-al"].single = this.state.output.pop();
7404	this["et-al"].single.strings.suffix = this.etal_suffix;
7405	this["et-al"].single.strings.prefix = this.etal_prefix_single;
7406	this.state.output.append(this.etal_term, this.etal_style, true);
7407	this["et-al"].multiple = this.state.output.pop();
7408	this["et-al"].multiple.strings.suffix = this.etal_suffix;
7409	this["et-al"].multiple.strings.prefix = this.etal_prefix_multiple;
7410	if ("undefined" === typeof item) {
7411		item = {};
7412	}
7413	if (item.position) {
7414		if (this.name.strings["et-al-subsequent-min"]) {
7415			this.etal_min = this.name.strings["et-al-subsequent-min"];
7416		} else {
7417			this.etal_min = this.name.strings["et-al-min"];
7418		}
7419		if (this.name.strings["et-al-subsequent-use-first"]) {
7420			this.etal_use_first = this.name.strings["et-al-subsequent-use-first"];
7421		} else {
7422			this.etal_use_first = this.name.strings["et-al-use-first"];
7423		}
7424	} else {
7425		if (this.state.tmp["et-al-min"]) {
7426			this.etal_min = this.state.tmp["et-al-min"];
7427		} else {
7428			this.etal_min = this.name.strings["et-al-min"];
7429		}
7430		if (this.state.tmp["et-al-use-first"]) {
7431			this.etal_use_first = this.state.tmp["et-al-use-first"];
7432		} else {
7433			this.etal_use_first = this.name.strings["et-al-use-first"];
7434		}
7435		if ("boolean" === typeof this.state.tmp["et-al-use-last"]) {
7436			this.etal_use_last = this.state.tmp["et-al-use-last"];
7437		} else {
7438			this.etal_use_last = this.name.strings["et-al-use-last"];
7439		}
7440	}
7441	if (!this.state.tmp["et-al-min"]) {
7442		this.state.tmp["et-al-min"] = this.etal_min;
7443	}
7444};
7445CSL.NameOutput.prototype.setEtAlParameters = function () {
7446	var i, ilen, j, jlen;
7447	for (i = 0, ilen = this.variables.length; i < ilen; i += 1) {
7448		var v = this.variables[i];
7449		if ("undefined" === typeof this.etal_spec[v]) {
7450			this.etal_spec[v] = {freeters:0,institutions:0,persons:[]};
7451		}
7452		this.etal_spec[this.nameset_base + i] = this.etal_spec[v];
7453		if (this.freeters[v].length) {
7454			this._setEtAlParameter("freeters", v);
7455		}
7456		for (j = 0, jlen = this.persons[v].length; j < jlen; j += 1) {
7457			if ("undefined" === typeof this.etal_spec[v][j]) {
7458				this.etal_spec[v].persons[j] = 0;
7459			}
7460			this._setEtAlParameter("persons", v, j);
7461		}
7462		if (this.institutions[v].length) {
7463			this._setEtAlParameter("institutions", v);
7464		}
7465	}
7466};
7467CSL.NameOutput.prototype._setEtAlParameter = function (type, v, j) {
7468	var lst, count;
7469	if (type === "persons") {
7470		lst = this.persons[v][j];
7471		count = this.persons_count[v][j];
7472	} else {
7473		lst = this[type][v];
7474		count = this[type + "_count"][v];
7475	}
7476	if (lst.length < count && !this.state.tmp.sort_key_flag) {
7477		if (this.etal_use_last) {
7478			if (type === "persons") {
7479				this.etal_spec[v].persons[j] = 2
7480			} else {
7481				this.etal_spec[v][type] = 2;
7482			}
7483		} else {
7484			if (type === "persons") {
7485				this.etal_spec[v].persons[j] = 1;
7486			} else {
7487				this.etal_spec[v][type] = 1;
7488			}
7489		}
7490	} else {
7491		if (type === "persons") {
7492			this.etal_spec[v].persons[j] = 0;
7493		} else {
7494			this.etal_spec[v][type] = 0;
7495		}
7496	}
7497};
7498CSL.NameOutput.prototype.renderAllNames = function () {
7499	var pos;
7500	for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) {
7501		var v = this.variables[i];
7502		pos = this.nameset_base + i;
7503		if (this.freeters[v].length) {
7504			this.freeters[v] = this._renderPersonalNames(this.freeters[v], pos);
7505		}
7506		for (var j = 0, jlen = this.institutions[v].length; j < jlen; j += 1) {
7507			this.persons[v][j] = this._renderPersonalNames(this.persons[v][j], pos, j);
7508		}
7509	}
7510	this.renderInstitutionNames();
7511};
7512CSL.NameOutput.prototype.renderInstitutionNames = function () {
7513	for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) {
7514		var v = this.variables[i];
7515		for (var j = 0, jlen = this.institutions[v].length; j < jlen; j += 1) {
7516			var institution, institution_short, institution_long, short_style, long_style;
7517			var name = this.institutions[v][j];
7518			var j, ret, optLangTag, jlen, key, localesets;
7519			if (this.state.tmp.extension) {
7520				localesets = ["sort"];
7521			} else if (name.isInstitution) {
7522				localesets = this.state.opt['cite-lang-prefs'].institutions;
7523			} else {
7524				localesets = this.state.opt['cite-lang-prefs'].persons;
7525			}
7526			slot = {primary:'locale-orig',secondary:false,tertiary:false};
7527			if (localesets) {
7528				var slotnames = ["primary", "secondary", "tertiary"];
7529				for (var k = 0, klen = slotnames.length; k < klen; k += 1) {
7530					if (localesets.length - 1 <  k) {
7531						break;
7532					}
7533					if (localesets[k]) {
7534						slot[slotnames[k]] = 'locale-' + localesets[k];
7535					}
7536				}
7537			} else {
7538				slot.primary = 'locale-translat';
7539			}
7540			if (this.state.tmp.area !== "bibliography"
7541				&& !(this.state.tmp.area === "citation"
7542					 && this.state.opt.xclass === "note"
7543					 && this.item && !this.item.position)) {
7544				slot.secondary = false;
7545				slot.tertiary = false;
7546			}
7547			var res;
7548			this.setRenderedName(name);
7549			res = this.getName(name, slot.primary, true);
7550			var primary = res.name;
7551			var usedOrig = res.usedOrig;
7552			if (primary) {
7553				primary = this.fixupInstitution(primary, v, j);
7554			}
7555			secondary = false;
7556			if (slot.secondary) {
7557				res = this.getName(name, slot.secondary, false, usedOrig);
7558				secondary = res.name;
7559				usedOrig = res.usedOrig;
7560				if (secondary) {
7561					secondary = this.fixupInstitution(secondary, v, j);
7562				}
7563			}
7564			tertiary = false;
7565			if (slot.tertiary) {
7566				res = this.getName(name, slot.tertiary, false, usedOrig);
7567				tertiary = res.name;
7568				if (tertiary) {
7569					tertiary = this.fixupInstitution(tertiary, v, j);
7570				}
7571			}
7572			switch (this.institution.strings["institution-parts"]) {
7573			case "short":
7574				if (primary["short"].length) {
7575					short_style = this._getShortStyle();
7576					institution = [this._renderOneInstitutionPart(primary["short"], short_style)];
7577				} else {
7578					long_style = this._getLongStyle(primary, v, j);
7579					institution = [this._renderOneInstitutionPart(primary["long"], long_style)];
7580				}
7581				break;
7582			case "short-long":
7583				long_style = this._getLongStyle(primary, v, j);
7584				short_style = this._getShortStyle();
7585				institution_short = this._renderOneInstitutionPart(primary["short"], short_style);
7586				institution_long = this._composeOneInstitutionPart([primary, secondary, tertiary], slot, long_style);
7587				institution = [institution_short, institution_long];
7588				break;
7589			case "long-short":
7590				long_style = this._getLongStyle(primary, v, j);
7591				short_style = this._getShortStyle();
7592				institution_short = this._renderOneInstitutionPart(primary["short"], short_style);
7593				institution_long = this._composeOneInstitutionPart([primary, secondary, tertiary], slot, long_style, true);
7594				institution = [institution_long, institution_short];
7595				break;
7596			default:
7597				long_style = this._getLongStyle(primary, v, j);
7598				institution = [this._composeOneInstitutionPart([primary, secondary, tertiary], slot, long_style)];
7599				break;
7600			}
7601			this.institutions[v][j] = this._join(institution, "");
7602		}
7603	}
7604};
7605CSL.NameOutput.prototype._composeOneInstitutionPart = function (names, slot, style) {
7606	var primary = false, secondary = false, tertiary = false;
7607	if (names[0]) {
7608		primary = this._renderOneInstitutionPart(names[0]["long"], style);
7609	}
7610	if (names[1]) {
7611		secondary = this._renderOneInstitutionPart(names[1]["long"], style);
7612	}
7613	if (names[2]) {
7614		tertiary = this._renderOneInstitutionPart(names[2]["long"], style);
7615	}
7616	var institutionblob;
7617	if (secondary || tertiary) {
7618		this.state.output.openLevel("empty");
7619		this.state.output.append(primary);
7620		secondary_tok = CSL.Util.cloneToken(style);
7621		if (slot.secondary) {
7622			secondary_tok.strings.prefix = this.state.opt.citeAffixes.institutions[slot.secondary].prefix;
7623			secondary_tok.strings.suffix = this.state.opt.citeAffixes.institutions[slot.secondary].suffix;
7624			if (!secondary_tok.strings.prefix) {
7625				secondary_tok.strings.prefix = " ";
7626			}
7627		}
7628		this.state.output.append(secondary, secondary_tok);
7629		tertiary_tok = CSL.Util.cloneToken(style);
7630		if (slot.tertiary) {
7631			tertiary_tok.strings.prefix = this.state.opt.citeAffixes.institutions[slot.tertiary].prefix;
7632			tertiary_tok.strings.suffix = this.state.opt.citeAffixes.institutions[slot.tertiary].suffix;
7633			if (!tertiary_tok.strings.prefix) {
7634				tertiary_tok.strings.prefix = " ";
7635			}
7636		}
7637		this.state.output.append(tertiary, tertiary_tok);
7638		this.state.output.closeLevel();
7639		institutionblob = this.state.output.pop();
7640	} else {
7641		institutionblob = primary;
7642	}
7643	return institutionblob;
7644}
7645CSL.NameOutput.prototype._renderOneInstitutionPart = function (blobs, style) {
7646	for (var i = 0, ilen = blobs.length; i < ilen; i += 1) {
7647		if (blobs[i]) {
7648			var str = blobs[i];
7649			if (this.state.tmp.strip_periods) {
7650				str = str.replace(/\./g, "");
7651			} else {
7652				for (var j = 0, jlen = style.decorations.length; j < jlen; j += 1) {
7653					if ("@strip-periods" === style.decorations[j][0] && "true" === style.decorations[j][1]) {
7654						str = str.replace(/\./g, "");
7655						break;
7656					}
7657				}
7658			}
7659			this.state.tmp.group_context.value()[2] = true;
7660			this.state.tmp.can_substitute.replace(false, CSL.LITERAL);
7661			if (str === "!here>>>") {
7662				blobs[i] = false;
7663			} else {
7664				this.state.output.append(str, style, true);
7665				blobs[i] = this.state.output.pop();
7666			}
7667		}
7668	}
7669	if ("undefined" === typeof this.institution.strings["part-separator"]) {
7670		this.institution.strings["part-separator"] = this.name.strings.delimiter;
7671	}
7672	return this._join(blobs, this.institution.strings["part-separator"]);
7673};
7674CSL.NameOutput.prototype._renderPersonalNames = function (values, pos, j) {
7675	var ret = false;
7676	if (values.length) {
7677		var names = [];
7678		for (var i = 0, ilen = values.length; i < ilen; i += 1) {
7679			var name = values[i];
7680			var ret, optLangTag, jlen, key, localesets;
7681			if (this.state.tmp.extension) {
7682				localesets = ["sort"];
7683			} else if (name.isInstitution) {
7684				localesets = this.state.opt['cite-lang-prefs'].institutions;
7685			} else {
7686				localesets = this.state.opt['cite-lang-prefs'].persons;
7687			}
7688			slot = {primary:'locale-orig',secondary:false,tertiary:false};
7689			if (localesets) {
7690				var slotnames = ["primary", "secondary", "tertiary"];
7691				for (var k = 0, klen = slotnames.length; k < klen; k += 1) {
7692					if (localesets.length - 1 <  k) {
7693						break;
7694					}
7695					slot[slotnames[k]] = 'locale-' + localesets[k];
7696				}
7697			} else {
7698				slot.primary = 'locale-translat';
7699			}
7700			if (this.state.tmp.sort_key_flag || (this.state.tmp.area !== "bibliography"
7701				&& !(this.state.tmp.area === "citation"
7702					 && this.state.opt.xclass === "note"
7703					 && this.item && !this.item.position))) {
7704				slot.secondary = false;
7705				slot.tertiary = false;
7706			}
7707			this.setRenderedName(name);
7708			var res = this.getName(name, slot.primary, true);
7709			var primary = this._renderOnePersonalName(res.name, pos, i, j);
7710			secondary = false;
7711			if (slot.secondary) {
7712				res = this.getName(name, slot.secondary, false, res.usedOrig);
7713				if (res.name) {
7714					secondary = this._renderOnePersonalName(res.name, pos, i, j);
7715				}
7716			}
7717			tertiary = false;
7718			if (slot.tertiary) {
7719				res = this.getName(name, slot.tertiary, false, res.usedOrig);
7720				if (res.name) {
7721					tertiary = this._renderOnePersonalName(res.name, pos, i, j);
7722				}
7723			}
7724			var personblob;
7725			if (secondary || tertiary) {
7726				this.state.output.openLevel("empty");
7727				this.state.output.append(primary);
7728				secondary_tok = new CSL.Token();
7729				if (slot.secondary) {
7730					secondary_tok.strings.prefix = this.state.opt.citeAffixes.persons[slot.secondary].prefix;
7731					secondary_tok.strings.suffix = this.state.opt.citeAffixes.persons[slot.secondary].suffix;
7732					if (!secondary_tok.strings.prefix) {
7733						secondary_tok.strings.prefix = " ";
7734					}
7735				}
7736				this.state.output.append(secondary, secondary_tok);
7737				tertiary_tok = new CSL.Token();
7738				if (slot.tertiary) {
7739					tertiary_tok.strings.prefix = this.state.opt.citeAffixes.persons[slot.tertiary].prefix;
7740					tertiary_tok.strings.suffix = this.state.opt.citeAffixes.persons[slot.tertiary].suffix;
7741					if (!tertiary_tok.strings.prefix) {
7742						tertiary_tok.strings.prefix = " ";
7743					}
7744				}
7745				this.state.output.append(tertiary, tertiary_tok);
7746				this.state.output.closeLevel();
7747				personblob = this.state.output.pop();
7748			} else {
7749				personblob = primary;
7750			}
7751			names.push(personblob);
7752		}
7753		ret = this.joinPersons(names, pos, j);
7754	}
7755	return ret;
7756};
7757CSL.NameOutput.prototype._isRomanesque = function (name) {
7758	var ret = 2;
7759	if (!name.family.replace('"', '', 'g').match(CSL.ROMANESQUE_REGEXP)) {
7760		ret = 0;
7761	}
7762	if (!ret && name.given && name.given.match(CSL.STARTSWITH_ROMANESQUE_REGEXP)) {
7763		ret = 1;
7764	}
7765	if (ret == 2) {
7766		if (name.multi && name.multi.main) {
7767			var top_locale = name.multi.main.slice(0, 2);
7768		} else if (this.Item.language) {
7769			top_locale = this.Item.language.slice(0, 2);
7770		}
7771		if (["ja", "zh"].indexOf(top_locale) > -1) {
7772			ret = 1;
7773		}
7774	}
7775	return ret;
7776};
7777CSL.NameOutput.prototype._renderOnePersonalName = function (value, pos, i, j) {
7778	var name = value;
7779	var dropping_particle = this._droppingParticle(name, pos, j);
7780	var family = this._familyName(name);
7781	var non_dropping_particle = this._nonDroppingParticle(name);
7782	var given = this._givenName(name, pos, i);
7783	var suffix = this._nameSuffix(name);
7784	if (this._isShort(pos, i) && !name["full-form-always"]) {
7785		dropping_particle = false;
7786		given = false;
7787		suffix = false;
7788	}
7789	var sort_sep = this.name.strings["sort-separator"];
7790	if (!sort_sep) {
7791		sort_sep = "";
7792	}
7793	var suffix_sep;
7794	if (name["comma-suffix"]) {
7795		suffix_sep = ", ";
7796	} else {
7797		suffix_sep = " ";
7798	}
7799	var romanesque = this._isRomanesque(name);
7800	var has_hyphenated_non_dropping_particle = non_dropping_particle && non_dropping_particle.blobs.slice(-1) === "-";
7801	var blob, merged, first, second;
7802	if (romanesque === 0) {
7803		blob = this._join([non_dropping_particle, family, given], "");
7804	} else if (romanesque === 1 || name["static-ordering"]) { // entry likes sort order
7805		blob = this._join([non_dropping_particle, family, given], " ");
7806	} else if (name["reverse-ordering"]) { // entry likes reverse order
7807		blob = this._join([given, non_dropping_particle, family], " ");
7808	} else if (this.state.tmp.sort_key_flag) {
7809		if (this.state.opt["demote-non-dropping-particle"] === "never") {
7810			first = this._join([non_dropping_particle, family, dropping_particle], " ");
7811			merged = this._join([first, given], " ");
7812			blob = this._join([merged, suffix], " ");
7813		} else {
7814			second = this._join([given, dropping_particle, non_dropping_particle], " ");
7815			merged = this._join([family, second], " ");
7816			blob = this._join([merged, suffix], " ");
7817		}
7818	} else if (this.name.strings["name-as-sort-order"] === "all" || (this.name.strings["name-as-sort-order"] === "first" && i === 0 && (j === 0 || "undefined" === typeof j))) {
7819		if (["Lord", "Lady"].indexOf(name.given) > -1) {
7820			sort_sep = ", ";
7821		}
7822		if (["always", "display-and-sort"].indexOf(this.state.opt["demote-non-dropping-particle"]) > -1 && !has_hyphenated_non_dropping_particle) {
7823			second = this._join([given, dropping_particle], (name["comma-dropping-particle"] + " "));
7824			second = this._join([second, non_dropping_particle], " ");
7825			if (second && this.given) {
7826				second.strings.prefix = this.given.strings.prefix;
7827				second.strings.suffix = this.given.strings.suffix;
7828			}
7829			if (family && this.family) {
7830				family.strings.prefix = this.family.strings.prefix;
7831				family.strings.suffix = this.family.strings.suffix;
7832			}
7833			merged = this._join([family, second], sort_sep);
7834			blob = this._join([merged, suffix], sort_sep);
7835		} else {
7836			if (this.state.tmp.area === "bibliography" && !this.state.tmp.term_predecessor && non_dropping_particle) {
7837				if (!has_hyphenated_non_dropping_particle) {
7838					non_dropping_particle.blobs = CSL.Output.Formatters["capitalize-first"](this.state, non_dropping_particle.blobs)
7839				}
7840			}
7841			if (has_hyphenated_non_dropping_particle) {
7842				first = this._join([non_dropping_particle, family], "");
7843			} else {
7844				first = this._join([non_dropping_particle, family], " ");
7845			}
7846			if (first && this.family) {
7847				first.strings.prefix = this.family.strings.prefix;
7848				first.strings.suffix = this.family.strings.suffix;
7849			}
7850			second = this._join([given, dropping_particle], (name["comma-dropping-particle"] + " "));
7851			if (second && this.given) {
7852				second.strings.prefix = this.given.strings.prefix;
7853				second.strings.suffix = this.given.strings.suffix;
7854			}
7855			merged = this._join([first, second], sort_sep);
7856			blob = this._join([merged, suffix], sort_sep);
7857		}
7858	} else { // plain vanilla
7859		if (name["dropping-particle"] && name.family && !name["non-dropping-particle"]) {
7860			if (["'","\u02bc","\u2019"].indexOf(name["dropping-particle"].slice(-1)) > -1) {
7861				family = this._join([dropping_particle, family], "");
7862				dropping_particle = false;
7863			}
7864		}
7865		if (!this.state.tmp.term_predecessor) {
7866			if (!given && this.state.tmp.area === "bibliography") {
7867				if (!dropping_particle && non_dropping_particle) {
7868					if (!has_hyphenated_non_dropping_particle) {
7869						non_dropping_particle.blobs = CSL.Output.Formatters["capitalize-first"](this.state, non_dropping_particle.blobs)
7870					}
7871				} else if (dropping_particle) {
7872					dropping_particle.blobs = CSL.Output.Formatters["capitalize-first"](this.state, dropping_particle.blobs)
7873				}
7874			}
7875		}
7876		if (has_hyphenated_non_dropping_particle) {
7877			second = this._join([non_dropping_particle, family], "");
7878			second = this._join([dropping_particle, second], " ");
7879		} else {
7880			second = this._join([dropping_particle, non_dropping_particle, family], " ");
7881		}
7882		second = this._join([second, suffix], suffix_sep);
7883		if (second && this.family) {
7884			second.strings.prefix = this.family.strings.prefix;
7885			second.strings.suffix = this.family.strings.suffix;
7886		}
7887		if (given && this.given) {
7888			given.strings.prefix = this.given.strings.prefix;
7889			given.strings.suffix = this.given.strings.suffix;
7890		}
7891		if (second.strings.prefix) {
7892			name["comma-dropping-particle"] = "";
7893		}
7894		blob = this._join([given, second], (name["comma-dropping-particle"] + " "));
7895	}
7896	this.state.tmp.group_context.value()[2] = true;
7897	this.state.tmp.can_substitute.replace(false, CSL.LITERAL);
7898	this.state.tmp.term_predecessor = true;
7899	this.state.tmp.name_node.children.push(blob);
7900	return blob;
7901};
7902CSL.NameOutput.prototype._isShort = function (pos, i) {
7903	if (0 === this.state.tmp.disambig_settings.givens[pos][i]) {
7904		return true;
7905	} else {
7906		return false;
7907	}
7908};
7909CSL.NameOutput.prototype._normalizeNameInput = function (value) {
7910	var name = {
7911		literal:value.literal,
7912		family:value.family,
7913		isInstitution:value.isInstitution,
7914		given:value.given,
7915		suffix:value.suffix,
7916		"comma-suffix":value["comma-suffix"],
7917		"non-dropping-particle":value["non-dropping-particle"],
7918		"dropping-particle":value["dropping-particle"],
7919		"static-ordering":value["static-ordering"],
7920		"reverse-ordering":value["reverse-ordering"],
7921		"full-form-always": value["full-form-always"],
7922		"parse-names":value["parse-names"],
7923		"comma-dropping-particle": "",
7924		block_initialize:value.block_initialize,
7925		multi:value.multi
7926	};
7927	this._parseName(name);
7928	return name;
7929};
7930CSL.NameOutput.prototype._stripPeriods = function (tokname, str) {
7931	var decor_tok = this[tokname + "_decor"];
7932	if (str) {
7933		if (this.state.tmp.strip_periods) {
7934			str = str.replace(/\./g, "");
7935		} else  if (decor_tok) {
7936			for (var i = 0, ilen = decor_tok.decorations.length; i < ilen; i += 1) {
7937				if ("@strip-periods" === decor_tok.decorations[i][0] && "true" === decor_tok.decorations[i][1]) {
7938					str = str.replace(/\./g, "");
7939					break;
7940				}
7941			}
7942		}
7943	}
7944	return str;
7945};
7946CSL.NameOutput.prototype._nonDroppingParticle = function (name) {
7947	var ndp = name["non-dropping-particle"];
7948	if (ndp && this.state.tmp.sort_key_flag) {
7949		ndp = ndp.replace(/[\'\u2019]/, "");
7950	}
7951	var str = this._stripPeriods("family", ndp);
7952	if (this.state.output.append(str, this.family_decor, true)) {
7953		return this.state.output.pop();
7954	}
7955	return false;
7956};
7957CSL.NameOutput.prototype._droppingParticle = function (name, pos, j) {
7958	var dp = name["dropping-particle"];
7959	if (dp && this.state.tmp.sort_key_flag) {
7960		dp = dp.replace(/[\'\u2019]/, "");
7961	}
7962	var str = this._stripPeriods("given", dp);
7963	if (name["dropping-particle"] && name["dropping-particle"].match(/^et.?al[^a-z]$/)) {
7964		if (this.name.strings["et-al-use-last"]) {
7965			if ("undefined" === typeof j) {
7966				this.etal_spec[pos].freeters = 2;
7967			} else {
7968				this.etal_spec[pos].persons = 2;
7969			}
7970		} else {
7971			if ("undefined" === typeof j) {
7972				this.etal_spec[pos].freeters = 1;
7973			} else {
7974				this.etal_spec[pos].persons = 1;
7975			}
7976		}
7977		name["comma-dropping-particle"] = "";
7978	} else if (this.state.output.append(str, this.given_decor, true)) {
7979		return this.state.output.pop();
7980	}
7981	return false;
7982};
7983CSL.NameOutput.prototype._familyName = function (name) {
7984	var str = this._stripPeriods("family", name.family);
7985	if (this.state.output.append(str, this.family_decor, true)) {
7986		return this.state.output.pop();
7987	}
7988	return false;
7989};
7990CSL.NameOutput.prototype._givenName = function (name, pos, i) {
7991	if (this.name.strings.initialize === false) {
7992		if (name.family && name.given && this.name.strings.initialize === false) {
7993			name.given = CSL.Util.Names.initializeWith(this.state, name.given, this.name.strings["initialize-with"], true);
7994		}
7995		name.given = CSL.Util.Names.unInitialize(this.state, name.given);
7996	} else {
7997		if (name.family && 1 === this.state.tmp.disambig_settings.givens[pos][i] && !name.block_initialize) {
7998			var initialize_with = this.name.strings["initialize-with"];
7999			name.given = CSL.Util.Names.initializeWith(this.state, name.given, initialize_with);
8000		} else {
8001			name.given = CSL.Util.Names.unInitialize(this.state, name.given);
8002		}
8003	}
8004	var str = this._stripPeriods("given", name.given);
8005	var rendered = this.state.output.append(str, this.given_decor, true);
8006	if (rendered) {
8007		ret = this.state.output.pop();
8008		return ret;
8009	}
8010	return false;
8011};
8012CSL.NameOutput.prototype._nameSuffix = function (name) {
8013	var str = name.suffix;
8014	if ("string" === typeof this.name.strings["initialize-with"]) {
8015		str = CSL.Util.Names.initializeWith(this.state, name.suffix, this.name.strings["initialize-with"], true);
8016	}
8017	str = this._stripPeriods("family", str);
8018	var toSuffix = '';
8019	if (str && str.slice(-1) === '.') {
8020	str = str.slice(0, -1);
8021	toSuffix = '.';
8022	}
8023	var rendered = this.state.output.append(str, "empty", true);
8024	if (rendered) {
8025		ret = this.state.output.pop();
8026	ret.strings.suffix = toSuffix + ret.strings.suffix;
8027	return ret;
8028	}
8029	return false;
8030};
8031CSL.NameOutput.prototype._getLongStyle = function (name, v, i) {
8032	var long_style, short_style;
8033	if (name["short"].length) {
8034		if (this.institutionpart["long-with-short"]) {
8035			long_style = this.institutionpart["long-with-short"];
8036		} else {
8037			long_style = this.institutionpart["long"];
8038		}
8039	} else {
8040		long_style = this.institutionpart["long"];
8041	}
8042	if (!long_style) {
8043		long_style = new CSL.Token();
8044	}
8045	return long_style;
8046};
8047CSL.NameOutput.prototype._getShortStyle = function () {
8048	var short_style;
8049	if (this.institutionpart["short"]) {
8050		short_style = this.institutionpart["short"];
8051	} else {
8052		short_style = new CSL.Token();
8053	}
8054	return short_style;
8055};
8056CSL.NameOutput.prototype._parseName = function (name) {
8057	var m, idx;
8058	if (!name["parse-names"] && "undefined" !== typeof name["parse-names"]) {
8059		return name;
8060	}
8061	if (name.family && !name.given && name.isInstitution) {
8062		name.literal = name.family;
8063		name.family = undefined;
8064		name.isInstitution = undefined;
8065	}
8066	var noparse;
8067	if (name.family
8068		&& (name.family.slice(0, 1) === '"' && name.family.slice(-1) === '"')
8069		|| (!name["parse-names"] && "undefined" !== typeof name["parse-names"])) {
8070		name.family = name.family.slice(1, -1);
8071		noparse = true;
8072		name["parse-names"] = 0;
8073	} else {
8074		noparse = false;
8075	}
8076	if (!name["non-dropping-particle"] && name.family && !noparse && name.given) {
8077		m = name.family.match(/^((?:[\'\u2019a-z][ \'\u2019a-z]*[-\s\'\u2019]+|[ABDVL][^ ][-\s]+[a-z]*\s*|[ABDVL][^ ][^ ][-\s]+[a-z]*\s*))/);
8078		if (m) {
8079			name.family = name.family.slice(m[1].length);
8080			name["non-dropping-particle"] = m[1].replace(/\s+$/, "").replace("'", "\u2019");
8081		}
8082	}
8083	if (!name.suffix && name.given) {
8084		m = name.given.match(/(\s*,!*\s*)/);
8085		if (m) {
8086			idx = name.given.indexOf(m[1]);
8087			var possible_suffix = name.given.slice(idx + m[1].length);
8088			var possible_comma = name.given.slice(idx, idx + m[1].length).replace(/\s*/g, "");
8089			if (possible_suffix.length <= 3) {
8090				if (possible_comma.length === 2) {
8091					name["comma-suffix"] = true;
8092				}
8093				name.suffix = possible_suffix;
8094			} else if (!name["dropping-particle"] && name.given) {
8095				name["dropping-particle"] = possible_suffix;
8096				name["comma-dropping-particle"] = ",";
8097			}
8098			name.given = name.given.slice(0, idx);
8099		}
8100	}
8101	if (!name["dropping-particle"] && name.given) {
8102		m = name.given.match(/(\s+)([a-z][ \'\u2019a-z]*)$/);
8103		if (m) {
8104			name.given = name.given.slice(0, (m[1].length + m[2].length) * -1);
8105			name["dropping-particle"] = m[2];
8106		}
8107	}
8108};
8109CSL.NameOutput.prototype.getName = function (name, slotLocaleset, fallback, stopOrig) {
8110	if (stopOrig && slotLocaleset === 'locale-orig') {
8111		return {name:false,usedOrig:stopOrig};
8112	}
8113	if (!name.family) {
8114		name.family = "";
8115	}
8116	if (!name.given) {
8117		name.given = "";
8118	}
8119	var name_params = {};
8120	name_params["static-ordering"] = this.getStaticOrder(name);
8121	var foundTag = true;
8122	if (slotLocaleset !== 'locale-orig') {
8123		foundTag = false;
8124		if (name.multi) {
8125			var langTags = this.state.opt[slotLocaleset]
8126			for (i = 0, ilen = langTags.length; i < ilen; i += 1) {
8127				langTag = langTags[i];
8128				if (name.multi._key[langTag]) {
8129					foundTag = true;
8130					name = name.multi._key[langTag];
8131					name_params = this.getNameParams(langTag);
8132					name_params.transliterated = true;
8133					break;
8134				}
8135			}
8136		}
8137	}
8138	if (!foundTag) {
8139		var langTag = false;
8140		if (name.multi && name.multi.main) {
8141			langTag = name.multi.main;
8142		} else if (this.Item.language) {
8143			langTag = this.Item.language;
8144		}
8145		if (langTag) {
8146			name_params = this.getNameParams(langTag);
8147		}
8148	}
8149	if (!fallback && !foundTag) {
8150		return {name:false,usedOrig:stopOrig};
8151	}
8152	if (!name.family) {
8153		name.family = "";
8154	}
8155	if (!name.given) {
8156		name.given = "";
8157	}
8158	name = {
8159		family:name.family,
8160		given:name.given,
8161		"non-dropping-particle":name["non-dropping-particle"],
8162		"dropping-particle":name["dropping-particle"],
8163		suffix:name.suffix,
8164		"static-ordering":name_params["static-ordering"],
8165		"reverse-ordering":name_params["reverse-ordering"],
8166		"full-form-always": name_params["full-form-always"],
8167		"parse-names":name["parse-names"],
8168		"comma-suffix":name["comma-suffix"],
8169		"comma-dropping-particle":name["comma-dropping-particle"],
8170		transliterated: name_params.transliterated,
8171		block_initialize: name_params["block-initialize"],
8172		literal:name.literal,
8173		isInstitution:name.isInstitution,
8174		multi:name.multi
8175	};
8176	if (!name.literal && (!name.given && name.family && name.isInstitution)) {
8177		name.literal = name.family;
8178	}
8179	if (name.literal) {
8180		delete name.family;
8181		delete name.given;
8182	}
8183	name = this._normalizeNameInput(name);
8184	var usedOrig;
8185	if (stopOrig) {
8186		usedOrig = stopOrig;
8187	} else {
8188		usedOrig = !foundTag;
8189	}
8190	return {name:name,usedOrig:usedOrig};
8191}
8192CSL.NameOutput.prototype.getNameParams = function (langTag) {
8193	var ret = {};
8194	var langspec = CSL.localeResolve(this.Item.language, this.state.opt["default-locale"][0]);
8195	var try_locale = this.state.locale[langspec.best] ? langspec.best : this.state.opt["default-locale"][0];
8196	var name_as_sort_order = this.state.locale[try_locale].opts["name-as-sort-order"]
8197	var name_as_reverse_order = this.state.locale[try_locale].opts["name-as-reverse-order"]
8198	var name_never_short = this.state.locale[try_locale].opts["name-never-short"]
8199	var field_lang_bare = langTag.split("-")[0];
8200	if (name_as_sort_order && name_as_sort_order[field_lang_bare]) {
8201		ret["static-ordering"] = true;
8202		ret["reverse-ordering"] = false;
8203	}
8204	if (name_as_reverse_order && name_as_reverse_order[field_lang_bare]) {
8205		ret["reverse-ordering"] = true;
8206		ret["static-ordering"] = false;
8207	}
8208	if (name_never_short && name_never_short[field_lang_bare]) {
8209		ret["full-form-always"] = true;
8210	}
8211	if (ret["static-ordering"]) {
8212		ret["block-initialize"] = true;
8213	}
8214	return ret;
8215}
8216CSL.NameOutput.prototype.setRenderedName = function (name) {
8217	if (this.state.tmp.area === "bibliography") {
8218		var strname = "";
8219		for (var j=0,jlen=CSL.NAME_PARTS.length;j<jlen;j+=1) {
8220			if (name[CSL.NAME_PARTS[j]]) {
8221				strname += name[CSL.NAME_PARTS[j]];
8222			}
8223		}
8224		this.state.tmp.rendered_name.push(strname);
8225	}
8226}
8227CSL.NameOutput.prototype.fixupInstitution = function (name, varname, listpos) {
8228	name = this._splitInstitution(name, varname, listpos);
8229	if (this.institution.strings["reverse-order"]) {
8230		name["long"].reverse();
8231	}
8232	var long_form = name["long"];
8233	var short_form = long_form.slice();
8234	if (this.state.sys.getAbbreviation) {
8235		var jurisdiction = this.Item.jurisdiction;
8236		for (var j = 0, jlen = long_form.length; j < jlen; j += 1) {
8237			jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-part", long_form[j]);
8238			if (this.state.transform.abbrevs[jurisdiction]["institution-part"][long_form[j]]) {
8239				short_form[j] = this.state.transform.abbrevs[jurisdiction]["institution-part"][long_form[j]];
8240			}
8241		}
8242	}
8243	name["short"] = short_form;
8244	return name;
8245}
8246CSL.NameOutput.prototype.getStaticOrder = function (name, refresh) {
8247	var static_ordering_val = false;
8248	if (!refresh && name["static-ordering"]) {
8249		static_ordering_val = true;
8250	} else if (this._isRomanesque(name) === 0) {
8251		static_ordering_val = true;
8252	} else if ((!name.multi || !name.multi.main) && this.Item.language && ['vi', 'hu'].indexOf(this.Item.language) > -1) {
8253		static_ordering_val = true;
8254	} else if (name.multi && name.multi.main && ['vi', 'hu'].indexOf(name.multi.main.slice(0,2)) > -1) {
8255		static_ordering_val = true;
8256	} else {
8257		if (this.state.opt['auto-vietnamese-names']
8258			&& (CSL.VIETNAMESE_NAMES.exec(name.family + " " + name.given)
8259				&& CSL.VIETNAMESE_SPECIALS.exec(name.family + name.given))) {
8260			static_ordering_val = true;
8261		}
8262	}
8263	return static_ordering_val;
8264}
8265CSL.NameOutput.prototype._splitInstitution = function (value, v, i) {
8266	var ret = {};
8267	var splitInstitution = value.literal.replace(/\s*\|\s*/g, "|");
8268	splitInstitution = splitInstitution.split("|");
8269	if (this.institution.strings.form === "short" && this.state.sys.getAbbreviation) {
8270		var jurisdiction = this.Item.jurisdiction;
8271		for (var j = splitInstitution.length; j > 0; j += -1) {
8272			var str = splitInstitution.slice(0, j).join("|");
8273			jurisdiction = this.state.transform.loadAbbreviation(jurisdiction, "institution-entire", str);
8274			if (this.state.transform.abbrevs[jurisdiction]["institution-entire"][str]) {
8275				var splitLst = this.state.transform.abbrevs[jurisdiction]["institution-entire"][str];
8276				splitLst = this.state.transform.quashCheck(splitLst);
8277				var splitSplitLst = splitLst.split(/>>[0-9]{4}>>/);
8278				var m = splitLst.match(/>>([0-9]{4})>>/);
8279				splitLst = splitSplitLst.pop();
8280				if (splitSplitLst.length > 0 && this.Item["original-date"] && this.Item["original-date"].year) {
8281					for (var k=m.length - 1; k > 0; k += -1) {
8282						if (parseInt(this.Item["original-date"].year, 10) >= parseInt(m[k], 10)) {
8283							break;
8284						}
8285						splitLst = splitSplitLst.pop();
8286					}
8287				}
8288				splitLst = splitLst.replace(/\s*\|\s*/g, "|");
8289				splitInstitution = [splitLst];
8290			}
8291		}
8292	}
8293	splitInstitution.reverse();
8294	ret["long"] = this._trimInstitution(splitInstitution, v, i);
8295	return ret;
8296};
8297CSL.NameOutput.prototype._trimInstitution = function (subunits, v, i) {
8298	var use_first = false;
8299	var append_last = false;
8300	var stop_last = false;
8301	var s = subunits.slice();
8302	if (this.institution) {
8303		if ("undefined" !== typeof this.institution.strings["use-first"]) {
8304			use_first = this.institution.strings["use-first"];
8305		}
8306		if ("undefined" !== typeof this.institution.strings["stop-last"]) {
8307			s = s.slice(0, this.institution.strings["stop-last"]);
8308			subunits = subunits.slice(0, this.institution.strings["stop-last"]);
8309		}
8310		if ("undefined" !== typeof this.institution.strings["use-last"]) {
8311			append_last = this.institution.strings["use-last"];
8312		}
8313	}
8314	if (false === use_first) {
8315		if (this.persons[v].length === 0) {
8316			use_first = this.institution.strings["substitute-use-first"];
8317		}
8318		if (!use_first) {
8319			use_first = 0;
8320		}
8321	}
8322	if (false === append_last) {
8323		if (!use_first) {
8324			append_last = subunits.length;
8325		} else {
8326			append_last = 0;
8327		}
8328	}
8329	if (use_first > subunits.length - append_last) {
8330		use_first = subunits.length - append_last;
8331	}
8332	if (stop_last) {
8333		append_last = 0;
8334	}
8335	subunits = subunits.slice(0, use_first);
8336	s = s.slice(use_first);
8337	if (append_last) {
8338		if (append_last > s.length) {
8339			append_last = s.length;
8340		}
8341		if (append_last) {
8342			subunits = subunits.concat(s.slice((s.length - append_last)));
8343		}
8344	}
8345	return subunits;
8346};
8347CSL.PublisherOutput = function (state, group_tok) {
8348	this.state = state;
8349	this.group_tok = group_tok;
8350	this.varlist = [];
8351};
8352CSL.PublisherOutput.prototype.render = function () {
8353	this.clearVars();
8354	this.composeAndBlob();
8355	this.composeElements();
8356	this.composePublishers();
8357	this.joinPublishers();
8358};
8359CSL.PublisherOutput.prototype.composeAndBlob = function () {
8360	this.and_blob = {};
8361	var and_term = false;
8362	if (this.group_tok.strings.and === "text") {
8363		and_term = this.state.getTerm("and");
8364	} else if (this.group_tok.strings.and === "symbol") {
8365		and_term = "&";
8366	}
8367	var tok = new CSL.Token();
8368	tok.strings.suffix = " ";
8369	tok.strings.prefix = " ";
8370	this.state.output.append(and_term, tok, true);
8371	var no_delim = this.state.output.pop();
8372	tok.strings.prefix = this.group_tok.strings["subgroup-delimiter"];
8373	this.state.output.append(and_term, tok, true);
8374	var with_delim = this.state.output.pop();
8375	this.and_blob.single = false;
8376	this.and_blob.multiple = false;
8377	if (and_term) {
8378		if (this.group_tok.strings["subgroup-delimiter-precedes-last"] === "always") {
8379			this.and_blob.single = with_delim;
8380		} else if (this.group_tok.strings["subgroup-delimiter-precedes-last"] === "never") {
8381			this.and_blob.single = no_delim;
8382			this.and_blob.multiple = no_delim;
8383		} else {
8384			this.and_blob.single = no_delim;
8385			this.and_blob.multiple = with_delim;
8386		}
8387	}
8388};
8389CSL.PublisherOutput.prototype.composeElements = function () {
8390	for (var i = 0, ilen = 2; i < ilen; i += 1) {
8391		var varname = ["publisher", "publisher-place"][i];
8392		for (var j = 0, jlen = this["publisher-list"].length; j < jlen; j += 1) {
8393			var str = this[varname + "-list"][j];
8394			var tok = this[varname + "-token"];
8395			this.state.output.append(str, tok, true);
8396			this[varname + "-list"][j] = this.state.output.pop();
8397		}
8398	}
8399};
8400CSL.PublisherOutput.prototype.composePublishers = function () {
8401	var blobs;
8402	for (var i = 0, ilen = this["publisher-list"].length; i < ilen; i += 1) {
8403		var ordered_list = [];
8404		blobs = [this[this.varlist[0] + "-list"][i], this[this.varlist[1] + "-list"][i]];
8405		this["publisher-list"][i] = this._join(blobs, this.group_tok.strings.delimiter);
8406	}
8407};
8408CSL.PublisherOutput.prototype.joinPublishers = function () {
8409	var blobs = this["publisher-list"];
8410	var delim = this.name_delimiter;
8411	var publishers = this._join(blobs, this.group_tok.strings["subgroup-delimiter"], this.and_blob.single, this.and_blob.multiple, this.group_tok);
8412	this.state.output.append(publishers, "literal");
8413};
8414CSL.PublisherOutput.prototype._join = CSL.NameOutput.prototype._join;
8415CSL.PublisherOutput.prototype._getToken = CSL.NameOutput.prototype._getToken;
8416CSL.PublisherOutput.prototype.clearVars = function () {
8417	this.state.tmp["publisher-list"] = false;
8418	this.state.tmp["publisher-place-list"] = false;
8419	this.state.tmp["publisher-group-token"] = false;
8420	this.state.tmp["publisher-token"] = false;
8421	this.state.tmp["publisher-place-token"] = false;
8422};
8423CSL.evaluateLabel = function (node, state, Item, item) {
8424	var myterm;
8425	if ("locator" === node.strings.term) {
8426		if (item && item.label) {
8427			if (item.label === "sub verbo") {
8428				myterm = "sub-verbo";
8429			} else {
8430				myterm = item.label;
8431			}
8432		}
8433		if (!myterm) {
8434			myterm = "page";
8435		}
8436	} else {
8437		myterm = node.strings.term;
8438	}
8439	var plural = node.strings.plural;
8440	if (item && "number" === typeof item.force_pluralism) {
8441		plural = item.force_pluralism;
8442	} else if ("number" !== typeof plural) {
8443		if ("locator" === node.strings.term) {
8444			if (item && item.locator) {
8445				if (state.opt.development_extensions.locator_parsing_for_plurals) {
8446					if (!state.tmp.shadow_numbers.locator) {
8447						state.processNumber(false, item, "locator", Item.type);
8448					}
8449					plural = state.tmp.shadow_numbers.locator.plural;
8450				} else {
8451					plural = CSL.evaluateStringPluralism(item.locator);
8452				}
8453			}
8454		} else if (["page", "page-first"].indexOf(node.variables[0]) > -1) {
8455			state.processNumber(false, Item, myterm, Item.type);
8456			plural = state.tmp.shadow_numbers[myterm].plural;
8457			myterm = state.tmp.shadow_numbers[myterm].label;
8458		} else {
8459			if (!state.tmp.shadow_numbers[myterm]) {
8460				state.processNumber(false, Item, myterm, Item.type);
8461			}
8462			plural = state.tmp.shadow_numbers[myterm].plural;
8463		}
8464		if (node.decorations && (state.opt.development_extensions.csl_reverse_lookup_support || state.sys.csl_reverse_lookup_support)) {
8465			node.decorations.reverse();
8466			node.decorations.push(["@showid","true", node.cslid]);
8467			node.decorations.reverse();
8468		}
8469	}
8470	return CSL.castLabel(state, node, myterm, plural, CSL.TOLERANT);
8471};
8472CSL.evaluateStringPluralism = function (str) {
8473	if (str) {
8474		var m = str.match(/(?:[0-9],\s*[0-9]|\s+and\s+|&|([0-9]+)\s*[\-\u2013]\s*([0-9]+))/);
8475		if (m && (!m[1] || parseInt(m[1], 10) < parseInt(m[2], 10))) {
8476			return 1;
8477		}
8478	}
8479	return 0;
8480};
8481CSL.castLabel = function (state, node, term, plural, mode) {
8482	var label_form = node.strings.form;
8483	if (state.tmp.group_context.value()[5]) {
8484		label_form = state.tmp.group_context.value()[5];
8485	}
8486	var ret = state.getTerm(term, label_form, plural, false, mode);
8487	if (state.tmp.strip_periods) {
8488		ret = ret.replace(/\./g, "");
8489	} else {
8490		for (var i = 0, ilen = node.decorations.length; i < ilen; i += 1) {
8491			if ("@strip-periods" === node.decorations[i][0] && "true" === node.decorations[i][1]) {
8492				ret = ret.replace(/\./g, "");
8493				break;
8494			}
8495		}
8496	}
8497	return ret;
8498};
8499CSL.Node.name = {
8500	build: function (state, target) {
8501		var func, pos, len, attrname;
8502		if ([CSL.SINGLETON, CSL.START].indexOf(this.tokentype) > -1) {
8503			state.fixOpt(this, "name-delimiter", "name_delimiter");
8504			state.fixOpt(this, "name-form", "form");
8505			state.fixOpt(this, "and", "and");
8506			state.fixOpt(this, "delimiter-precedes-last", "delimiter-precedes-last");
8507			state.fixOpt(this, "delimiter-precedes-et-al", "delimiter-precedes-et-al");
8508			state.fixOpt(this, "initialize-with", "initialize-with");
8509			state.fixOpt(this, "initialize", "initialize");
8510			state.fixOpt(this, "name-as-sort-order", "name-as-sort-order");
8511			state.fixOpt(this, "sort-separator", "sort-separator");
8512			state.fixOpt(this, "and", "and");
8513			state.fixOpt(this, "et-al-min", "et-al-min");
8514			state.fixOpt(this, "et-al-use-first", "et-al-use-first");
8515			state.fixOpt(this, "et-al-use-last", "et-al-use-last");
8516			state.fixOpt(this, "et-al-subsequent-min", "et-al-subsequent-min");
8517			state.fixOpt(this, "et-al-subsequent-use-first", "et-al-subsequent-use-first");
8518			if (this.strings["et-al-subsequent-min"]
8519				&& (this.strings["et-al-subsequent-min"] !== this.strings["et-al-min"])) {
8520				state.opt.update_mode = CSL.POSITION;
8521			}
8522			if (this.strings["et-al-subsequent-use-first"]
8523				&& (this.strings["et-al-subsequent-use-first"] !== this.strings["et-al-use-first"])) {
8524				state.opt.update_mode = CSL.POSITION;
8525			}
8526			if ("undefined" == typeof this.strings.name_delimiter) {
8527				this.strings.delimiter = ", ";
8528			} else {
8529				this.strings.delimiter = this.strings.name_delimiter;
8530			}
8531			if (this.strings["et-al-use-last"]) {
8532				this.ellipsis_term = "\u2026";
8533				this.ellipsis_prefix_single = " ";
8534				this.ellipsis_prefix_multiple =  this.strings.delimiter;
8535				this.ellipsis_suffix = " ";
8536			}
8537			func = function (state, Item) {
8538				state.tmp.etal_term = "et-al";
8539				state.tmp.name_delimiter = this.strings.delimiter;
8540				state.tmp["delimiter-precedes-et-al"] = this.strings["delimiter-precedes-et-al"];
8541				if ("text" === this.strings.and) {
8542					this.and_term = state.getTerm("and", "long", 0);
8543				} else if ("symbol" === this.strings.and) {
8544					if (state.opt.development_extensions.expect_and_symbol_form) {
8545						this.and_term = state.getTerm("and", "symbol", 0);
8546					} else {
8547						this.and_term = "&";
8548					}
8549				}
8550				state.tmp.and_term = this.and_term;
8551				if (CSL.STARTSWITH_ROMANESQUE_REGEXP.test(this.and_term)) {
8552					this.and_prefix_single = " ";
8553					this.and_prefix_multiple = ", ";
8554					if ("string" === typeof this.strings.delimiter) {
8555						this.and_prefix_multiple = this.strings.delimiter;
8556					}
8557					this.and_suffix = " ";
8558					state.build.name_delimiter = this.strings.delimiter;
8559				} else {
8560					this.and_prefix_single = "";
8561					this.and_prefix_multiple = "";
8562					this.and_suffix = "";
8563				}
8564				if (this.strings["delimiter-precedes-last"] === "always") {
8565					this.and_prefix_single = this.strings.delimiter;
8566				} else if (this.strings["delimiter-precedes-last"] === "never") {
8567					if (this.and_prefix_multiple) {
8568						this.and_prefix_multiple = " ";
8569					}
8570				} else if (this.strings["delimiter-precedes-last"] === "after-inverted-name") {
8571					if (this.and_prefix_single) {
8572						this.and_prefix_single = this.strings.delimiter;;
8573					}
8574					if (this.and_prefix_multiple) {
8575						this.and_prefix_multiple = " ";
8576					}
8577				}
8578				this.and = {};
8579				if (this.strings.and) {
8580					state.output.append(this.and_term, "empty", true);
8581					this.and.single = state.output.pop();
8582					this.and.single.strings.prefix = this.and_prefix_single;
8583					this.and.single.strings.suffix = this.and_suffix;
8584					state.output.append(this.and_term, "empty", true);
8585					this.and.multiple = state.output.pop();
8586					this.and.multiple.strings.prefix = this.and_prefix_multiple;
8587					this.and.multiple.strings.suffix = this.and_suffix;
8588				} else if (this.strings.delimiter) {
8589					this.and.single = new CSL.Blob(this.strings.delimiter);
8590					this.and.single.strings.prefix = "";
8591					this.and.single.strings.suffix = "";
8592					this.and.multiple = new CSL.Blob(this.strings.delimiter);
8593					this.and.multiple.strings.prefix = "";
8594					this.and.multiple.strings.suffix = "";
8595				}
8596				this.ellipsis = {};
8597				if (this.strings["et-al-use-last"]) {
8598					this.ellipsis.single = new CSL.Blob(this.ellipsis_term);
8599					this.ellipsis.single.strings.prefix = this.ellipsis_prefix_single;
8600					this.ellipsis.single.strings.suffix = this.ellipsis_suffix;
8601					this.ellipsis.multiple = new CSL.Blob(this.ellipsis_term);
8602					this.ellipsis.multiple.strings.prefix = this.ellipsis_prefix_multiple;
8603					this.ellipsis.multiple.strings.suffix = this.ellipsis_suffix;
8604				}
8605				if ("undefined" === typeof state.tmp["et-al-min"]) {
8606					state.tmp["et-al-min"] = this.strings["et-al-min"];
8607				}
8608				if ("undefined" === typeof state.tmp["et-al-use-first"]) {
8609					state.tmp["et-al-use-first"] = this.strings["et-al-use-first"];
8610				}
8611				if ("undefined" === typeof state.tmp["et-al-use-last"]) {
8612					state.tmp["et-al-use-last"] = this.strings["et-al-use-last"];
8613				}
8614				state.nameOutput.name = this;
8615			};
8616			state.build.name_flag = true;
8617			this.execs.push(func);
8618		}
8619		target.push(this);
8620	}
8621};
8622CSL.Node["name-part"] = {
8623	build: function (state, target) {
8624		state.build[this.strings.name] = this;
8625	}
8626};
8627CSL.Node.names = {
8628	build: function (state, target) {
8629		var func, len, pos, attrname;
8630		var debug = false;
8631		if (this.tokentype === CSL.START || this.tokentype === CSL.SINGLETON) {
8632			CSL.Util.substituteStart.call(this, state, target);
8633			state.build.substitute_level.push(1);
8634			state.fixOpt(this, "names-delimiter", "delimiter");
8635		}
8636		if (this.tokentype === CSL.SINGLETON) {
8637			state.build.names_variables.push(this.variables);
8638			for (var i = 0, ilen = this.variables.length; i < ilen; i += 1) {
8639				state.build.name_label[this.variables[i]] = state.build.name_label[state.build.names_variables.slice(0)[0]];
8640			}
8641			func = function (state, Item, item) {
8642				state.nameOutput.reinit(this);
8643			};
8644			this.execs.push(func);
8645		}
8646		if (this.tokentype === CSL.START) {
8647			state.build.names_flag = true;
8648			state.build.names_level += 1;
8649			if (state.build.names_level === 1) {
8650				state.build.names_variables = [];
8651				state.build.name_label = {};
8652			}
8653			state.build.names_variables.push(this.variables);
8654			func = function (state, Item, item) {
8655				state.tmp.can_substitute.push(true);
8656				state.parallel.StartVariable("names",this.variables[0]);
8657				state.nameOutput.init(this);
8658			};
8659			this.execs.push(func);
8660		}
8661		if (this.tokentype === CSL.END) {
8662			for (var i = 0, ilen = 3; i < ilen; i += 1) {
8663				var key = ["family", "given", "et-al"][i];
8664				this[key] = state.build[key];
8665				if (state.build.names_level === 1) {
8666					state.build[key] = undefined;
8667				}
8668			}
8669			this.label = state.build.name_label;
8670			if (state.build.names_level === 1) {
8671				state.build.name_label = {};
8672			}
8673			state.build.names_level += -1;
8674			state.build.names_variables.pop();
8675			var mywith = "with";
8676			var with_default_prefix = "";
8677			var with_suffix = "";
8678			if (CSL.STARTSWITH_ROMANESQUE_REGEXP.test(mywith)) {
8679				with_default_prefix = " ";
8680				with_suffix = " ";
8681			}
8682			this["with"] = {};
8683			this["with"].single = new CSL.Blob(mywith);
8684			this["with"].single.strings.suffix = with_suffix;
8685			this["with"].multiple = new CSL.Blob(mywith);
8686			this["with"].multiple.strings.suffix = with_suffix;
8687			if (this.strings["delimiter-precedes-last"] === "always") {
8688				this["with"].single.strings.prefix = this.strings.delimiter;
8689				this["with"].multiple.strings.prefix = this.strings.delimiter;
8690			} else if (this.strings["delimiter-precedes-last"] === "contextual") {
8691				this["with"].single.strings.prefix = with_default_prefix;
8692				this["with"].multiple.strings.prefix = this.strings.delimiter;
8693			} else if (this.strings["delimiter-precedes-last"] === "after-inverted-name") {
8694				this["with"].single.strings.prefix = this.strings.delimiter;
8695				this["with"].multiple.strings.prefix = with_default_prefix;
8696			} else {
8697				this["with"].single.strings.prefix = with_default_prefix;
8698				this["with"].multiple.strings.prefix = with_default_prefix;
8699			}
8700			func = function (state, Item, item) {
8701				if (state.tmp.etal_node) {
8702					this.etal_style = state.tmp.etal_node;
8703				} else {
8704					this.etal_style = "empty";
8705				}
8706				this.etal_term = state.getTerm(state.tmp.etal_term, "long", 0);
8707				if (CSL.STARTSWITH_ROMANESQUE_REGEXP.test(this.etal_term)) {
8708					this.etal_prefix_single = " ";
8709					this.etal_prefix_multiple = state.tmp.name_delimiter;
8710					if (state.tmp["delimiter-precedes-et-al"] === "always") {
8711						this.etal_prefix_single = state.tmp.name_delimiter;
8712					} else if (state.tmp["delimiter-precedes-et-al"] === "never") {
8713						this.etal_prefix_multiple = " ";
8714					} else if (state.tmp["delimiter-precedes-et-al"] === "after-inverted-name") {
8715						this.etal_prefix_single = state.tmp.name_delimiter;
8716						this.etal_prefix_multiple = " ";
8717					}
8718					this.etal_suffix = "";
8719				} else {
8720					this.etal_prefix_single = "";
8721					this.etal_prefix_multiple = "";
8722					this.etal_suffix = "";
8723				}
8724				for (var i = 0, ilen = 3; i < ilen; i += 1) {
8725					var key = ["family", "given"][i];
8726					state.nameOutput[key] = this[key];
8727				}
8728				state.nameOutput["with"] = this["with"];
8729				state.nameOutput.label = this.label;
8730				state.nameOutput.etal_style = this.etal_style;
8731				state.nameOutput.etal_term = this.etal_term;
8732				state.nameOutput.etal_prefix_single = this.etal_prefix_single;
8733				state.nameOutput.etal_prefix_multiple = this.etal_prefix_multiple;
8734				state.nameOutput.etal_suffix = this.etal_suffix;
8735				state.nameOutput.outputNames();
8736				state.tmp["et-al-use-first"] = undefined;
8737				state.tmp["et-al-min"] = undefined;
8738				state.tmp["et-al-use-last"] = undefined;
8739			};
8740			this.execs.push(func);
8741			func = function (state, Item) {
8742				if (!state.tmp.can_substitute.pop()) {
8743					state.tmp.can_substitute.replace(false, CSL.LITERAL);
8744				}
8745				state.parallel.CloseVariable("names");
8746				if (state.tmp.can_substitute.mystack.length === 1) {
8747					state.tmp.can_block_substitute = false;
8748				}
8749			};
8750			this.execs.push(func);
8751			state.build.name_flag = false;
8752		}
8753		target.push(this);
8754		if (this.tokentype === CSL.END || this.tokentype === CSL.SINGLETON) {
8755			state.build.substitute_level.pop();
8756			CSL.Util.substituteEnd.call(this, state, target);
8757		}
8758	}
8759};
8760CSL.Node.number = {
8761	build: function (state, target) {
8762		var func;
8763		CSL.Util.substituteStart.call(this, state, target);
8764		if (this.strings.form === "roman") {
8765			this.formatter = state.fun.romanizer;
8766		} else if (this.strings.form === "ordinal") {
8767			this.formatter = state.fun.ordinalizer;
8768		} else if (this.strings.form === "long-ordinal") {
8769			this.formatter = state.fun.long_ordinalizer;
8770		}
8771		if ("undefined" === typeof this.successor_prefix) {
8772			this.successor_prefix = state[state.build.area].opt.layout_delimiter;
8773		}
8774		if ("undefined" === typeof this.splice_prefix) {
8775			this.splice_prefix = state[state.build.area].opt.layout_delimiter;
8776		}
8777		func = function (state, Item, item) {
8778			var i, ilen, newlst, lst;
8779			if (this.variables.length === 0) {
8780				return;
8781			}
8782			if ("undefined" === typeof item) {
8783				var item = {};
8784			}
8785			var varname, num, number, m, j, jlen;
8786			varname = this.variables[0];
8787			if (varname === "locator" && state.tmp.just_looking) {
8788				return;
8789			}
8790			state.parallel.StartVariable(this.variables[0]);
8791			if (this.variables[0] === "locator") {
8792				state.parallel.AppendToVariable(Item.section);
8793			} else {
8794				state.parallel.AppendToVariable(Item[this.variables[0]]);
8795			}
8796			var rex = new RegExp("(?:&|, | and |" + state.getTerm("page-range-delimiter") + ")");
8797			if (varname === 'collection-number' && Item.type === 'legal_case') {
8798				state.tmp.renders_collection_number = true;
8799			}
8800			var value = Item[this.variables[0]];
8801			var form = "long";
8802			if (this.strings.label_form_override) {
8803				form = this.strings.label_form_override;
8804			}
8805			if (varname === "locator"
8806				&& item.locator) {
8807				item.locator = item.locator.replace(/([^\\])\s*-\s*/, "$1" + state.getTerm("page-range-delimiter"));
8808				m = item.locator.match(CSL.STATUTE_SUBDIV_GROUPED_REGEX);
8809				if (m) {
8810					lst = item.locator.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX);
8811					for (i = 0, ilen = lst.length; i < ilen; i += 1) {
8812						lst[i] = state.fun.page_mangler(lst[i]);
8813					}
8814					newlst = [lst[0]];
8815					if (!this.strings.label_form_override && state.tmp.group_context.value()[5]) {
8816						form = state.tmp.group_context.value()[5];
8817					}
8818					for (i = 1, ilen = lst.length; i < ilen; i += 1) {
8819						var subplural = 0;
8820						if (lst[i].match(rex)) {
8821							subplural = 1;
8822						}
8823						var term = CSL.STATUTE_SUBDIV_STRINGS[m[i - 1].replace(/^\s*/,"")];
8824						var myform = form;
8825						if (item.section_label_count > i && item.section_form_override) {
8826							myform = item.section_form_override;
8827						}
8828						newlst.push(state.getTerm(term, myform, subplural));
8829						newlst.push(lst[i].replace(/^\s*/,""));
8830					}
8831					value = newlst.join(" ");
8832					value = value.replace(/\\/, "", "g");
8833					state.output.append(value, this);
8834				} else {
8835					value = state.fun.page_mangler(item.locator);
8836					value = value.replace(/\\/, "", "g");
8837					state.output.append(value, this);
8838				}
8839			} else {
8840				var node = this;
8841				if (!state.tmp.shadow_numbers[varname]
8842					|| (state.tmp.shadow_numbers[varname].values.length
8843						&& state.tmp.shadow_numbers[varname].values[0][2] === false)) {
8844					if (varname === "locator") {
8845						state.processNumber(node, item, varname, Item.type);
8846					} else {
8847						state.processNumber(node, Item, varname, Item.type);
8848					}
8849				}
8850				var values = state.tmp.shadow_numbers[varname].values;
8851				var blob;
8852				var newstr = "";
8853				var rangeType = "page";
8854				if (["bill","gazette","legislation","legal_case","treaty"].indexOf(Item.type) > -1
8855					&& varname === "collection-number") {
8856					rangeType = "year";
8857				}
8858				if (((varname === "number"
8859						&& ["bill","gazette","legislation","treaty"].indexOf(Item.type) > -1)
8860					 || state.opt[rangeType + "-range-format"])
8861					&& !this.strings.prefix && !this.strings.suffix
8862					&& !this.strings.form) {
8863					for (i = 0, ilen = values.length; i < ilen; i += 1) {
8864						newstr += values[i][1];
8865					}
8866				}
8867				if (newstr && !newstr.match(/^[\-.\u20130-9]+$/)) {
8868					if (varname === "number"
8869						&& ["bill","gazette","legislation","treaty"].indexOf(Item.type) > -1) {
8870						var firstword = newstr.split(/\s/)[0];
8871						if (firstword) {
8872							newlst = [];
8873							m = newstr.match(CSL.STATUTE_SUBDIV_GROUPED_REGEX);
8874							if (m) {
8875								lst = newstr.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX);
8876								for (i = 1, ilen = lst.length; i < ilen; i += 1) {
8877									newlst.push(state.getTerm(CSL.STATUTE_SUBDIV_STRINGS[m[i - 1].replace(/^\s+/, "")], this.strings.label_form_override));
8878									newlst.push(lst[i].replace(/^\s+/, ""));
8879								}
8880								newstr = newlst.join(" ");
8881							}
8882						}
8883					}
8884					state.output.append(newstr, this);
8885				} else {
8886					if (values.length) {
8887						state.output.openLevel("empty");
8888						for (i = 0, ilen = values.length; i < ilen; i += 1) {
8889							blob = new CSL[values[i][0]](values[i][1], values[i][2], Item.id);
8890							if (i > 0) {
8891								blob.strings.prefix = blob.strings.prefix.replace(/^\s*/, "");
8892							}
8893							if (i < values.length - 1) {
8894								blob.strings.suffix = blob.strings.suffix.replace(/\s*$/, "");
8895							}
8896							if ("undefined" === typeof blob.gender) {
8897								blob.gender = state.locale[state.opt.lang]["noun-genders"][varname];
8898							}
8899							state.output.append(blob, "literal", false, false, true);
8900						}
8901						state.output.closeLevel("empty");
8902					}
8903				}
8904			}
8905			if (varname === "locator") {
8906				state.tmp.done_vars.push("locator");
8907			}
8908			state.parallel.CloseVariable("number");
8909		};
8910		this.execs.push(func);
8911		target.push(this);
8912		CSL.Util.substituteEnd.call(this, state, target);
8913	}
8914};
8915CSL.Node.sort = {
8916	build: function (state, target) {
8917		target = state[state.build.root + "_sort"].tokens;
8918		if (this.tokentype === CSL.START) {
8919			if (state.build.area === "citation") {
8920				state.parallel.use_parallels = false;
8921				state.opt.sort_citations = true;
8922			}
8923			state.build.area = state.build.root + "_sort";
8924			state.build.extension = "_sort";
8925			var func = function (state, Item) {
8926				if (state.opt.has_layout_locale) {
8927					var langspec = CSL.localeResolve(Item.language, state.opt["default-locale"][0]);
8928					var sort_locales = state[state.tmp.area.slice(0,-5)].opt.sort_locales;
8929					var langForItem;
8930					for (var i=0,ilen=sort_locales.length;i<ilen;i+=1) {
8931						langForItem = sort_locales[i][langspec.bare];
8932						if (!langForItem) {
8933							langForItem = sort_locales[i][langspec.best];
8934						}
8935						if (langForItem) {
8936							break;
8937						}
8938					}
8939					if (!langForItem) {
8940						langForItem = state.opt["default-locale"][0];
8941					}
8942					state.tmp.lang_sort_hold = state.opt.lang;
8943					state.opt.lang = langForItem;
8944				}
8945			}
8946			this.execs.push(func);
8947		}
8948		if (this.tokentype === CSL.END) {
8949			state.build.area = state.build.root;
8950			state.build.extension = "";
8951			var func = function (state, Item) {
8952				if (state.opt.has_layout_locale) {
8953					state.opt.lang = state.tmp.lang_sort_hold;
8954					delete state.tmp.lang_sort_hold;
8955				}
8956			}
8957			this.execs.push(func);
8958		}
8959		target.push(this);
8960	}
8961};
8962CSL.Node.substitute = {
8963	build: function (state, target) {
8964		var func;
8965		if (this.tokentype === CSL.START) {
8966			func = function (state, Item) {
8967				state.tmp.can_block_substitute = true;
8968				if (state.tmp.value.length) {
8969					state.tmp.can_substitute.replace(false, CSL.LITERAL);
8970				}
8971			};
8972			this.execs.push(func);
8973		}
8974		target.push(this);
8975	}
8976};
8977CSL.Node.text = {
8978	build: function (state, target) {
8979		var variable, func, form, plural, id, num, number, formatter, firstoutput, specialdelimiter, label, myname, names, name, year, suffix, term, dp, len, pos, n, m, value, flag;
8980		if (this.postponed_macro) {
8981			return CSL.expandMacro.call(state, this);
8982		} else {
8983			CSL.Util.substituteStart.call(this, state, target);
8984			if (!this.variables_real) {
8985				this.variables_real = [];
8986			}
8987			if (!this.variables) {
8988				this.variables = [];
8989			}
8990			form = "long";
8991			plural = 0;
8992			if (this.strings.form) {
8993				form = this.strings.form;
8994			}
8995			if (this.strings.plural) {
8996				plural = this.strings.plural;
8997			}
8998			if ("citation-number" === this.variables_real[0] || "year-suffix" === this.variables_real[0] || "citation-label" === this.variables_real[0]) {
8999				if (this.variables_real[0] === "citation-number") {
9000					if (state.build.root === "citation") {
9001						state.opt.update_mode = CSL.NUMERIC;
9002					}
9003					if (state.build.root === "bibliography") {
9004						state.opt.bib_mode = CSL.NUMERIC;
9005					}
9006					if (state.build.area === "bibliography_sort") {
9007						state.opt.citation_number_sort_used = true;
9008					}
9009					if ("citation-number" === state[state.tmp.area].opt.collapse) {
9010						this.range_prefix = state.getTerm("citation-range-delimiter");
9011					}
9012					this.successor_prefix = state[state.build.area].opt.layout_delimiter;
9013					this.splice_prefix = state[state.build.area].opt.layout_delimiter;
9014					func = function (state, Item, item) {
9015						id = "" + Item.id;
9016						if (!state.tmp.just_looking) {
9017							if (item && item["author-only"]) {
9018								state.tmp.element_trace.replace("do-not-suppress-me");
9019								var reference_term = state.getTerm("reference", "long", "singular");
9020								if ("undefined" === typeof reference_term) {
9021									reference_term = "reference";
9022								}
9023								term = CSL.Output.Formatters["capitalize-first"](state, reference_term);
9024								state.output.append(term + " ");
9025								state.tmp.last_element_trace = true;
9026							}
9027							if (item && item["suppress-author"]) {
9028								if (state.tmp.last_element_trace) {
9029									state.tmp.element_trace.replace("suppress-me");
9030								}
9031								state.tmp.last_element_trace = false;
9032							}
9033							num = state.registry.registry[id].seq;
9034							if (state.opt.citation_number_slug) {
9035								state.output.append(state.opt.citation_number_slug, this);
9036							} else {
9037								number = new CSL.NumericBlob(num, this, Item.id);
9038								state.output.append(number, "literal");
9039							}
9040						}
9041					};
9042					this.execs.push(func);
9043				} else if (this.variables_real[0] === "year-suffix") {
9044					state.opt.has_year_suffix = true;
9045					if (state[state.tmp.area].opt.collapse === "year-suffix-ranged") {
9046						this.range_prefix = state.getTerm("citation-range-delimiter");
9047					}
9048					this.successor_prefix = state[state.build.area].opt.layout_delimiter;
9049					if (state[state.tmp.area].opt["year-suffix-delimiter"]) {
9050						this.successor_prefix = state[state.build.area].opt["year-suffix-delimiter"];
9051					}
9052					func = function (state, Item) {
9053						if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false && !state.tmp.just_looking) {
9054							num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10);
9055							number = new CSL.NumericBlob(num, this, Item.id);
9056							formatter = new CSL.Util.Suffixator(CSL.SUFFIX_CHARS);
9057							number.setFormatter(formatter);
9058							state.output.append(number, "literal");
9059							firstoutput = false;
9060							len = state.tmp.group_context.mystack.length;
9061							for (pos = 0; pos < len; pos += 1) {
9062								flag = state.tmp.group_context.mystack[pos];
9063								if (!flag[2] && (flag[1] || (!flag[1] && !flag[0]))) {
9064									firstoutput = true;
9065									break;
9066								}
9067							}
9068							specialdelimiter = state[state.tmp.area].opt["year-suffix-delimiter"];
9069							if (firstoutput && specialdelimiter && !state.tmp.sort_key_flag) {
9070								state.tmp.splice_delimiter = state[state.tmp.area].opt["year-suffix-delimiter"];
9071							}
9072						}
9073					};
9074					this.execs.push(func);
9075				} else if (this.variables_real[0] === "citation-label") {
9076					state.opt.has_year_suffix = true;
9077					func = function (state, Item) {
9078						label = Item["citation-label"];
9079						if (!label) {
9080							label = state.getCitationLabel(Item);
9081						}
9082						if (!state.tmp.just_looking) {
9083							suffix = "";
9084							if (state.registry.registry[Item.id] && state.registry.registry[Item.id].disambig.year_suffix !== false) {
9085								num = parseInt(state.registry.registry[Item.id].disambig.year_suffix, 10);
9086								suffix = state.fun.suffixator.format(num);
9087							}
9088							label += suffix;
9089						}
9090						state.output.append(label, this);
9091					};
9092					this.execs.push(func);
9093				}
9094			} else {
9095				if (this.strings.term) {
9096					func = function (state, Item, item) {
9097						var gender = state.opt.gender[Item.type];
9098						var term = this.strings.term;
9099						term = state.getTerm(term, form, plural, gender, false, ("accessed" === term));
9100						var myterm;
9101						if (term !== "") {
9102							flag = state.tmp.group_context.value();
9103							flag[0] = true;
9104							state.tmp.group_context.replace(flag);
9105						}
9106						if (!state.tmp.term_predecessor && !(state.opt["class"] === "in-text" && state.tmp.area === "citation")) {
9107							myterm = CSL.Output.Formatters["capitalize-first"](state, term);
9108						} else {
9109							myterm = term;
9110						}
9111						if (state.tmp.strip_periods) {
9112							myterm = myterm.replace(/\./g, "");
9113						} else {
9114							for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) {
9115								if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) {
9116									myterm = myterm.replace(/\./g, "");
9117									break;
9118								}
9119							}
9120						}
9121						state.output.append(myterm, this);
9122					};
9123					this.execs.push(func);
9124					state.build.term = false;
9125					state.build.form = false;
9126					state.build.plural = false;
9127				} else if (this.variables_real.length) {
9128					func = function (state, Item, item) {
9129						var parallel_variable = this.variables[0];
9130						if (parallel_variable === "title"
9131							&& (form === "short" || Item["title-short"])) {
9132							parallel_variable = "title-short";
9133						}
9134						state.parallel.StartVariable(parallel_variable);
9135						state.parallel.AppendToVariable(Item[parallel_variable],parallel_variable);
9136					};
9137					this.execs.push(func);
9138					if (CSL.MULTI_FIELDS.indexOf(this.variables_real[0]) > -1) {
9139						var abbrevfam = this.variables[0];
9140						var abbrfall = false;
9141						var altvar = false;
9142						var transfall = false;
9143						if (form === "short") {
9144							if (this.variables_real[0] === "container-title") {
9145								altvar = "journalAbbreviation";
9146							} else if (this.variables_real[0] === "title") {
9147								altvar = "title-short";
9148							}
9149						} else {
9150							abbrevfam = false;
9151						}
9152						if (state.build.extension) {
9153							transfall = true;
9154						} else {
9155							transfall = true;
9156							abbrfall = true;
9157						}
9158						func = state.transform.getOutputFunction(this.variables, abbrevfam, abbrfall, altvar, transfall);
9159					} else {
9160						if (CSL.CITE_FIELDS.indexOf(this.variables_real[0]) > -1) {
9161							func = function (state, Item, item) {
9162								if (item && item[this.variables[0]]) {
9163									var value = "" + item[this.variables[0]];
9164									value = value.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter"));
9165									value = value.replace(/\\-/g,"-");
9166									state.output.append(value, this, false, false, true);
9167									if (this.variables[0] === "locator-revision") {
9168										state.tmp.done_vars.push("locator-revision");
9169									}
9170								}
9171							};
9172						} else if (this.variables_real[0] === "page-first") {
9173							func = function (state, Item) {
9174								var idx, value;
9175								value = state.getVariable(Item, "page-first", form);
9176								if (value) {
9177									value = value.replace("\\", "");
9178									state.output.append(value, this, false, false, true);
9179								}
9180							};
9181						} else  if (this.variables_real[0] === "page") {
9182							func = function (state, Item) {
9183								var value = state.getVariable(Item, "page", form);
9184								if (value) {
9185									value = ""+value;
9186									value = value.replace(/([^\\])--*/g,"$1"+state.getTerm("page-range-delimiter"));
9187									value = value.replace(/\\-/g,"-");
9188									value = state.fun.page_mangler(value);
9189									state.output.append(value, this, false, false, true);
9190								}
9191							};
9192						} else if (this.variables_real[0] === "volume") {
9193							func = function (state, Item) {
9194								if (this.variables[0]) {
9195									var value = state.getVariable(Item, this.variables[0], form);
9196									if (value) {
9197										state.output.append(value, this);
9198									}
9199								}
9200							};
9201						} else if (["URL", "DOI"].indexOf(this.variables_real[0]) > -1) {
9202							func = function (state, Item) {
9203								var value;
9204								if (this.variables[0]) {
9205									value = state.getVariable(Item, this.variables[0], form);
9206									if (value) {
9207										if (state.opt.development_extensions.wrap_url_and_doi) {
9208											if (!this.decorations.length || this.decorations[0][0] !== "@" + this.variables[0]) {
9209												this.decorations = [["@" + this.variables[0], "true"]].concat(this.decorations);
9210											}
9211										} else {
9212											if (this.decorations.length && this.decorations[0][0] === "@" + this.variables[0]) {
9213												this.decorations = this.decorations.slice(1);
9214											}
9215										}
9216										state.output.append(value, this, false, false, true);
9217									}
9218								}
9219							};
9220						} else if (this.variables_real[0] === "section") {
9221							func = function (state, Item) {
9222								var value;
9223								value = state.getVariable(Item, this.variables[0], form);
9224								if (value) {
9225									state.output.append(value, this);
9226								}
9227							};
9228						} else if (this.variables_real[0] === "hereinafter") {
9229							func = function (state, Item) {
9230								var value = state.transform.abbrevs["default"]["hereinafter"][Item.id];
9231								if (value) {
9232									state.output.append(value, this);
9233									state.tmp.group_context.value()[2] = true;
9234								}
9235							}
9236						} else {
9237							func = function (state, Item) {
9238								var value;
9239								if (this.variables[0]) {
9240									value = state.getVariable(Item, this.variables[0], form);
9241									if (value) {
9242										value = "" + value;
9243										value = value.replace("\\", "", "g");
9244										state.output.append(value, this);
9245									}
9246								}
9247							};
9248						}
9249					}
9250					this.execs.push(func);
9251					func = function (state, Item) {
9252						state.parallel.CloseVariable("text");
9253					};
9254					this.execs.push(func);
9255				} else if (this.strings.value) {
9256					func = function (state, Item) {
9257						var flag;
9258						flag = state.tmp.group_context.value();
9259						flag[0] = true;
9260						state.tmp.group_context.replace(flag);
9261						state.output.append(this.strings.value, this);
9262					};
9263					this.execs.push(func);
9264				}
9265			}
9266			target.push(this);
9267			CSL.Util.substituteEnd.call(this, state, target);
9268		}
9269	}
9270};
9271CSL.Attributes = {};
9272CSL.Attributes["@genre"] = function (state, arg) {
9273	arg = arg.replace("-", " ");
9274	var func = function (Item, item) {
9275		var ret;
9276		if (arg === Item.genre) {
9277			return true;
9278		}
9279		return false;
9280	}
9281	this.tests.push(func);
9282}
9283CSL.Attributes["@disambiguate"] = function (state, arg) {
9284	if (arg === "true") {
9285		state.opt.has_disambiguate = true;
9286		var func = function (Item, item) {
9287			state.tmp.disambiguate_maxMax += 1;
9288			if (state.tmp.disambig_settings.disambiguate
9289				&& state.tmp.disambiguate_count < state.tmp.disambig_settings.disambiguate) {
9290				state.tmp.disambiguate_count += 1;
9291				return true;
9292			}
9293			return false;
9294		};
9295		this.tests.push(func);
9296	} else if (arg === "check-ambiguity-and-backreference") {
9297		var func = function (Item, item) {
9298			if (state.registry.registry[Item.id].disambig.disambiguate && state.registry.registry[Item.id]["citation-count"] > 1) {
9299				return true;
9300			}
9301			return false;
9302		};
9303		this.tests.push(func);
9304	}
9305};
9306CSL.Attributes["@is-numeric"] = function (state, arg, joiner) {
9307	var variables = arg.split(/\s+/);
9308	var maketest = function(variable) {
9309		return function (Item, item) {
9310			var myitem = Item;
9311			if (["locator","locator-revision"].indexOf(variable) > -1) {
9312				myitem = item;
9313			}
9314			if ("undefined" === typeof myitem) {
9315				return false;
9316			}
9317			if (CSL.NUMERIC_VARIABLES.indexOf(variable) > -1) {
9318				if (!state.tmp.shadow_numbers[variable]) {
9319					state.processNumber(false, myitem, variable, Item.type);
9320				}
9321				if (myitem[variable] && state.tmp.shadow_numbers[variable].numeric) {
9322					return true;
9323				}
9324			} else if (["title", "locator-revision","version"].indexOf(variable) > -1) {
9325				if (myitem[variable]) {
9326					if (myitem[variable].slice(-1) === "" + parseInt(myitem[variable].slice(-1), 10)) {
9327						return true;
9328					}
9329				}
9330			}
9331			return false;
9332		}
9333	}
9334	for (var i=0; i<variables.length; i+=1) {
9335		this.tests.push(maketest(variables[i]));
9336	}
9337};
9338CSL.Attributes["@is-uncertain-date"] = function (state, arg) {
9339	var variables = arg.split(/\s+/);
9340	var maketest = function (myvariable) {
9341		return function(Item, item) {
9342			if (Item[myvariable] && Item[myvariable].circa) {
9343				return true;
9344			} else {
9345				return false;
9346			}
9347		}
9348	}
9349	for (var i=0,ilen=variables.length;i<ilen;i+=1) {
9350		this.tests.push(maketest(variables[i]));
9351	};
9352};
9353CSL.Attributes["@locator"] = function (state, arg) {
9354	var trylabels = arg.replace("sub verbo", "sub-verbo");
9355	trylabels = trylabels.split(/\s+/);
9356	var maketest = function (trylabel) {
9357		return function(Item, item) {
9358			var label;
9359			if ("undefined" === typeof item || !item.label) {
9360				label = "page";
9361			} else if (item.label === "sub verbo") {
9362				label = "sub-verbo";
9363			} else {
9364				label = item.label;
9365			}
9366			if (trylabel === label) {
9367				return true;
9368			} else {
9369				return false;
9370			}
9371		}
9372	}
9373	for (var i=0,ilen=trylabels.length;i<ilen;i+=1) {
9374		this.tests.push(maketest(trylabels[i]));
9375	}
9376};
9377CSL.Attributes["@position"] = function (state, arg) {
9378	var tryposition;
9379	state.opt.update_mode = CSL.POSITION;
9380	state.parallel.use_parallels = true;
9381	var trypositions = arg.split(/\s+/);
9382	var maketest = function(tryposition) {
9383		return function (Item, item) {
9384			if (state.tmp.area === "bibliography") {
9385				return false;
9386			}
9387			if (item && "undefined" === typeof item.position) {
9388				item.position = 0;
9389			}
9390			if (item && typeof item.position === "number") {
9391				if (item.position === 0 && tryposition === 0) {
9392					return true;
9393				} else if (tryposition > 0 && item.position >= tryposition) {
9394					return true;
9395				}
9396			} else if (tryposition === 0) {
9397				return true;
9398			}
9399			return false;
9400		}
9401	}
9402	for (var i=0,ilen=trypositions.length;i<ilen;i+=1) {
9403		var tryposition = trypositions[i];
9404		if (tryposition === "first") {
9405			tryposition = CSL.POSITION_FIRST;
9406		} else if (tryposition === "subsequent") {
9407			tryposition = CSL.POSITION_SUBSEQUENT;
9408		} else if (tryposition === "ibid") {
9409			tryposition = CSL.POSITION_IBID;
9410		} else if (tryposition === "ibid-with-locator") {
9411			tryposition = CSL.POSITION_IBID_WITH_LOCATOR;
9412		}
9413		if ("near-note" === tryposition) {
9414			this.tests.push(function (Item, item) {
9415				if (item && item.position >= CSL.POSITION_SUBSEQUENT && item["near-note"]) {
9416					return true;
9417				}
9418				return false;
9419			});
9420		} else {
9421			this.tests.push(maketest(tryposition));
9422		}
9423	}
9424};
9425CSL.Attributes["@type"] = function (state, arg) {
9426	var types = arg.split(/\s+/);
9427	var maketest = function (mytype) {
9428		return function(Item,item) {
9429			var ret = (Item.type === mytype);
9430			if (ret) {
9431				return true;
9432			} else {
9433				return false;
9434			}
9435		}
9436	}
9437	var tests = [];
9438	for (var i=0,ilen=types.length;i<ilen;i+=1) {
9439		tests.push(maketest(types[i]));
9440	}
9441	this.tests.push(state.fun.match.any(this, state, tests));
9442};
9443CSL.Attributes["@variable"] = function (state, arg) {
9444	var func;
9445	this.variables = arg.split(/\s+/);
9446	this.variables_real = this.variables.slice();
9447	if ("label" === this.name && this.variables[0]) {
9448		this.strings.term = this.variables[0];
9449	} else if (["names", "date", "text", "number"].indexOf(this.name) > -1) {
9450		func = function (state, Item, item) {
9451			variables = this.variables_real.slice();
9452			for (var i = this.variables.length - 1; i > -1; i += -1) {
9453				this.variables.pop();
9454			}
9455			len = variables.length;
9456			for (pos = 0; pos < len; pos += 1) {
9457				if (state.tmp.done_vars.indexOf(variables[pos]) === -1 && !(item && Item.type === "legal_case" && item["suppress-author"] && variables[pos] === "title")) {
9458					this.variables.push(variables[pos]);
9459				}
9460				if (state.tmp.can_block_substitute) {
9461					state.tmp.done_vars.push(variables[pos]);
9462				}
9463			}
9464		};
9465		this.execs.push(func);
9466		func = function (state, Item, item) {
9467			var mydate;
9468			output = false;
9469			len = this.variables.length;
9470			for (pos = 0; pos < len; pos += 1) {
9471				variable = this.variables[pos];
9472				if (variable === "authority"
9473					&& "string" === typeof Item[variable]
9474					&& "names" === this.name) {
9475					var creatorParent = {
9476						family:Item[variable],
9477						isInstitution:true,
9478						multi:{
9479							_key:{}
9480						}
9481					};
9482					if (Item.multi && Item.multi._keys && Item.multi._keys[variable]) {
9483						for (var langTag in Item.multi._keys[variable]) {
9484							creatorChild = {
9485								family:Item.multi._keys[variable][langTag],
9486								isInstitution:true
9487							}
9488							creatorParent.multi._key[langTag] = creatorChild;
9489						}
9490					}
9491					Item[variable] = [creatorParent];
9492				}
9493				if (this.strings.form === "short" && !Item[variable]) {
9494					if (variable === "title") {
9495						variable = "title-short";
9496					} else if (variable === "container-title") {
9497						variable = "journalAbbreviation";
9498					}
9499				}
9500				if (variable === "year-suffix") {
9501					output = true;
9502					break;
9503				} else if (CSL.DATE_VARIABLES.indexOf(variable) > -1) {
9504					if (state.opt.development_extensions.locator_date_and_revision && "locator-date" === variable) {
9505						output = true;
9506						break;
9507					}
9508					if (Item[variable]) {
9509						for (var key in Item[variable]) {
9510							if (this.dateparts.indexOf(key) === -1 && "literal" !== key) {
9511								continue;
9512							}
9513							if (Item[variable][key]) {
9514								output = true;
9515								break;
9516							}
9517						}
9518						if (output) {
9519							break;
9520						}
9521					}
9522				} else if ("locator" === variable) {
9523					if (item && item.locator) {
9524						output = true;
9525					}
9526					break;
9527				} else if ("locator-revision" === variable) {
9528					if (item && item["locator-revision"]) {
9529						output = true;
9530					}
9531					break;
9532				} else if (["citation-number","citation-label"].indexOf(variable) > -1) {
9533					output = true;
9534					break;
9535				} else if ("first-reference-note-number" === variable) {
9536					if (item && item["first-reference-note-number"]) {
9537						output = true;
9538					}
9539					break;
9540				} else if ("hereinafter" === variable) {
9541					if (state.transform.abbrevs["default"].hereinafter[Item.id]
9542						&& state.sys.getAbbreviation
9543						&& Item.id) {
9544						output = true;
9545					}
9546					break;
9547				} else if ("object" === typeof Item[variable]) {
9548					if (Item[variable].length) {
9549					}
9550					break;
9551				} else if ("string" === typeof Item[variable] && Item[variable]) {
9552					output = true;
9553					break;
9554				} else if ("number" === typeof Item[variable]) {
9555					output = true;
9556					break;
9557				}
9558				if (output) {
9559					break;
9560				}
9561			}
9562			flag = state.tmp.group_context.value();
9563			if (output) {
9564				if (variable !== "citation-number" || state.tmp.area !== "bibliography") {
9565					state.tmp.cite_renders_content = true;
9566				}
9567				flag[2] = true;
9568				state.tmp.group_context.replace(flag);
9569				if (state.tmp.can_substitute.value()
9570					&& state.tmp.area === "bibliography"
9571					&& "string" === typeof Item[variable]) {
9572					state.tmp.rendered_name.push(Item[variable]);
9573				}
9574				state.tmp.can_substitute.replace(false,  CSL.LITERAL);
9575			} else {
9576				flag[1] = true;
9577			}
9578		};
9579		this.execs.push(func);
9580	} else if (["if",  "else-if", "condition"].indexOf(this.name) > -1) {
9581		var maketest = function (variable) {
9582			return function(Item,item){
9583				var myitem = Item;
9584				if (item && ["locator", "locator-revision", "first-reference-note-number", "locator-date"].indexOf(variable) > -1) {
9585					myitem = item;
9586				}
9587				if (variable === "hereinafter" && state.sys.getAbbreviation && myitem.id) {
9588					if (state.transform.abbrevs["default"].hereinafter[myitem.id]) {
9589						return true;
9590					}
9591				} else if (myitem[variable]) {
9592					if ("number" === typeof myitem[variable] || "string" === typeof myitem[variable]) {
9593						return true;
9594					} else if ("object" === typeof myitem[variable]) {
9595						for (key in myitem[variable]) {
9596							if (myitem[variable][key]) {
9597								return true;
9598							}
9599						}
9600					}
9601				}
9602				return false;
9603			}
9604		}
9605		for (var i=0,ilen=this.variables.length;i<ilen;i+=1) {
9606			this.tests.push(maketest(this.variables[i]));
9607		}
9608	}
9609};
9610CSL.Attributes["@page"] = function (state, arg) {
9611	var trylabels = arg.replace("sub verbo", "sub-verbo");
9612	trylabels = trylabels.split(/\s+/);
9613	var maketest = function (trylabel) {
9614		return function(Item, item) {
9615			var label;
9616			state.processNumber(false, Item, "page", Item.type);
9617			if (!state.tmp.shadow_numbers.page.label) {
9618				label = "page";
9619			} else if (state.tmp.shadow_numbers.page.label === "sub verbo") {
9620				label = "sub-verbo";
9621			} else {
9622				label = state.tmp.shadow_numbers.page.label;
9623			}
9624			if (trylabel === label) {
9625				return true;
9626			} else {
9627				return false;
9628			}
9629		}
9630	}
9631	for (var i=0,ilen=trylabels.length;i<ilen;i+=1) {
9632		this.tests.push(maketest(trylabels[i]));
9633	}
9634};
9635CSL.Attributes["@jurisdiction"] = function (state, arg) {
9636	var tryjurisdictions = arg.split(/\s+/);
9637	for (var i=0,ilen=tryjurisdictions.length;i<ilen;i+=1) {
9638		tryjurisdictions[i] = tryjurisdictions[i].split(";");
9639	}
9640	var maketests = function (tryjurisdiction) {
9641		return function(Item,item){
9642			if (!Item.jurisdiction) {
9643				return false;
9644			}
9645			var jurisdictions = Item.jurisdiction.split(";");
9646			for (var i=0,ilen=jurisdictions.length;i<ilen;i+=1) {
9647				jurisdictions[i] = jurisdictions[i].split(";");
9648			}
9649			for (i=tryjurisdiction.length;i>0;i+=-1) {
9650				var tryjurisdictionStr = tryjurisdiction.slice(0,i).join(";");
9651				var jurisdiction = jurisdictions.slice(0,i).join(";");
9652				if (tryjurisdictionStr !== jurisdiction) {
9653					return false;
9654				}
9655			}
9656			return true;
9657		}
9658	}
9659	for (var i=0,ilen=tryjurisdictions.length;i<ilen;i+=1) {
9660		var tryjurisdictionSlice = tryjurisdictions[i].slice();
9661		this.tests.push(maketests(tryjurisdictionSlice));
9662	}
9663};
9664CSL.Attributes["@context"] = function (state, arg) {
9665	var func = function (Item, item) {
9666		var area = state.tmp.area.slice(0, arg.length);
9667		if (area === arg) {
9668			return true;
9669		}
9670		return false;
9671	};
9672	this.tests.push(func);
9673};
9674CSL.Attributes["@has-year-only"] = function (state, arg) {
9675	var trydates = arg.split(/\s+/);
9676	var maketest = function (trydate) {
9677		return function(Item,item){
9678			var date = Item[trydate];
9679			if (!date || date.month || date.season) {
9680				return false;
9681			} else {
9682				return true;
9683			}
9684		}
9685	}
9686	for (var i=0,ilen=trydates.length;i<ilen;i+=1) {
9687		this.tests.push(maketest(trydates[i]));
9688	}
9689};
9690CSL.Attributes["@has-to-month-or-season"] = function (state, arg) {
9691	var trydates = arg.split(/\s+/);
9692	var maketest = function (trydate) {
9693		return function(Item,item){
9694			var date = Item[trydate];
9695			if (!date || (!date.month && !date.season) || date.day) {
9696				return false;
9697			} else {
9698				return true;
9699			}
9700		}
9701	}
9702	for (var i=0,ilen=trydates.length;i<ilen;i+=1) {
9703		this.tests.push(maketest(trydates[i]));
9704	}
9705};
9706CSL.Attributes["@has-day"] = function (state, arg) {
9707	var trydates = arg.split(/\s+/);
9708	var maketest = function (trydate) {
9709		return function(Item,item){
9710			var date = Item[trydate];
9711			if (!date || !date.day) {
9712				return false;
9713			} else {
9714				return true;
9715			}
9716		}
9717	}
9718	for (var i=0,ilen=trydates.length;i<ilen;i+=1) {
9719		this.tests.push(maketest(trydates[i]));
9720	};
9721};
9722CSL.Attributes["@subjurisdictions"] = function (state, arg) {
9723	var trysubjurisdictions = parseInt(arg, 10);
9724	var func = function (Item, item) {
9725		var subjurisdictions = 0;
9726		if (Item.jurisdiction) {
9727			subjurisdictions = Item.jurisdiction.split(";").length;
9728		}
9729		if (subjurisdictions) {
9730			subjurisdictions += -1;
9731		}
9732		if (subjurisdictions >= trysubjurisdictions) {
9733			return true;
9734		}
9735		return false;
9736	};
9737	this.tests.push(func);
9738};
9739CSL.Attributes["@is-plural"] = function (state, arg) {
9740	var func = function (Item, item) {
9741		var nameList = Item[arg];
9742		if (nameList && nameList.length) {
9743			var persons = 0;
9744			var institutions = 0;
9745			var last_is_person = false;
9746			for (var i = 0, ilen = nameList.length; i < ilen; i += 1) {
9747				if (nameList[i].isInstitution && (nameList[i].literal || (nameList[i].family && !nameList[i].given))) {
9748					institutions += 1;
9749					last_is_person = false;
9750				} else {
9751					persons += 1;
9752					last_is_person = true;
9753				}
9754			}
9755			if (persons > 1) {
9756				return true;
9757			} else if (institutions > 1) {
9758				return true;
9759			} else if (institutions && last_is_person) {
9760				return true;
9761			}
9762		}
9763		return false;
9764	};
9765	this.tests.push(func);
9766};
9767CSL.Attributes["@locale"] = function (state, arg) {
9768	var func, ret, len, pos, variable, myitem, langspec, lang, lst, i, ilen, fallback;
9769	var locale_default = state.opt["default-locale"][0];
9770	if (this.name === "layout") {
9771		this.locale_raw = arg;
9772		if (this.tokentype === CSL.START) {
9773			var locales = arg.split(/\s+/);
9774			var sort_locale = {};
9775			var localeMaster = CSL.localeResolve(locales[0], locale_default);
9776			if (localeMaster.generic) {
9777				sort_locale[localeMaster.generic] = localeMaster.best;
9778			} else {
9779				sort_locale[localeMaster.best] = localeMaster.best;
9780			}
9781			for (var i=1,ilen=locales.length;i<ilen;i+=1) {
9782				var localeServant = CSL.localeResolve(locales[i], locale_default);
9783				if (localeServant.generic) {
9784					sort_locale[localeServant.generic] = localeMaster.best;
9785				} else {
9786					sort_locale[localeServant.best] = localeMaster.best;
9787				}
9788			}
9789			state[state.build.area].opt.sort_locales.push(sort_locale);
9790		}
9791		state.opt.has_layout_locale = true;
9792	} else {
9793		lst = arg.split(/\s+/);
9794		var locale_bares = [];
9795		for (i = 0, ilen = lst.length; i < ilen; i += 1) {
9796			lang = lst[i];
9797			langspec = CSL.localeResolve(lang, locale_default);
9798			if (lst[i].length === 2) {
9799				locale_bares.push(langspec.bare);
9800			}
9801			state.localeConfigure(langspec, true);
9802			lst[i] = langspec;
9803		}
9804		var locale_list = lst.slice();
9805		var maketest = function (locale_list, locale_default,locale_bares) {
9806			return function (Item, item) {
9807				var key, res;
9808				ret = [];
9809				res = false;
9810				var langspec = false;
9811				var lang;
9812				if (!Item.language) {
9813					lang = locale_default;
9814				} else {
9815					lang = Item.language;
9816				}
9817				langspec = CSL.localeResolve(lang, locale_default);
9818				for (i = 0, ilen = locale_list.length; i < ilen; i += 1) {
9819					if (langspec.best === locale_list[i].best) {
9820						res = true;
9821						break;
9822					}
9823				}
9824				if (!res && locale_bares.indexOf(langspec.bare) > -1) {
9825					res = true;
9826				}
9827				return res;
9828			}
9829		}
9830		this.tests.push(maketest(locale_list,locale_default,locale_bares));
9831	}
9832};
9833CSL.Attributes["@locale-internal"] = function (state, arg) {
9834	var func, ret, len, pos, variable, myitem, langspec, lang, lst, i, ilen, fallback;
9835		lst = arg.split(/\s+/);
9836		this.locale_bares = [];
9837		for (i = 0, ilen = lst.length; i < ilen; i += 1) {
9838			lang = lst[i];
9839			langspec = CSL.localeResolve(lang, state.opt["default-locale"][0]);
9840			if (lst[i].length === 2) {
9841				this.locale_bares.push(langspec.bare);
9842			}
9843			state.localeConfigure(langspec);
9844			lst[i] = langspec;
9845		}
9846		this.locale_default = state.opt["default-locale"][0];
9847		this.locale = lst[0].best;
9848		this.locale_list = lst.slice();
9849		var maketest = function (me) {
9850			return function (Item, item) {
9851				var key, res;
9852				ret = [];
9853				res = false;
9854				var langspec = false;
9855				if (Item.language) {
9856					lang = Item.language;
9857					langspec = CSL.localeResolve(lang, state.opt["default-locale"][0]);
9858					if (langspec.best === state.opt["default-locale"][0]) {
9859						langspec = false;
9860					}
9861				}
9862				if (langspec) {
9863					for (i = 0, ilen = me.locale_list.length; i < ilen; i += 1) {
9864						if (langspec.best === me.locale_list[i].best) {
9865							state.opt.lang = me.locale;
9866							state.tmp.last_cite_locale = me.locale;
9867							state.output.openLevel("empty");
9868							state.output.current.value().new_locale = me.locale;
9869							res = true;
9870							break;
9871						}
9872					}
9873					if (!res && me.locale_bares.indexOf(langspec.bare) > -1) {
9874						state.opt.lang = me.locale;
9875						state.tmp.last_cite_locale = me.locale;
9876						state.output.openLevel("empty");
9877						state.output.current.value().new_locale = me.locale;
9878						res = true;
9879					}
9880				}
9881				return res;
9882			}
9883		}
9884		var me = this;
9885		this.tests.push(maketest(me));
9886}
9887CSL.Attributes["@is-parallel"] = function (state, arg) {
9888	var values = arg.split(" ");
9889	for (var i = 0, ilen = values.length; i < ilen; i += 1) {
9890		if (values[i] === "true") {
9891			values[i] = true;
9892		} else if (values[i] === "false") {
9893			values[i] = false;
9894		}
9895	}
9896	this.strings.set_parallel_condition = values;
9897};
9898CSL.Attributes["@gender"] = function (state, arg) {
9899	this.gender = arg;
9900}
9901CSL.Attributes["@cslid"] = function (state, arg) {
9902	this.cslid = parseInt(arg, 10);
9903};
9904CSL.Attributes["@label-form"] = function (state, arg) {
9905	this.strings.label_form_override = arg;
9906};
9907CSL.Attributes["@part-separator"] = function (state, arg) {
9908	this.strings["part-separator"] = arg;
9909};
9910CSL.Attributes["@leading-noise-words"] = function (state, arg) {
9911	this["leading-noise-words"] = arg;
9912};
9913CSL.Attributes["@name-never-short"] = function (state, arg) {
9914	this["name-never-short"] = arg;
9915};
9916CSL.Attributes["@class"] = function (state, arg) {
9917	state.opt["class"] = arg;
9918};
9919CSL.Attributes["@version"] = function (state, arg) {
9920	state.opt.version = arg;
9921};
9922CSL.Attributes["@value"] = function (state, arg) {
9923	this.strings.value = arg;
9924};
9925CSL.Attributes["@name"] = function (state, arg) {
9926	this.strings.name = arg;
9927};
9928CSL.Attributes["@form"] = function (state, arg) {
9929	this.strings.form = arg;
9930};
9931CSL.Attributes["@date-parts"] = function (state, arg) {
9932	this.strings["date-parts"] = arg;
9933};
9934CSL.Attributes["@range-delimiter"] = function (state, arg) {
9935	this.strings["range-delimiter"] = arg;
9936};
9937CSL.Attributes["@macro"] = function (state, arg) {
9938	this.postponed_macro = arg;
9939};
9940CSL.Attributes["@term"] = function (state, arg) {
9941	if (arg === "sub verbo") {
9942		this.strings.term = "sub-verbo";
9943	} else {
9944		this.strings.term = arg;
9945	}
9946};
9947CSL.Attributes["@xmlns"] = function (state, arg) {};
9948CSL.Attributes["@lang"] = function (state, arg) {
9949	if (arg) {
9950		state.build.lang = arg;
9951	}
9952};
9953CSL.Attributes["@lingo"] = function (state, arg) {
9954};
9955CSL.Attributes["@macro-has-date"] = function (state, arg) {
9956	this["macro-has-date"] = true;
9957};
9958CSL.Attributes["@suffix"] = function (state, arg) {
9959	this.strings.suffix = arg;
9960};
9961CSL.Attributes["@prefix"] = function (state, arg) {
9962	this.strings.prefix = arg;
9963};
9964CSL.Attributes["@delimiter"] = function (state, arg) {
9965	if ("name" == this.name) {
9966		this.strings.name_delimiter = arg;
9967	} else {
9968		this.strings.delimiter = arg;
9969	}
9970};
9971CSL.Attributes["@match"] = function (state, arg) {
9972	this.match = arg;
9973};
9974CSL.Attributes["@names-min"] = function (state, arg) {
9975	var val = parseInt(arg, 10);
9976	if (state[state.tmp.area].opt.max_number_of_names < val) {
9977		state[state.tmp.area].opt.max_number_of_names = val;
9978	}
9979	this.strings["et-al-min"] = val;
9980};
9981CSL.Attributes["@names-use-first"] = function (state, arg) {
9982	this.strings["et-al-use-first"] = parseInt(arg, 10);
9983};
9984CSL.Attributes["@names-use-last"] = function (state, arg) {
9985	if (arg === "true") {
9986		this.strings["et-al-use-last"] = true;
9987	} else {
9988		this.strings["et-al-use-last"] = false;
9989	}
9990};
9991CSL.Attributes["@sort"] = function (state, arg) {
9992	if (arg === "descending") {
9993		this.strings.sort_direction = CSL.DESCENDING;
9994	}
9995};
9996CSL.Attributes["@plural"] = function (state, arg) {
9997	if ("always" === arg || "true" === arg) {
9998		this.strings.plural = 1;
9999	} else if ("never" === arg || "false" === arg) {
10000		this.strings.plural = 0;
10001	} else if ("contextual" === arg) {
10002		this.strings.plural = false;
10003	}
10004};
10005CSL.Attributes["@number"] = function (state, arg) {
10006	var func;
10007	var trylabels = arg.replace("sub verbo", "sub-verbo");
10008	trylabels = trylabels.split(/\s+/);
10009	if (["if",  "else-if"].indexOf(this.name) > -1) {
10010		func = function (state, Item, item) {
10011			var ret = [];
10012			var label;
10013			state.processNumber(false, Item, "number", Item.type);
10014			if (!state.tmp.shadow_numbers.number.label) {
10015				label = "number";
10016			} else if (state.tmp.shadow_numbers.number.label === "sub verbo") {
10017				label = "sub-verbo";
10018			} else {
10019				label = state.tmp.shadow_numbers.number.label;
10020			}
10021			for (var i = 0, ilen = trylabels.length; i < ilen; i += 1) {
10022				if (trylabels[i] === label) {
10023					ret.push(true);
10024				} else {
10025					ret.push(false);
10026				}
10027			}
10028			return ret;
10029		};
10030		this.tests.push(func);
10031	}
10032};
10033CSL.Attributes["@has-publisher-and-publisher-place"] = function (state, arg) {
10034	this.strings["has-publisher-and-publisher-place"] = true;
10035};
10036CSL.Attributes["@publisher-delimiter-precedes-last"] = function (state, arg) {
10037	this.strings["publisher-delimiter-precedes-last"] = arg;
10038};
10039CSL.Attributes["@publisher-delimiter"] = function (state, arg) {
10040	this.strings["publisher-delimiter"] = arg;
10041};
10042CSL.Attributes["@publisher-and"] = function (state, arg) {
10043	this.strings["publisher-and"] = arg;
10044};
10045CSL.Attributes["@newdate"] = function (state, arg) {
10046};
10047CSL.Attributes["@givenname-disambiguation-rule"] = function (state, arg) {
10048	if (CSL.GIVENNAME_DISAMBIGUATION_RULES.indexOf(arg) > -1) {
10049		state.citation.opt["givenname-disambiguation-rule"] = arg;
10050	}
10051};
10052CSL.Attributes["@collapse"] = function (state, arg) {
10053	if (arg) {
10054		state[this.name].opt.collapse = arg;
10055	}
10056};
10057CSL.Attributes["@cite-group-delimiter"] = function (state, arg) {
10058	if (arg) {
10059		state[state.tmp.area].opt.cite_group_delimiter = arg;
10060	}
10061};
10062CSL.Attributes["@names-delimiter"] = function (state, arg) {
10063	state.setOpt(this, "names-delimiter", arg);
10064};
10065CSL.Attributes["@name-form"] = function (state, arg) {
10066	state.setOpt(this, "name-form", arg);
10067};
10068CSL.Attributes["@subgroup-delimiter"] = function (state, arg) {
10069	this.strings["subgroup-delimiter"] = arg;
10070};
10071CSL.Attributes["@subgroup-delimiter-precedes-last"] = function (state, arg) {
10072	this.strings["subgroup-delimiter-precedes-last"] = arg;
10073};
10074CSL.Attributes["@name-delimiter"] = function (state, arg) {
10075	state.setOpt(this, "name-delimiter", arg);
10076};
10077CSL.Attributes["@et-al-min"] = function (state, arg) {
10078	var val = parseInt(arg, 10);
10079	if (state[state.tmp.area].opt.max_number_of_names < val) {
10080		state[state.tmp.area].opt.max_number_of_names = val;
10081	}
10082	state.setOpt(this, "et-al-min", val);
10083};
10084CSL.Attributes["@et-al-use-first"] = function (state, arg) {
10085	state.setOpt(this, "et-al-use-first", parseInt(arg, 10));
10086};
10087CSL.Attributes["@et-al-use-last"] = function (state, arg) {
10088	if (arg === "true") {
10089		state.setOpt(this, "et-al-use-last", true);
10090	} else {
10091		state.setOpt(this, "et-al-use-last", false);
10092	}
10093};
10094CSL.Attributes["@et-al-subsequent-min"] = function (state, arg) {
10095	var val = parseInt(arg, 10);
10096	if (state[state.tmp.area].opt.max_number_of_names < val) {
10097		state[state.tmp.area].opt.max_number_of_names = val;
10098	}
10099	state.setOpt(this, "et-al-subsequent-min", val);
10100};
10101CSL.Attributes["@et-al-subsequent-use-first"] = function (state, arg) {
10102	state.setOpt(this, "et-al-subsequent-use-first", parseInt(arg, 10));
10103};
10104CSL.Attributes["@suppress-min"] = function (state, arg) {
10105	this.strings["suppress-min"] = parseInt(arg, 10);
10106};
10107CSL.Attributes["@suppress-max"] = function (state, arg) {
10108	this.strings["suppress-max"] = parseInt(arg, 10);
10109};
10110CSL.Attributes["@and"] = function (state, arg) {
10111	state.setOpt(this, "and", arg);
10112};
10113CSL.Attributes["@delimiter-precedes-last"] = function (state, arg) {
10114	state.setOpt(this, "delimiter-precedes-last", arg);
10115};
10116CSL.Attributes["@delimiter-precedes-et-al"] = function (state, arg) {
10117	state.setOpt(this, "delimiter-precedes-et-al", arg);
10118};
10119CSL.Attributes["@initialize-with"] = function (state, arg) {
10120	state.setOpt(this, "initialize-with", arg);
10121};
10122CSL.Attributes["@initialize"] = function (state, arg) {
10123	if (arg === "false") {
10124		state.setOpt(this, "initialize", false);
10125	}
10126};
10127CSL.Attributes["@name-as-reverse-order"] = function (state, arg) {
10128	this["name-as-reverse-order"] = arg;
10129};
10130CSL.Attributes["@name-as-sort-order"] = function (state, arg) {
10131	if (this.name === "style-options") {
10132		this["name-as-sort-order"] = arg;
10133	} else {
10134		state.setOpt(this, "name-as-sort-order", arg);
10135	}
10136};
10137CSL.Attributes["@sort-separator"] = function (state, arg) {
10138	state.setOpt(this, "sort-separator", arg);
10139};
10140CSL.Attributes["@year-suffix-delimiter"] = function (state, arg) {
10141	state[this.name].opt["year-suffix-delimiter"] = arg;
10142};
10143CSL.Attributes["@after-collapse-delimiter"] = function (state, arg) {
10144	state[this.name].opt["after-collapse-delimiter"] = arg;
10145};
10146CSL.Attributes["@subsequent-author-substitute"] = function (state, arg) {
10147	state[this.name].opt["subsequent-author-substitute"] = arg;
10148};
10149CSL.Attributes["@subsequent-author-substitute-rule"] = function (state, arg) {
10150	state[this.name].opt["subsequent-author-substitute-rule"] = arg;
10151};
10152CSL.Attributes["@disambiguate-add-names"] = function (state, arg) {
10153	if (arg === "true") {
10154		state.opt["disambiguate-add-names"] = true;
10155	}
10156};
10157CSL.Attributes["@disambiguate-add-givenname"] = function (state, arg) {
10158	if (arg === "true") {
10159		state.opt["disambiguate-add-givenname"] = true;
10160	}
10161};
10162CSL.Attributes["@disambiguate-add-year-suffix"] = function (state, arg) {
10163	if (arg === "true" && state.opt.xclass !== "numeric") {
10164		state.opt["disambiguate-add-year-suffix"] = true;
10165	}
10166};
10167CSL.Attributes["@second-field-align"] = function (state, arg) {
10168	if (arg === "flush" || arg === "margin") {
10169		state[this.name].opt["second-field-align"] = arg;
10170	}
10171};
10172CSL.Attributes["@hanging-indent"] = function (state, arg) {
10173	if (arg === "true") {
10174		state[this.name].opt.hangingindent = 2;
10175	}
10176};
10177CSL.Attributes["@line-spacing"] = function (state, arg) {
10178	if (arg && arg.match(/^[.0-9]+$/)) {
10179		state[this.name].opt["line-spacing"] = parseFloat(arg, 10);
10180	}
10181};
10182CSL.Attributes["@entry-spacing"] = function (state, arg) {
10183	if (arg && arg.match(/^[.0-9]+$/)) {
10184		state[this.name].opt["entry-spacing"] = parseFloat(arg, 10);
10185	}
10186};
10187CSL.Attributes["@near-note-distance"] = function (state, arg) {
10188	state[this.name].opt["near-note-distance"] = parseInt(arg, 10);
10189};
10190CSL.Attributes["@text-case"] = function (state, arg) {
10191	var func = function (state, Item) {
10192		if (arg === "normal") {
10193			this.text_case_normal = true;
10194		} else {
10195			this.strings["text-case"] = arg;
10196			if (arg === "title") {
10197				var m = false;
10198				var default_locale = state.opt["default-locale"][0].slice(0, 2);
10199				if (Item.jurisdiction) {
10200					this.strings["text-case"] = "passthrough";
10201				}
10202			}
10203		}
10204	};
10205	this.execs.push(func);
10206};
10207CSL.Attributes["@page-range-format"] = function (state, arg) {
10208	state.opt["page-range-format"] = arg;
10209};
10210CSL.Attributes["@year-range-format"] = function (state, arg) {
10211	state.opt["year-range-format"] = arg;
10212};
10213CSL.Attributes["@default-locale"] = function (state, arg) {
10214	var lst, len, pos, m, ret;
10215	m = arg.match(/-x-(sort|translit|translat)-/g);
10216	if (m) {
10217		for (pos = 0, len = m.length; pos < len; pos += 1) {
10218			m[pos] = m[pos].replace(/^-x-/, "").replace(/-$/, "");
10219		}
10220	}
10221	lst = arg.split(/-x-(?:sort|translit|translat)-/);
10222	ret = [lst[0]];
10223	for (pos = 1, len = lst.length; pos < len; pos += 1) {
10224		ret.push(m[pos - 1]);
10225		ret.push(lst[pos]);
10226	}
10227	lst = ret.slice();
10228	len = lst.length;
10229	for (pos = 1; pos < len; pos += 2) {
10230		state.opt[("locale-" + lst[pos])].push(lst[(pos + 1)].replace(/^\s*/g, "").replace(/\s*$/g, ""));
10231	}
10232	if (lst.length) {
10233		state.opt["default-locale"] = lst.slice(0, 1);
10234	} else {
10235		state.opt["default-locale"] = ["en"];
10236	}
10237};
10238CSL.Attributes["@default-locale-sort"] = function (state, arg) {
10239	var lst, len, pos, m, ret;
10240	state.opt["default-locale-sort"] = arg;
10241};
10242CSL.Attributes["@demote-non-dropping-particle"] = function (state, arg) {
10243	state.opt["demote-non-dropping-particle"] = arg;
10244};
10245CSL.Attributes["@initialize-with-hyphen"] = function (state, arg) {
10246	if (arg === "false") {
10247		state.opt["initialize-with-hyphen"] = false;
10248	}
10249};
10250CSL.Attributes["@institution-parts"] = function (state, arg) {
10251	this.strings["institution-parts"] = arg;
10252};
10253CSL.Attributes["@if-short"] = function (state, arg) {
10254	if (arg === "true") {
10255		this.strings["if-short"] = true;
10256	}
10257};
10258CSL.Attributes["@substitute-use-first"] = function (state, arg) {
10259	this.strings["substitute-use-first"] = parseInt(arg, 10);
10260};
10261CSL.Attributes["@use-first"] = function (state, arg) {
10262	this.strings["use-first"] = parseInt(arg, 10);
10263};
10264CSL.Attributes["@stop-last"] = function (state, arg) {
10265	this.strings["stop-last"] = parseInt(arg, 10) * -1;
10266};
10267CSL.Attributes["@oops"] = function (state, arg) {
10268	this.strings.oops = arg;
10269};
10270CSL.Attributes["@use-last"] = function (state, arg) {
10271	this.strings["use-last"] = parseInt(arg, 10);
10272};
10273CSL.Attributes["@reverse-order"] = function (state, arg) {
10274	if ("true" === arg) {
10275		this.strings["reverse-order"] = true;
10276	}
10277};
10278CSL.Attributes["@display"] = function (state, arg) {
10279	this.strings.cls = arg;
10280};
10281CSL.Stack = function (val, literal) {
10282	this.mystack = [];
10283	if (literal || val) {
10284		this.mystack.push(val);
10285	}
10286};
10287CSL.Stack.prototype.push = function (val, literal) {
10288	if (literal || val) {
10289		this.mystack.push(val);
10290	} else {
10291		this.mystack.push("");
10292	}
10293};
10294CSL.Stack.prototype.clear = function () {
10295	this.mystack = [];
10296};
10297CSL.Stack.prototype.replace = function (val, literal) {
10298	if (this.mystack.length === 0) {
10299		throw "Internal CSL processor error: attempt to replace nonexistent stack item with " + val;
10300	}
10301	if (literal || val) {
10302		this.mystack[(this.mystack.length - 1)] = val;
10303	} else {
10304		this.mystack[(this.mystack.length - 1)] = "";
10305	}
10306};
10307CSL.Stack.prototype.pop = function () {
10308	return this.mystack.pop();
10309};
10310CSL.Stack.prototype.value = function () {
10311	return this.mystack.slice(-1)[0];
10312};
10313CSL.Stack.prototype.length = function () {
10314	return this.mystack.length;
10315};
10316CSL.Parallel = function (state) {
10317	this.state = state;
10318	this.sets = new CSL.Stack([]);
10319	this.try_cite = true;
10320	this.use_parallels = false;
10321	this.midVars = ["section", "volume", "container-title", "collection-number", "issue", "page-first", "page", "number"];
10322	this.ignoreVarsLawGeneral = ["first-reference-note-number", "locator", "label","page-first","page","genre"];
10323	this.ignoreVarsLawProceduralHistory = ["issued", "first-reference-note-number", "locator", "label","page-first","page","genre","jurisdiction"];
10324	this.ignoreVarsOrders = ["first-reference-note-number"];
10325	this.ignoreVarsOther = ["first-reference-note-number", "locator", "label","section","page-first","page"];
10326};
10327CSL.Parallel.prototype.isMid = function (variable) {
10328	return (this.midVars.indexOf(variable) > -1);
10329};
10330CSL.Parallel.prototype.StartCitation = function (sortedItems, out) {
10331	this.parallel_conditional_blobs_list = [];
10332	if (this.use_parallels) {
10333		this.sortedItems = sortedItems;
10334		this.sortedItemsPos = -1;
10335		this.sets.clear();
10336		this.sets.push([]);
10337		this.in_series = true;
10338		this.delim_counter = 0;
10339		this.delim_pointers = [];
10340		if (out) {
10341			this.out = out;
10342		} else {
10343			this.out = this.state.output.queue;
10344		}
10345		this.master_was_neutral_cite = true;
10346	}
10347};
10348CSL.Parallel.prototype.StartCite = function (Item, item, prevItemID) {
10349	var position, len, pos, x, curr, master, last_id, prev_locator, curr_locator, is_master, parallel;
10350	if (this.use_parallels) {
10351		if (this.sets.value().length && this.sets.value()[0].itemId == Item.id) {
10352			this.ComposeSet();
10353		}
10354		this.sortedItemsPos += 1;
10355		if (item) {
10356			position = item.position;
10357		}
10358		this.try_cite = true;
10359		var has_required_var = false;
10360		for (var i = 0, ilen = CSL.PARALLEL_MATCH_VARS.length; i < ilen; i += 1) {
10361			if (Item[CSL.PARALLEL_MATCH_VARS[i]]) {
10362				has_required_var = true;
10363				break;
10364			}
10365		}
10366		var basics_ok = true;
10367		var last_cite = this.sets.value().slice(-1)[0];
10368		if (last_cite && last_cite.Item) {
10369			var lastJuris = last_cite.Item.jurisdiction ? last_cite.Item.jurisdiction.split(";")[0] : "";
10370			var thisJuris = Item.jurisdiction ? Item.jurisdiction.split(";")[0] : "";
10371			if (last_cite.Item.title !== Item.title) {
10372				basics_ok = false;
10373			} else if (lastJuris !== thisJuris) {
10374				basics_ok = false;
10375			} else if (last_cite.Item.type !== Item.type) {
10376				basics_ok = false;
10377			} else if (["article-journal","article-magazine"].indexOf(Item.type) > -1) {
10378				if (!this.state.opt.development_extensions.handle_parallel_articles
10379					 || last_cite.Item["container-title"] !== Item["container-title"]) {
10380					basics_ok = false;
10381				}
10382			}
10383		}
10384		if (!basics_ok || !has_required_var || CSL.PARALLEL_TYPES.indexOf(Item.type) === -1) {
10385			this.try_cite = true;
10386			if (this.in_series) {
10387				this.in_series = false;
10388			}
10389		}
10390		this.cite = {};
10391		this.cite.front = [];
10392		this.cite.mid = [];
10393		this.cite.back = [];
10394		this.cite.front_collapse = {};
10395		this.cite.back_forceme = [];
10396		this.cite.position = position;
10397		this.cite.Item = Item;
10398		this.cite.itemId = "" + Item.id;
10399		this.cite.prevItemID = "" + prevItemID;
10400		this.target = "front";
10401		if (["treaty"].indexOf(Item.type) > -1) {
10402			this.ignoreVars = this.ignoreVarsOrders;
10403		} else if (["article-journal","article-magazine"].indexOf(Item.type) > -1) {
10404			this.ignoreVars = this.ignoreVarsOther;
10405		} else if (item && item.prefix) {
10406			this.ignoreVars = this.ignoreVarsLawProceduralHistory;
10407			this.cite.useProceduralHistory = true;
10408			var prev = this.sets.value()[(this.sets.value().length - 1)];
10409			if (prev && prev.back) {
10410				for (var i=prev.back.length-1;i>-1;i+=-1) {
10411					if (prev.back[i] && prev[prev.back[i]]) {
10412						delete prev[prev.back[i]];
10413					}
10414				}
10415			}
10416		} else {
10417			this.ignoreVars = this.ignoreVarsLawGeneral;
10418		}
10419		if (this.sortedItems && this.sortedItemsPos > 0 && this.sortedItemsPos < this.sortedItems.length) {
10420			curr = this.sortedItems[this.sortedItemsPos][1];
10421			last_id = "" + this.sortedItems[(this.sortedItemsPos - 1)][1].id;
10422			master = this.state.registry.registry[last_id].parallel;
10423			prev_locator = false;
10424			if (master == curr.id) {
10425				len = this.sortedItemsPos - 1;
10426				for (pos = len; pos > -1; pos += -1) {
10427					if (this.sortedItems[pos][1].id == Item.id) {
10428						prev_locator = this.sortedItems[pos][1].locator;
10429						break;
10430					}
10431				}
10432				curr_locator = this.sortedItems[this.sortedItemsPos][1].locator;
10433				if (!prev_locator && curr_locator) {
10434					curr.position = CSL.POSITION_IBID_WITH_LOCATOR;
10435				} else if (curr_locator === prev_locator) {
10436					curr.position = CSL.POSITION_IBID;
10437				} else {
10438					curr.position = CSL.POSITION_IBID_WITH_LOCATOR;
10439				}
10440			}
10441		} else if (this.state.registry.registry[Item.id]) {
10442			this.state.registry.registry[Item.id].parallel = false;
10443		} else {
10444			this.try_cite = false;
10445			this.force_collapse = false;
10446			return;
10447		}
10448		this.force_collapse = false;
10449		if (this.state.registry.registry[Item.id].parallel) {
10450			this.force_collapse = true;
10451		}
10452	}
10453};
10454CSL.Parallel.prototype.StartVariable = function (variable, real_variable) {
10455	if (this.use_parallels && (this.try_cite || this.force_collapse)) {
10456		if (variable === "names") {
10457			this.variable = variable + ":" + this.target;
10458		} else {
10459			this.variable = variable;
10460		}
10461		if (this.ignoreVars.indexOf(variable) > -1) {
10462			return;
10463		}
10464		if (variable === "container-title" && this.sets.value().length === 0) {
10465			this.master_was_neutral_cite = false;
10466		}
10467		this.data = {};
10468		this.data.value = "";
10469		this.data.blobs = [];
10470		var is_mid = this.isMid(variable);
10471		if (real_variable === "authority" && this.variable === "names:front") {
10472			this.try_cite = true;
10473			this.in_series = false;
10474		} else if (this.target === "front" && is_mid) {
10475			this.target = "mid";
10476		} else if (this.target === "mid" && !is_mid && this.cite.Item.title && variable !== "names") {
10477			this.target = "back";
10478		} else if (this.target === "back" && is_mid) {
10479			this.try_cite = true;
10480			this.in_series = false;
10481		}
10482		if (variable === "number") {
10483			this.cite.front.push(this.variable);
10484		} else if (CSL.PARALLEL_COLLAPSING_MID_VARSET.indexOf(variable) > -1) {
10485			if (["article-journal","article-magazine"].indexOf(this.cite.Item.type) > -1) {
10486				this.cite.mid.push(this.variable);
10487			} else {
10488				this.cite.front.push(this.variable);
10489			}
10490		} else {
10491			this.cite[this.target].push(this.variable);
10492		}
10493	 }
10494};
10495CSL.Parallel.prototype.AppendBlobPointer = function (blob) {
10496	if (this.use_parallels) {
10497		if (this.ignoreVars.indexOf(this.variable) > -1) {
10498			return;
10499		}
10500		if (this.use_parallels && (this.force_collapse || this.try_cite)) {
10501			if (["article-journal", "article-magazine"].indexOf(this.cite.Item.type) > -1) {
10502				if (["volume","page","page-first","issue"].indexOf(this.variable) > -1) {
10503					return;
10504				}
10505				if ("container-title" === this.variable && this.cite.mid.length > 1) {
10506					return;
10507				}
10508			}
10509			if (this.variable && (this.try_cite || this.force_collapse) && blob && blob.blobs) {
10510				if (!(this.cite.useProceduralHistory && this.target === "back")) {
10511					this.data.blobs.push([blob, blob.blobs.length]);
10512				}
10513			}
10514		}
10515	}
10516};
10517CSL.Parallel.prototype.AppendToVariable = function (str, varname) {
10518	if (this.use_parallels) {
10519		if (this.ignoreVars.indexOf(this.variable) > -1) {
10520			return;
10521		}
10522		if (this.try_cite || this.force_collapse) {
10523			if (this.target !== "back" || true) {
10524				this.data.value += "::" + str;
10525			} else {
10526				var prev = this.sets.value()[(this.sets.value().length - 1)];
10527				if (prev) {
10528					if (prev[this.variable]) {
10529						if (prev[this.variable].value) {
10530							this.data.value += "::" + str;
10531						}
10532					}
10533				}
10534			}
10535		}
10536	}
10537};
10538CSL.Parallel.prototype.CloseVariable = function () {
10539	if (this.use_parallels) {
10540		if (this.ignoreVars.indexOf(this.variable) > -1) {
10541			return;
10542		}
10543		if (this.try_cite || this.force_collapse) {
10544			this.cite[this.variable] = this.data;
10545			if (this.sets.value().length > 0) {
10546				var prev = this.sets.value()[(this.sets.value().length - 1)];
10547				if (this.target === "front" && this.variable === "issued") {
10548					if (this.data.value && this.master_was_neutral_cite) {
10549						this.target = "mid";
10550					}
10551				}
10552				if (this.target === "front") {
10553					if ((prev[this.variable] || this.data.value) && (!prev[this.variable] || this.data.value !== prev[this.variable].value)) {
10554						if ("issued" !== this.variable) {
10555							this.in_series = false;
10556						}
10557					}
10558				} else if (this.target === "mid") {
10559					if (CSL.PARALLEL_COLLAPSING_MID_VARSET.indexOf(this.variable) > -1) {
10560						if (prev[this.variable]) {
10561							if (prev[this.variable].value === this.data.value) {
10562								this.cite.front_collapse[this.variable] = true;
10563							} else {
10564								this.cite.front_collapse[this.variable] = false;
10565							}
10566						} else {
10567							this.cite.front_collapse[this.variable] = false;
10568						}
10569					}
10570				} else if (this.target === "back") {
10571					if (prev[this.variable]) {
10572						if (this.data.value !== prev[this.variable].value
10573							&& this.sets.value().slice(-1)[0].back_forceme.indexOf(this.variable) === -1) {
10574							this.in_series = false;
10575						}
10576					}
10577				}
10578			}
10579		}
10580		this.variable = false;
10581	}
10582};
10583CSL.Parallel.prototype.CloseCite = function () {
10584	var x, pos, len, has_issued, use_journal_info, volume_pos, container_title_pos, section_pos;
10585	if (this.use_parallels && (this.force_collapse || this.try_cite)) {
10586		use_journal_info = false;
10587		if (!this.cite.front_collapse["container-title"]) {
10588			use_journal_info = true;
10589		}
10590		if (this.cite.front_collapse.volume === false) {
10591			use_journal_info = true;
10592		}
10593		if (this.cite.front_collapse["collection-number"] === false) {
10594			use_journal_info = true;
10595		}
10596		if (this.cite.front_collapse.section === false) {
10597			use_journal_info = true;
10598		}
10599		if (use_journal_info) {
10600			this.cite.use_journal_info = true;
10601			section_pos = this.cite.front.indexOf("section");
10602			if (section_pos > -1) {
10603				this.cite.front = this.cite.front.slice(0,section_pos).concat(this.cite.front.slice(section_pos + 1));
10604			}
10605			volume_pos = this.cite.front.indexOf("volume");
10606			if (volume_pos > -1) {
10607				this.cite.front = this.cite.front.slice(0,volume_pos).concat(this.cite.front.slice(volume_pos + 1));
10608			}
10609			container_title_pos = this.cite.front.indexOf("container-title");
10610			if (container_title_pos > -1) {
10611				this.cite.front = this.cite.front.slice(0,container_title_pos).concat(this.cite.front.slice(container_title_pos + 1));
10612			}
10613			collection_number_pos = this.cite.front.indexOf("collection-number");
10614			if (collection_number_pos > -1) {
10615				this.cite.front = this.cite.front.slice(0,collection_number_pos).concat(this.cite.front.slice(collection_number_pos + 1));
10616			}
10617		}
10618		if (!this.in_series && !this.force_collapse) {
10619			this.ComposeSet(true);
10620		}
10621		if (this.sets.value().length === 0) {
10622			has_date = false;
10623			for (pos = 0, len = this.cite.back.length; pos < len; pos += 1) {
10624				x = this.cite.back[pos];
10625				if (x === "issued" && this.cite["issued"] && this.cite["issued"].value) {
10626					has_date = true;
10627					break;
10628				}
10629			}
10630			if (!has_date) {
10631				this.cite.back_forceme.push("issued");
10632			}
10633		} else {
10634			var idx = this.cite.front.indexOf("issued");
10635			if (idx === -1 || this.master_was_neutral_cite) {
10636				this.cite.back_forceme = this.sets.value().slice(-1)[0].back_forceme;
10637			}
10638			if (idx > -1) {
10639				var prev = this.sets.value()[this.sets.value().length - 1];
10640				if (!prev["issued"]) {
10641					this.cite.front = this.cite.front.slice(0, idx).concat(this.cite.front.slice(idx + 1));
10642				}
10643			}
10644			if (this.master_was_neutral_cite && this.cite.mid.indexOf("names:mid") > -1) {
10645				this.cite.front.push("names:mid");
10646			}
10647		}
10648		this.sets.value().push(this.cite);
10649	}
10650};
10651CSL.Parallel.prototype.ComposeSet = function (next_output_in_progress) {
10652	var cite, pos, master, len;
10653	if (this.use_parallels && (this.force_collapse || this.try_cite)) {
10654		var lengthCheck = this.sets.value().length;
10655		if (this.sets.value().length === 1) {
10656			if (!this.in_series) {
10657				this.sets.value().pop();
10658				this.delim_counter += 1;
10659			}
10660		} else {
10661			len = this.sets.value().length;
10662			for (pos = 0; pos < len; pos += 1) {
10663				cite = this.sets.value()[pos];
10664				if (pos === 0) {
10665					this.delim_counter += 1;
10666				} else {
10667					if (!cite.Item.title && cite.use_journal_info) {
10668						this.delim_pointers.push(false);
10669					} else {
10670						this.delim_pointers.push(this.delim_counter);
10671					}
10672					this.delim_counter += 1;
10673				}
10674				if (CSL.POSITION_FIRST === cite.position) {
10675					if (pos === 0) {
10676						this.state.registry.registry[cite.itemId].master = true;
10677						this.state.registry.registry[cite.itemId].siblings = [];
10678						this.state.registry.registry[cite.itemId].parallel = false;
10679					} else {
10680						if (cite.prevItemID) {
10681							if (!this.state.registry.registry[cite.prevItemID].parallel) {
10682								this.state.registry.registry[cite.itemId].parallel = cite.prevItemID;
10683							} else {
10684								this.state.registry.registry[cite.itemId].parallel = this.state.registry.registry[cite.prevItemID].parallel;
10685							}
10686							this.state.registry.registry[cite.itemId].siblings = this.state.registry.registry[cite.prevItemID].siblings;
10687							if (!this.state.registry.registry[cite.itemId].siblings) {
10688								this.state.registry.registry[cite.itemId].siblings = [];
10689								CSL.debug("WARNING: adding missing siblings array to registry object");
10690							}
10691							this.state.registry.registry[cite.itemId].siblings.push(cite.itemId);
10692						}
10693					}
10694				}
10695			}
10696			this.sets.push([]);
10697		}
10698		if (lengthCheck < 2) {
10699			this.purgeGroupsIfParallel(false);
10700		} else {
10701			this.purgeGroupsIfParallel(true);
10702		}
10703		this.in_series = true;
10704	}
10705};
10706CSL.Parallel.prototype.PruneOutputQueue = function () {
10707	var len, pos, series, ppos, llen, cite;
10708	if (this.use_parallels) {
10709		len = this.sets.mystack.length;
10710		for (pos = 0; pos < len; pos += 1) {
10711			series = this.sets.mystack[pos];
10712			if (series.length > 1) {
10713				llen = series.length;
10714				for (ppos = 0; ppos < llen; ppos += 1) {
10715					cite = series[ppos];
10716					if (ppos === 0) {
10717						this.purgeVariableBlobs(cite, cite.back);
10718					} else if (ppos === (series.length - 1)) {
10719						this.purgeVariableBlobs(cite, cite.front.concat(cite.back_forceme));
10720					} else {
10721						this.purgeVariableBlobs(cite, cite.front.concat(cite.back));
10722					}
10723				}
10724			}
10725		}
10726	}
10727};
10728CSL.Parallel.prototype.purgeVariableBlobs = function (cite, varnames) {
10729	var len, pos, varname, b, llen, ppos, out;
10730	if (this.use_parallels) {
10731		out = this.state.output.current.value();
10732		if ("undefined" === typeof out.length) {
10733			out = out.blobs;
10734		}
10735		for (pos = 0, len = this.delim_pointers.length; pos < len; pos += 1) {
10736			ppos = this.delim_pointers[pos];
10737			if (ppos !== false) {
10738				out[ppos].parallel_delimiter = ", ";
10739			}
10740		}
10741		len = varnames.length - 1;
10742		for (pos = len; pos > -1; pos += -1) {
10743			varname = varnames[pos];
10744			if (cite[varname]) {
10745				llen = cite[varname].blobs.length - 1;
10746				for (ppos = llen; ppos > -1; ppos += -1) {
10747					b = cite[varname].blobs[ppos];
10748					b[0].blobs = b[0].blobs.slice(0, b[1]).concat(b[0].blobs.slice((b[1] + 1)));
10749					this.state.tmp.has_purged_parallel = true;
10750					if (b[0] && b[0].strings && "string" == typeof b[0].strings.oops
10751						&& b[0].parent && b[0].parent) {
10752						b[0].parent.parent.strings.delimiter = b[0].strings.oops;
10753					}
10754				}
10755			}
10756		}
10757	}
10758};
10759CSL.Parallel.prototype.purgeGroupsIfParallel = function (original_condition) {
10760	for (var i = this.parallel_conditional_blobs_list.length - 1; i > -1; i += -1) {
10761		var obj = this.parallel_conditional_blobs_list[i];
10762		var purgeme = true;
10763		for (var j = 0, jlen = obj.conditions.length; j < jlen; j += 1) {
10764			if (!(!obj.conditions[j] === !!original_condition
10765				|| ("master" === obj.conditions[j]
10766					&& !this.state.registry.registry[obj.id].master)
10767				|| ("servant" === obj.conditions[j]
10768					&& !this.state.registry.registry[obj.id].parallel))) {
10769				var purgeme = false;
10770				break;
10771			}
10772		}
10773		if (purgeme) {
10774			var buffer = [];
10775			while (obj.blobs.length > obj.pos) {
10776				buffer.push(obj.blobs.pop());
10777			}
10778			if (buffer.length) {
10779				buffer.pop();
10780			}
10781			while (buffer.length) {
10782				obj.blobs.push(buffer.pop());
10783			}
10784		}
10785		this.parallel_conditional_blobs_list.pop();
10786	}
10787}
10788CSL.Util = {};
10789CSL.Util.Match = function () {
10790	this.any = function (token, state, tests) {
10791		return function (Item, item) {
10792			for (var i=0, ilen=tests.length; i < ilen; i += 1) {
10793				result = tests[i](Item, item);
10794				if (result) {
10795					return true;
10796				}
10797			}
10798			return false;
10799		};
10800	};
10801	this.none = function (token, state, tests) {
10802		return function (Item, item) {
10803			for (var i=0,ilen=tests.length;i<ilen;i+=1) {
10804				result = tests[i](Item,item);
10805				if (result) {
10806					return false;
10807				}
10808			}
10809			return true;
10810		};
10811	};
10812	this.all = function (token, state, tests) {
10813		return function (Item, item) {
10814			for (var i=0,ilen=tests.length;i<ilen;i+=1) {
10815				result = tests[i](Item,item);
10816				if (!result) {
10817					return false;
10818				}
10819			}
10820			return true;
10821		};
10822	};
10823	this[undefined] = this.all;
10824	this.nand = function (token, state, tests) {
10825		return function (Item, item) {
10826			for (var i=0,ilen=tests.length;i<ilen;i+=1) {
10827				result = tests[i](Item,item);
10828				if (!result) {
10829					return true;
10830				}
10831			}
10832			return false;
10833		};
10834	};
10835};
10836CSL.Transform = function (state) {
10837	var debug = false, abbreviations, token, fieldname, abbrev_family, opt;
10838	this.abbrevs = {};
10839	this.abbrevs["default"] = new state.sys.AbbreviationSegments();
10840	this.getTextSubField = getTextSubField;
10841	function abbreviate(state, Item, altvar, basevalue, myabbrev_family, use_field) {
10842		var value;
10843		if (!myabbrev_family) {
10844			return basevalue;
10845		}
10846		var variable = myabbrev_family;
10847		var noHints = false;
10848		if (["title", "title-short"].indexOf(variable) > -1 && !Item.jurisdiction) {
10849			noHints = true;
10850		}
10851		if (CSL.NUMERIC_VARIABLES.indexOf(myabbrev_family) > -1) {
10852			myabbrev_family = "number";
10853		}
10854		if (["publisher-place", "event-place", "jurisdiction", "archive-place"].indexOf(myabbrev_family) > -1) {
10855			myabbrev_family = "place";
10856		}
10857		if (["publisher", "authority"].indexOf(myabbrev_family) > -1) {
10858			myabbrev_family = "institution-part";
10859		}
10860		if (["genre", "event", "medium", "title-short"].indexOf(myabbrev_family) > -1) {
10861			myabbrev_family = "title";
10862		}
10863		if (["archive"].indexOf(myabbrev_family) > -1) {
10864			myabbrev_family = "collection-title";
10865		}
10866		value = "";
10867		if (state.sys.getAbbreviation) {
10868			var jurisdiction = state.transform.loadAbbreviation(Item.jurisdiction, myabbrev_family, basevalue, Item.type, noHints);
10869			if (state.transform.abbrevs[jurisdiction][myabbrev_family] && basevalue && state.sys.getAbbreviation) {
10870				if (state.transform.abbrevs[jurisdiction][myabbrev_family][basevalue]) {
10871					value = state.transform.abbrevs[jurisdiction][myabbrev_family][basevalue].replace("{stet}",basevalue);
10872				}
10873			}
10874		}
10875		if (!value
10876			&& (!state.opt.development_extensions.require_explicit_legal_case_title_short || Item.type !== 'legal_case')
10877			&& altvar && Item[altvar] && use_field) {
10878			value = Item[altvar];
10879		}
10880		if (!value) {
10881			value = basevalue;
10882		}
10883		if (value && value.slice(0, 10) === "!here>>>") {
10884			if (variable === "jurisdiction" && ["treaty", "patent"].indexOf(variable) > -1) {
10885				value = value.slice(10);
10886			} else {
10887				value = false;
10888			}
10889		}
10890		return value;
10891	}
10892	function getFieldLocale(Item,field) {
10893		var ret = state.opt["default-locale"][0].slice(0, 2)
10894		var localeRex;
10895		if (state.opt.development_extensions.strict_text_case_locales) {
10896			localeRex = new RegExp("^([a-zA-Z]{2})(?:$|-.*| .*)");
10897		} else {
10898			localeRex = new RegExp("^([a-zA-Z]{2})(?:$|-.*|.*)");
10899		}
10900		if (Item.language) {
10901			m = ("" + Item.language).match(localeRex);
10902			if (m) {
10903				ret = m[1];
10904			} else {
10905				ret = "tlh";
10906			}
10907		}
10908		if (Item.multi && Item.multi && Item.multi.main && Item.multi.main[field]) {
10909			ret = Item.multi.main[field];
10910		}
10911		if (!state.opt.development_extensions.strict_text_case_locales
10912			 || state.opt.development_extensions.normalize_lang_keys_to_lowercase) {
10913			ret = ret.toLowerCase();
10914		}
10915		return ret;
10916	};
10917	function getTextSubField(Item, field, locale_type, use_default, stopOrig) {
10918		var m, lst, opt, o, oo, pos, key, ret, len, myret, opts;
10919		var usedOrig = stopOrig;
10920		if (!Item[field]) {
10921			return {name:"", usedOrig:stopOrig};
10922		}
10923		ret = {name:"", usedOrig:stopOrig,locale:getFieldLocale(Item,field)};
10924		opts = state.opt[locale_type];
10925		if (locale_type === 'locale-orig') {
10926			if (stopOrig) {
10927				ret = {name:"", usedOrig:stopOrig};
10928			} else {
10929				ret = {name:Item[field], usedOrig:false, locale:getFieldLocale(Item,field)};
10930			}
10931			return ret;
10932		} else if (use_default && ("undefined" === typeof opts || opts.length === 0)) {
10933			return {name:Item[field], usedOrig:true, locale:getFieldLocale(Item,field)};
10934		}
10935		for (var i = 0, ilen = opts.length; i < ilen; i += 1) {
10936			opt = opts[i];
10937			o = opt.split(/[\-_]/)[0];
10938			if (opt && Item.multi && Item.multi._keys[field] && Item.multi._keys[field][opt]) {
10939				ret.name = Item.multi._keys[field][opt];
10940				ret.locale = o;
10941				break;
10942			} else if (o && Item.multi && Item.multi._keys[field] && Item.multi._keys[field][o]) {
10943				ret.name = Item.multi._keys[field][o];
10944				ret.locale = o;
10945				break;
10946			}
10947		}
10948		if (!ret.name && use_default) {
10949			ret = {name:Item[field], usedOrig:true, locale:getFieldLocale(Item,field)};
10950		}
10951		return ret;
10952	}
10953	function loadAbbreviation(jurisdiction, category, orig, itemType, noHints) {
10954		var pos, len;
10955		if (!jurisdiction) {
10956			jurisdiction = "default";
10957		}
10958		if (!orig) {
10959			if (!state.transform.abbrevs[jurisdiction]) {
10960				state.transform.abbrevs[jurisdiction] = new state.sys.AbbreviationSegments();
10961			}
10962			return jurisdiction;
10963		}
10964		if (state.sys.getAbbreviation) {
10965			var tryList = ['default'];
10966			if (jurisdiction !== 'default') {
10967				var workLst = jurisdiction.split(/\s*;\s*/);
10968				for (var i=0, ilen=workLst.length; i < ilen; i += 1) {
10969					tryList.push(workLst.slice(0,i+1).join(';'));
10970				}
10971			}
10972			for (var i=tryList.length - 1; i > -1; i += -1) {
10973				if (!state.transform.abbrevs[tryList[i]]) {
10974					state.transform.abbrevs[tryList[i]] = new state.sys.AbbreviationSegments();
10975				}
10976				if (!state.transform.abbrevs[tryList[i]][category][orig]) {
10977					state.sys.getAbbreviation(state.opt.styleID, state.transform.abbrevs, tryList[i], category, orig, itemType, noHints);
10978				}
10979				if (state.transform.abbrevs[tryList[i]][category][orig]) {
10980					if (i < tryList.length) {
10981						state.transform.abbrevs[jurisdiction][category][orig] = state.transform.abbrevs[tryList[i]][category][orig];
10982					}
10983					break;
10984				}
10985			}
10986		}
10987		return jurisdiction;
10988	}
10989	this.loadAbbreviation = loadAbbreviation;
10990	function publisherCheck (tok, Item, primary, myabbrev_family) {
10991		var varname = tok.variables[0];
10992		if (state.publisherOutput && primary) {
10993			if (["publisher","publisher-place"].indexOf(varname) === -1) {
10994				return false;
10995			} else {
10996				state.publisherOutput[varname + "-token"] = tok;
10997				state.publisherOutput.varlist.push(varname);
10998				var lst = primary.split(/;\s*/);
10999				if (lst.length === state.publisherOutput[varname + "-list"].length) {
11000					state.publisherOutput[varname + "-list"] = lst;
11001				}
11002				for (var i = 0, ilen = lst.length; i < ilen; i += 1) {
11003					lst[i] = abbreviate(state, Item, false, lst[i], myabbrev_family, true);
11004				}
11005				state.tmp[varname + "-token"] = tok;
11006				return true;
11007			}
11008		}
11009		return false;
11010	}
11011	function getOutputFunction(variables, myabbrev_family, abbreviation_fallback, alternative_varname, transform_fallback) {
11012		var localesets;
11013		var langPrefs = CSL.LangPrefsMap[variables[0]];
11014		if (!langPrefs) {
11015			localesets = false;
11016		} else {
11017			localesets = state.opt['cite-lang-prefs'][langPrefs];
11018		}
11019		return function (state, Item, item, usedOrig) {
11020			var primary, primary_locale, secondary, secondary_locale, tertiary, tertiary_locale, primary_tok, group_tok, key;
11021			if (!variables[0] || (!Item[variables[0]] && !Item[alternative_varname])) {
11022				return null;
11023			}
11024			if (state.opt.suppressJurisdictions
11025				&& variables[0] === "jurisdiction"
11026				&& state.opt.suppressJurisdictions[Item.jurisdiction]
11027				&& ["legal_case","gazette","regulation","legislation"].indexOf(Item.type) > -1) {
11028				return null;
11029			}
11030			var slot = {primary:false, secondary:false, tertiary:false};
11031			if (state.tmp.area.slice(-5) === "_sort") {
11032				slot.primary = 'locale-sort';
11033			} else {
11034				if (localesets) {
11035					var slotnames = ["primary", "secondary", "tertiary"];
11036					for (var i = 0, ilen = slotnames.length; i < ilen; i += 1) {
11037						if (localesets.length - 1 <  i) {
11038							break;
11039						}
11040						if (localesets[i]) {
11041							slot[slotnames[i]] = 'locale-' + localesets[i];
11042						}
11043					}
11044				} else {
11045					slot.primary = 'locale-orig';
11046				}
11047			}
11048			if ((state.tmp.area !== "bibliography"
11049				 && !(state.tmp.area === "citation"
11050						&& state.opt.xclass === "note"
11051						&& item && !item.position))) {
11052				slot.secondary = false;
11053				slot.tertiary = false;
11054			}
11055			if (state.tmp["publisher-list"]) {
11056				if (variables[0] === "publisher") {
11057					state.tmp["publisher-token"] = this;
11058				} else if (variables[0] === "publisher-place") {
11059					state.tmp["publisher-place-token"] = this;
11060				}
11061				return null;
11062			}
11063			var res = getTextSubField(Item, variables[0], slot.primary, true);
11064			primary = res.name;
11065			primary_locale = res.locale;
11066			var primaryUsedOrig = res.usedOrig;
11067			if (publisherCheck(this, Item, primary, myabbrev_family)) {
11068				return null;
11069			}
11070			secondary = false;
11071			tertiary = false;
11072			if (slot.secondary) {
11073				res = getTextSubField(Item, variables[0], slot.secondary, false, res.usedOrig);
11074				secondary = res.name;
11075				secondary_locale = res.locale;
11076			}
11077			if (slot.tertiary) {
11078				res = getTextSubField(Item, variables[0], slot.tertiary, false, res.usedOrig);
11079				tertiary = res.name;
11080				tertiary_locale = res.locale;
11081			}
11082			if (myabbrev_family) {
11083				primary = abbreviate(state, Item, alternative_varname, primary, myabbrev_family, true);
11084				if (primary) {
11085					primary = quashCheck(primary);
11086				}
11087				secondary = abbreviate(state, Item, false, secondary, myabbrev_family, true);
11088				tertiary = abbreviate(state, Item, false, tertiary, myabbrev_family, true);
11089			}
11090			var template_tok = CSL.Util.cloneToken(this);
11091			var primary_tok = CSL.Util.cloneToken(this);
11092			var primaryPrefix;
11093			if (slot.primary === "locale-translit") {
11094				primaryPrefix = state.opt.citeAffixes[langPrefs][slot.primary].prefix;
11095			}
11096			if (primaryPrefix === "<i>" && variables[0] === 'title' && !primaryUsedOrig) {
11097				var hasItalic = false;
11098				for (var i = 0, ilen = primary_tok.decorations.length; i < ilen; i += 1) {
11099					if (primary_tok.decorations[i][0] === "@font-style"
11100						&& primary_tok.decorations[i][1] === "italic") {
11101						hasItalic = true;
11102					}
11103				}
11104				if (!hasItalic) {
11105					primary_tok.decorations.push(["@font-style", "italic"])
11106				}
11107			}
11108			if (primary_locale !== "en" && primary_tok.strings["text-case"] === "title") {
11109				primary_tok.strings["text-case"] = "passthrough";
11110			}
11111			if ("title" === variables[0]) {
11112				primary = CSL.demoteNoiseWords(state, primary, this["leading-noise-words"]);
11113			}
11114			if (secondary || tertiary) {
11115				state.output.openLevel("empty");
11116				primary_tok.strings.suffix = primary_tok.strings.suffix.replace(/[ .,]+$/,"");
11117				state.output.append(primary, primary_tok);
11118				if (secondary) {
11119					secondary_tok = CSL.Util.cloneToken(template_tok);
11120					secondary_tok.strings.prefix = state.opt.citeAffixes[langPrefs][slot.secondary].prefix;
11121					secondary_tok.strings.suffix = state.opt.citeAffixes[langPrefs][slot.secondary].suffix;
11122					if (!secondary_tok.strings.prefix) {
11123						secondary_tok.strings.prefix = " ";
11124					}
11125					for (var i = secondary_tok.decorations.length - 1; i > -1; i += -1) {
11126						if (['@quotes/true','@font-style/italic','@font-style/oblique','@font-weight/bold'].indexOf(secondary_tok.decorations[i].join('/')) > -1) {
11127							secondary_tok.decorations = secondary_tok.decorations.slice(0, i).concat(secondary_tok.decorations.slice(i + 1))
11128						}
11129					}
11130					if (secondary_locale !== "en" && secondary_tok.strings["text-case"] === "title") {
11131						secondary_tok.strings["text-case"] = "passthrough";
11132					}
11133					state.output.append(secondary, secondary_tok);
11134					var blob_obj = state.output.current.value();
11135					var blobs_pos = state.output.current.value().blobs.length - 1;
11136					if (state.parallel.use_parallels) {
11137						state.parallel.cite.front.push(variables[0] + ":secondary");
11138						state.parallel.cite[variables[0] + ":secondary"] = {blobs:[[blob_obj, blobs_pos]]};
11139					}
11140				}
11141				if (tertiary) {
11142					tertiary_tok = CSL.Util.cloneToken(template_tok);
11143					tertiary_tok.strings.prefix = state.opt.citeAffixes[langPrefs][slot.tertiary].prefix;
11144					tertiary_tok.strings.suffix = state.opt.citeAffixes[langPrefs][slot.tertiary].suffix;
11145					if (!tertiary_tok.strings.prefix) {
11146						tertiary_tok.strings.prefix = " ";
11147					}
11148					for (var i = tertiary_tok.decorations.length - 1; i > -1; i += -1) {
11149						if (['@quotes/true','@font-style/italic','@font-style/oblique','@font-weight/bold'].indexOf(tertiary_tok.decorations[i].join('/')) > -1) {
11150							tertiary_tok.decorations = tertiary_tok.decorations.slice(0, i).concat(tertiary_tok.decorations.slice(i + 1))
11151						}
11152					}
11153					if (tertiary_locale !== "en" && tertiary_tok.strings["text-case"] === "title") {
11154						tertiary_tok.strings["text-case"] = "passthrough";
11155					}
11156					state.output.append(tertiary, tertiary_tok);
11157					var blob_obj = state.output.current.value();
11158					var blobs_pos = state.output.current.value().blobs.length - 1;
11159					if (state.parallel.use_parallels) {
11160						state.parallel.cite.front.push(variables[0] + ":tertiary");
11161						state.parallel.cite[variables[0] + ":tertiary"] = {blobs:[[blob_obj, blobs_pos]]};
11162					}
11163				}
11164				state.output.closeLevel();
11165			} else {
11166				state.output.append(primary, primary_tok);
11167			}
11168			return null;
11169		};
11170	}
11171	this.getOutputFunction = getOutputFunction;
11172	function quashCheck(value) {
11173		var m = value.match(/^!([-,_a-z]+)>>>/);
11174		if (m) {
11175			var fields = m[1].split(",");
11176			value = value.slice(m[0].length);
11177			for (var i = 0, ilen = fields.length; i < ilen; i += 1) {
11178				if (state.tmp.done_vars.indexOf(fields[i]) === -1) {
11179					state.tmp.done_vars.push(fields[i]);
11180				}
11181			}
11182		}
11183		return value;
11184	}
11185	this.quashCheck = quashCheck;
11186};
11187CSL.Token = function (name, tokentype) {
11188	this.name = name;
11189	this.strings = {};
11190	this.strings.delimiter = undefined;
11191	this.strings.prefix = "";
11192	this.strings.suffix = "";
11193	this.decorations = [];
11194	this.variables = [];
11195	this.execs = [];
11196	this.tokentype = tokentype;
11197	this.evaluator = false;
11198	this.tests = [];
11199	this.rawtests = [];
11200	this.succeed = false;
11201	this.fail = false;
11202	this.next = false;
11203};
11204CSL.Util.cloneToken = function (token) {
11205	var newtok, key, pos, len;
11206	if ("string" === typeof token) {
11207		return token;
11208	}
11209	newtok = new CSL.Token(token.name, token.tokentype);
11210	for (key in token.strings) {
11211		if (token.strings.hasOwnProperty(key)) {
11212			newtok.strings[key] = token.strings[key];
11213		}
11214	}
11215	if (token.decorations) {
11216		newtok.decorations = [];
11217		for (pos = 0, len = token.decorations.length; pos < len; pos += 1) {
11218			newtok.decorations.push(token.decorations[pos].slice());
11219		}
11220	}
11221	if (token.variables) {
11222		newtok.variables = token.variables.slice();
11223	}
11224	if (token.execs) {
11225		newtok.execs = token.execs.slice();
11226		newtok.tests = token.tests.slice();
11227		newtok.rawtests = token.tests.slice();
11228	}
11229	return newtok;
11230};
11231CSL.AmbigConfig = function () {
11232	this.maxvals = [];
11233	this.minval = 1;
11234	this.names = [];
11235	this.givens = [];
11236	this.year_suffix = false;
11237	this.disambiguate = 0;
11238};
11239CSL.Blob = function (str, token, levelname) {
11240	var len, pos, key;
11241	this.levelname = levelname;
11242	if (token) {
11243		this.strings = {"prefix":"","suffix":""};
11244		for (key in token.strings) {
11245			if (token.strings.hasOwnProperty(key)) {
11246				this.strings[key] = token.strings[key];
11247			}
11248		}
11249		this.decorations = [];
11250		if (token.decorations === undefined) {
11251			len = 0;
11252		} else {
11253			len = token.decorations.length;
11254		}
11255		for (pos = 0; pos < len; pos += 1) {
11256			this.decorations.push(token.decorations[pos].slice());
11257		}
11258	} else {
11259		this.strings = {};
11260		this.strings.prefix = "";
11261		this.strings.suffix = "";
11262		this.strings.delimiter = "";
11263		this.decorations = [];
11264	}
11265	if ("string" === typeof str) {
11266		this.blobs = str;
11267	} else if (str) {
11268		this.blobs = [str];
11269	} else {
11270		this.blobs = [];
11271	}
11272	this.alldecor = [this.decorations];
11273};
11274CSL.Blob.prototype.push = function (blob) {
11275	if ("string" === typeof this.blobs) {
11276		throw "Attempt to push blob onto string object";
11277	} else if (false !== blob) {
11278		blob.alldecor = blob.alldecor.concat(this.alldecor);
11279		this.blobs.push(blob);
11280	}
11281};
11282CSL.NumericBlob = function (num, mother_token, id) {
11283	this.id = id;
11284	this.alldecor = [];
11285	this.num = num;
11286	this.blobs = num.toString();
11287	this.status = CSL.START;
11288	this.strings = {};
11289	if (mother_token) {
11290		this.gender = mother_token.gender;
11291		this.decorations = mother_token.decorations;
11292		this.strings.prefix = mother_token.strings.prefix;
11293		this.strings.suffix = mother_token.strings.suffix;
11294		this.strings["text-case"] = mother_token.strings["text-case"];
11295		this.successor_prefix = mother_token.successor_prefix;
11296		this.range_prefix = mother_token.range_prefix;
11297		this.splice_prefix = mother_token.splice_prefix;
11298		this.formatter = mother_token.formatter;
11299		if (!this.formatter) {
11300			this.formatter =  new CSL.Output.DefaultFormatter();
11301		}
11302		if (this.formatter) {
11303			this.type = this.formatter.format(1);
11304		}
11305	} else {
11306		this.decorations = [];
11307		this.strings.prefix = "";
11308		this.strings.suffix = "";
11309		this.successor_prefix = "";
11310		this.range_prefix = "";
11311		this.splice_prefix = "";
11312		this.formatter = new CSL.Output.DefaultFormatter();
11313	}
11314};
11315CSL.NumericBlob.prototype.setFormatter = function (formatter) {
11316	this.formatter = formatter;
11317	this.type = this.formatter.format(1);
11318};
11319CSL.Output.DefaultFormatter = function () {};
11320CSL.Output.DefaultFormatter.prototype.format = function (num) {
11321	return num.toString();
11322};
11323CSL.NumericBlob.prototype.checkNext = function (next,start) {
11324	if (start) {
11325		this.status = CSL.START;
11326		if ("object" === typeof next) {
11327			if (next.num === (this.num + 1)) {
11328				next.status = CSL.SUCCESSOR;
11329			} else {
11330				next.status = CSL.SEEN;
11331			}
11332		}
11333	} else if (! next || !next.num || this.type !== next.type || next.num !== (this.num + 1)) {
11334		if (this.status === CSL.SUCCESSOR_OF_SUCCESSOR) {
11335			this.status = CSL.END;
11336		}
11337		if ("object" === typeof next) {
11338			next.status = CSL.SEEN;
11339		}
11340	} else { // next number is in the sequence
11341		if (this.status === CSL.START || this.status === CSL.SEEN) {
11342			next.status = CSL.SUCCESSOR;
11343		} else if (this.status === CSL.SUCCESSOR || this.status === CSL.SUCCESSOR_OF_SUCCESSOR) {
11344			if (this.range_prefix) {
11345				next.status = CSL.SUCCESSOR_OF_SUCCESSOR;
11346				this.status = CSL.SUPPRESS;
11347			} else {
11348				next.status = CSL.SUCCESSOR;
11349			}
11350		}
11351	}
11352};
11353CSL.NumericBlob.prototype.checkLast = function (last) {
11354	if (this.status === CSL.SEEN
11355	|| (last.num !== (this.num - 1) && this.status === CSL.SUCCESSOR)) {
11356		this.status = CSL.SUCCESSOR;
11357		return true;
11358	}
11359	return false;
11360};
11361CSL.Util.fixDateNode = function (parent, pos, node) {
11362	var form, variable, datexml, subnode, partname, attr, val, prefix, suffix, children, key, subchildren, kkey, display, cslid;
11363	this.build.date_key = true;
11364	form = this.sys.xml.getAttributeValue(node, "form");
11365	var lingo;
11366	if ("accessed" === this.sys.xml.getAttributeValue(node, "variable")) {
11367		lingo = this.opt["default-locale"][0];
11368	} else {
11369		lingo = this.sys.xml.getAttributeValue(node, "lingo");
11370	}
11371	if (!this.getDate(form)) {
11372		return parent;
11373	}
11374	var dateparts = this.sys.xml.getAttributeValue(node, "date-parts");
11375	variable = this.sys.xml.getAttributeValue(node, "variable");
11376	prefix = this.sys.xml.getAttributeValue(node, "prefix");
11377	suffix = this.sys.xml.getAttributeValue(node, "suffix");
11378	display = this.sys.xml.getAttributeValue(node, "display");
11379	cslid = this.sys.xml.getAttributeValue(node, "cslid");
11380	datexml = this.sys.xml.nodeCopy(this.getDate(form, ("accessed" === variable)));
11381	this.sys.xml.setAttribute(datexml, 'lingo', this.opt.lang);
11382	this.sys.xml.setAttribute(datexml, 'form', form);
11383	this.sys.xml.setAttribute(datexml, 'date-parts', dateparts);
11384	this.sys.xml.setAttribute(datexml, "cslid", cslid);
11385	this.sys.xml.setAttribute(datexml, 'variable', variable);
11386	if (prefix) {
11387		this.sys.xml.setAttribute(datexml, "prefix", prefix);
11388	}
11389	if (suffix) {
11390		this.sys.xml.setAttribute(datexml, "suffix", suffix);
11391	}
11392	if (display) {
11393		this.sys.xml.setAttribute(datexml, "display", display);
11394	}
11395	children = this.sys.xml.children(node);
11396	for (key in children) {
11397			subnode = children[key];
11398			if ("date-part" === this.sys.xml.nodename(subnode)) {
11399				partname = this.sys.xml.getAttributeValue(subnode, "name");
11400				subchildren = this.sys.xml.attributes(subnode);
11401				for (attr in subchildren) {
11402					if (subchildren.hasOwnProperty(attr)) {
11403						if ("@name" === attr) {
11404							continue;
11405						}
11406						if (lingo && lingo !== this.opt.lang) {
11407							if (["@suffix", "@prefix", "@form"].indexOf(attr) > -1) {
11408								continue;
11409							}
11410						}
11411						val = subchildren[attr];
11412						this.sys.xml.setAttributeOnNodeIdentifiedByNameAttribute(datexml, "date-part", partname, attr, val);
11413					}
11414				}
11415			}
11416	}
11417	if ("year" === this.sys.xml.getAttributeValue(node, "date-parts")) {
11418		this.sys.xml.deleteNodeByNameAttribute(datexml, 'month');
11419		this.sys.xml.deleteNodeByNameAttribute(datexml, 'day');
11420	} else if ("year-month" === this.sys.xml.getAttributeValue(node, "date-parts")) {
11421		this.sys.xml.deleteNodeByNameAttribute(datexml, 'day');
11422	}
11423	return this.sys.xml.insertChildNodeAfter(parent, node, pos, datexml);
11424};
11425CSL.dateMacroAsSortKey = function (state, Item) {
11426	CSL.dateAsSortKey.call(this, state, Item, true);
11427};
11428CSL.dateAsSortKey = function (state, Item, isMacro) {
11429	var dp, elem, value, e, yr, prefix, i, ilen, num;
11430	var variable = this.variables[0];
11431	var macroFlag = "empty";
11432	if (isMacro) {
11433		macroFlag = "macro-with-date";
11434	}
11435	dp = Item[variable];
11436	if ("undefined" === typeof dp) {
11437		dp = {"date-parts": [[0]] };
11438		if (!dp.year) {
11439			state.tmp.empty_date = true;
11440		}
11441	}
11442	if ("undefined" === typeof this.dateparts) {
11443		this.dateparts = ["year", "month", "day"];
11444	}
11445	if (dp.raw) {
11446		dp = state.fun.dateparser.parse(dp.raw);
11447	} else if (dp["date-parts"]) {
11448		dp = state.dateParseArray(dp);
11449	}
11450	if ("undefined" === typeof dp) {
11451		dp = {};
11452	}
11453	for (i = 0, ilen = CSL.DATE_PARTS_INTERNAL.length; i < ilen; i += 1) {
11454		elem = CSL.DATE_PARTS_INTERNAL[i];
11455		value = 0;
11456		e = elem;
11457		if (e.slice(-4) === "_end") {
11458			e = e.slice(0, -4);
11459		}
11460		if (dp[elem] && this.dateparts.indexOf(e) > -1) {
11461			value = dp[elem];
11462		}
11463		if (elem.slice(0, 4) === "year") {
11464			yr = CSL.Util.Dates[e].numeric(state, value);
11465			prefix = "Y";
11466			if (yr[0] === "-") {
11467				prefix = "X";
11468				yr = yr.slice(1);
11469				yr = 9999 - parseInt(yr, 10);
11470			}
11471			state.output.append(CSL.Util.Dates[elem.slice(0, 4)].numeric(state, (prefix + yr)), macroFlag);
11472		} else {
11473			value = CSL.Util.Dates[e]["numeric-leading-zeros"](state, value);
11474			if (!value) {
11475				value = "00";
11476			}
11477			state.output.append(value, macroFlag);
11478		}
11479	}
11480};
11481CSL.Engine.prototype.dateParseArray = function (date_obj) {
11482	var ret, field, dpos, ppos, dp, exts, llen, pos, len, pppos, lllen;
11483	ret = {};
11484	for (field in date_obj) {
11485		if (field === "date-parts") {
11486			dp = date_obj["date-parts"];
11487			if (dp.length > 1) {
11488				if (dp[0].length !== dp[1].length) {
11489					CSL.error("CSL data error: element mismatch in date range input.");
11490				}
11491			}
11492			exts = ["", "_end"];
11493			for (var i = 0, ilen = dp.length; i < ilen; i += 1) {
11494				for (var j = 0, jlen = CSL.DATE_PARTS.length; j < jlen; j += 1) {
11495					if ("undefined" === typeof dp[i][j]) {
11496						ret[(CSL.DATE_PARTS[j] + exts[i])] = dp[i][j];
11497					} else {
11498						ret[(CSL.DATE_PARTS[j] + exts[i])] = parseInt(dp[i][j], 10);
11499					}
11500				}
11501			}
11502		} else if (date_obj.hasOwnProperty(field)) {
11503			if (field === "literal" && "object" === typeof date_obj.literal && "string" === typeof date_obj.literal.part) {
11504				CSL.debug("Warning: fixing up weird literal date value");
11505				ret.literal = date_obj.literal.part;
11506			} else {
11507				ret[field] = date_obj[field];
11508			}
11509		}
11510	}
11511	return ret;
11512};
11513CSL.Util.Names = {};
11514CSL.Util.Names.compareNamesets = CSL.NameOutput.prototype._compareNamesets;
11515CSL.Util.Names.unInitialize = function (state, name) {
11516	var i, ilen, namelist, punctlist, ret;
11517	if (!name) {
11518		return "";
11519	}
11520	namelist = name.split(/(?:\-|\s+)/);
11521	punctlist = name.match(/(\-|\s+)/g);
11522	ret = "";
11523	for (i = 0, ilen = namelist.length; i < ilen; i += 1) {
11524		if (CSL.ALL_ROMANESQUE_REGEXP.exec(namelist[i].slice(0,-1))
11525			&& namelist[i]
11526			&& namelist[i] !== namelist[i].toUpperCase()) {
11527			namelist[i] = namelist[i].slice(0, 1) + namelist[i].slice(1, 2).toLowerCase() + namelist[i].slice(2);
11528		}
11529		ret += namelist[i];
11530		if (i < ilen - 1) {
11531			ret += punctlist[i];
11532		}
11533	}
11534	return ret;
11535};
11536CSL.Util.Names.initializeWith = function (state, name, terminator, normalizeOnly) {
11537	var i, ilen, j, jlen, n, m, mm, str, lst, ret;
11538	if (!name) {
11539		return "";
11540	}
11541	if (["Lord", "Lady"].indexOf(name) > -1
11542		|| (!name.match(CSL.STARTSWITH_ROMANESQUE_REGEXP)
11543			&& !terminator.match("%s"))) {
11544		return name;
11545	}
11546	if (!terminator) {
11547		terminator = "";
11548	}
11549	var namelist = name;
11550	if (state.opt["initialize-with-hyphen"] === false) {
11551		namelist = namelist.replace(/\-/g, " ");
11552	}
11553	namelist = namelist.replace(/\s*\-\s*/g, "-").replace(/\s+/g, " ");
11554	namelist = namelist.replace(/-([a-z])/g, "\u2013$1");
11555	mm = namelist.match(/[\-\s]+/g);
11556	lst = namelist.split(/[\-\s]+/);
11557	if (lst.length === 0) {
11558		namelist = mm;
11559	} else {
11560		namelist = [lst[0]];
11561		for (i = 1, ilen = lst.length; i < ilen; i += 1) {
11562			namelist.push(mm[i - 1]);
11563			namelist.push(lst[i]);
11564		}
11565	}
11566	lst = namelist;
11567	for (i = lst.length -1; i > -1; i += -1) {
11568		if (lst[i] && lst[i].slice(0, -1).indexOf(".") > -1) {
11569			var lstend = lst.slice(i + 1);
11570			var lstmid = lst[i].slice(0, -1).split(".");
11571			lst = lst.slice(0, i);
11572			for (j = 0, jlen = lstmid.length; j < jlen; j += 1) {
11573				lst.push(lstmid[j] + ".");
11574				if (j < lstmid.length - 1) {
11575					lst.push(" ");
11576				}
11577			}
11578			lst = lst.concat(lstend);
11579		}
11580	}
11581	if (normalizeOnly) {
11582		ret = CSL.Util.Names.doNormalize(state, lst, terminator);
11583	} else {
11584		ret = CSL.Util.Names.doInitialize(state, lst, terminator);
11585	}
11586	ret = ret.replace(/\u2013([a-z])/g, "-$1");
11587	return ret;
11588};
11589CSL.Util.Names.doNormalize = function (state, namelist, terminator, mode) {
11590	var i, ilen;
11591	var isAbbrev = [];
11592	for (i = 0, ilen = namelist.length; i < ilen; i += 1) {
11593		if (namelist[i].length > 1 && namelist[i].slice(-1) === ".") {
11594			namelist[i] = namelist[i].slice(0, -1);
11595			isAbbrev.push(true);
11596		} else if (namelist[i].length === 1 && namelist[i].toUpperCase() === namelist[i]) {
11597			isAbbrev.push(true);
11598		} else {
11599			isAbbrev.push(false);
11600		}
11601	}
11602	var ret = [];
11603	for (i = 0, ilen = namelist.length; i < ilen; i += 2) {
11604		if (isAbbrev[i]) {
11605			if (i < namelist.length - 2) {
11606				namelist[i + 1] = "";
11607				if ((!terminator || terminator.slice(-1) && terminator.slice(-1) !== " ")
11608					&& namelist[i].length && namelist[i].match(CSL.ALL_ROMANESQUE_REGEXP)
11609					&& (namelist[i].length > 1 || namelist[i + 2].length > 1)) {
11610					namelist[i + 1] = " ";
11611				}
11612				namelist[i] = namelist[i] + terminator;
11613			}
11614			if (i === namelist.length - 1) {
11615				namelist[i] = namelist[i] + terminator;
11616			}
11617		}
11618	}
11619	return namelist.join("").replace(/\s+$/,"");
11620};
11621CSL.Util.Names.doInitialize = function (state, namelist, terminator, mode) {
11622	var i, ilen, m, j, jlen, lst, n;
11623	for (i = 0, ilen = namelist.length; i < ilen; i += 2) {
11624		n = namelist[i];
11625		if (!n) {
11626			continue;
11627		}
11628		m = n.match(CSL.NAME_INITIAL_REGEXP);
11629		if (!m && (!n.match(CSL.STARTSWITH_ROMANESQUE_REGEXP) && n.length > 1 && terminator.match("%s"))) {
11630			m = n.match(/(.)(.*)/);
11631		}
11632		if (m && m[1] === m[1].toUpperCase()) {
11633			var extra = "";
11634			if (m[2]) {
11635				var s = "";
11636				lst = m[2].split("");
11637				for (j = 0, jlen = lst.length; j < jlen; j += 1) {
11638					var c = lst[j];
11639					if (c === c.toUpperCase()) {
11640						s += c;
11641					} else {
11642						break;
11643					}
11644				}
11645				if (s.length < m[2].length) {
11646					extra = s.toLocaleLowerCase();
11647				}
11648			}
11649			namelist[i] = m[1].toLocaleUpperCase() + extra;
11650			if (i < (ilen - 1)) {
11651				if (terminator.match("%s")) {
11652					namelist[i] = terminator.replace("%s", namelist[i]);
11653				} else {
11654					if (namelist[i + 1].indexOf("-") > -1) {
11655						namelist[i + 1] = terminator + namelist[i + 1];
11656					} else {
11657						namelist[i + 1] = terminator;
11658					}
11659				}
11660			} else {
11661				if (terminator.match("%s")) {
11662					namelist[i] = terminator.replace("%s", namelist[i]);
11663				} else {
11664					namelist.push(terminator);
11665				}
11666			}
11667		} else if (n.match(CSL.ROMANESQUE_REGEXP)) {
11668			namelist[i] = " " + n;
11669		}
11670	}
11671	var ret = namelist.join("");
11672	ret = ret.replace(/\s+$/,"").replace(/\s*\-\s*/g, "-").replace(/\s+/g, " ");
11673	return ret;
11674};
11675CSL.Util.Names.getRawName = function (name) {
11676	var ret = [];
11677	if (name.given) {
11678		ret.push(name.given);
11679	}
11680	if (name.family) {
11681		ret.push(name.family);
11682	}
11683	return ret.join(" ");
11684};
11685CSL.Util.Dates = {};
11686CSL.Util.Dates.year = {};
11687CSL.Util.Dates.year["long"] = function (state, num) {
11688	if (!num) {
11689		if ("boolean" === typeof num) {
11690			num = "";
11691		} else {
11692			num = 0;
11693		}
11694	}
11695	return num.toString();
11696};
11697CSL.Util.Dates.year.imperial = function (state, num, end, makeShort) {
11698	if (!num) {
11699		if ("boolean" === typeof num) {
11700			num = "";
11701		} else {
11702			num = 0;
11703		}
11704	}
11705	end = end ? "_end" : "";
11706	var month = state.tmp.date_object["month" + end];
11707	month = month ? ""+month : "1";
11708	while (month.length < 2) {
11709		month = "0" + month;
11710	}
11711	var day = state.tmp.date_object["day" + end];
11712	day = day ? ""+day : "1";
11713	while (day.length < 2) {
11714		day = "0" + day;
11715	}
11716	var date = parseInt(num + month + day, 10);
11717	var label;
11718	var offset;
11719	if (date >= 18680908 && date < 19120730) {
11720		label = '\u660e\u6cbb';
11721		offset = 1867;
11722	} else if (date >= 19120730 && date < 19261225) {
11723		label = '\u5927\u6b63';
11724		offset = 1911;
11725	} else if (date >= 19261225 && date < 19890108) {
11726		label = '\u662d\u548c';
11727		offset = 1925;
11728	} else if (date >= 19890108) {
11729		label = '\u5e73\u6210';
11730		offset = 1988;
11731	}
11732	if (label && offset) {
11733		if (!state.transform.abbrevs['default']['number'][label]) {
11734			state.transform.loadAbbreviation('default', "number", label);
11735		}
11736		if (state.transform.abbrevs['default']['number'][label]) {
11737			label = state.transform.abbrevs['default']['number'][label];
11738		};
11739		year = label + (num - offset);
11740	}
11741	return year;
11742};
11743CSL.Util.Dates.year["short"] = function (state, num) {
11744	num = num.toString();
11745	if (num && num.length === 4) {
11746		return num.substr(2);
11747	}
11748};
11749CSL.Util.Dates.year.numeric = function (state, num) {
11750	var m, pre;
11751	num = "" + num;
11752	m = num.match(/([0-9]*)$/);
11753	if (m) {
11754		pre = num.slice(0, m[1].length * -1);
11755		num = m[1];
11756	} else {
11757		pre = num;
11758		num = "";
11759	}
11760	while (num.length < 4) {
11761		num = "0" + num;
11762	}
11763	return (pre + num);
11764};
11765CSL.Util.Dates.normalizeMonth = function (num, useSeason) {
11766	var ret;
11767	if (!num) {
11768		num = 0;
11769	}
11770	num = "" + num;
11771	if (!num.match(/^[0-9]+$/)) {
11772		num = 0;
11773	}
11774	num = parseInt(num, 10);
11775	if (useSeason) {
11776		var res = {stub: "month-", num: num};
11777		if (res.num < 1 || res.num > 20) {
11778			res.num = 0;
11779		} else if (res.num > 16) {
11780			res.stub = "season-";
11781			res.num = res.num - 16;
11782		} else if (res.num > 12) {
11783			res.stub = "season-";
11784			res.num = res.num - 12;
11785		}
11786		ret = res;
11787	} else {
11788		if (num < 1 || num > 12) {
11789			num = 0;
11790		}
11791		ret = num;
11792	}
11793	return ret;
11794}
11795CSL.Util.Dates.month = {};
11796CSL.Util.Dates.month.numeric = function (state, num) {
11797	var num = CSL.Util.Dates.normalizeMonth(num);
11798	if (!num) {
11799		num = "";
11800	}
11801	return num;
11802};
11803CSL.Util.Dates.month["numeric-leading-zeros"] = function (state, num) {
11804	var num = CSL.Util.Dates.normalizeMonth(num);
11805	if (!num) {
11806		num = "";
11807	} else {
11808		num = "" + num;
11809		while (num.length < 2) {
11810			num = "0" + num;
11811		}
11812	}
11813	return num;
11814};
11815CSL.Util.Dates.month["long"] = function (state, num, gender, forceDefaultLocale) {
11816	var res = CSL.Util.Dates.normalizeMonth(num, true);
11817	var num = res.num;
11818	if (!num) {
11819		num = "";
11820	} else {
11821		num = "" + num;
11822		while (num.length < 2) {
11823			num = "0" + num;
11824		}
11825		num = state.getTerm(res.stub + num, "long", 0, 0, false, forceDefaultLocale);
11826	}
11827	return num;
11828};
11829CSL.Util.Dates.month["short"] = function (state, num, gender, forceDefaultLocale) {
11830	var res = CSL.Util.Dates.normalizeMonth(num, true);
11831	var num = res.num;
11832	if (!num) {
11833		num = "";
11834	} else {
11835		num = "" + num;
11836		while (num.length < 2) {
11837			num = "0" + num;
11838		}
11839		num = state.getTerm(res.stub + num, "short", 0, 0, false, forceDefaultLocale);
11840	}
11841	return num;
11842};
11843CSL.Util.Dates.day = {};
11844CSL.Util.Dates.day.numeric = function (state, num) {
11845	return num.toString();
11846};
11847CSL.Util.Dates.day["long"] = CSL.Util.Dates.day.numeric;
11848CSL.Util.Dates.day["numeric-leading-zeros"] = function (state, num) {
11849	if (!num) {
11850		num = 0;
11851	}
11852	num = num.toString();
11853	while (num.length < 2) {
11854		num = "0" + num;
11855	}
11856	return num.toString();
11857};
11858CSL.Util.Dates.day.ordinal = function (state, num, gender) {
11859	return state.fun.ordinalizer.format(num, gender);
11860};
11861CSL.Util.Sort = {};
11862CSL.Util.Sort.strip_prepositions = function (str) {
11863	var m;
11864	if ("string" === typeof str) {
11865		m = str.toLocaleLowerCase();
11866		m = str.match(/^((a|an|the)\s+)/);
11867	}
11868	if (m) {
11869		str = str.substr(m[1].length);
11870	}
11871	return str;
11872};
11873CSL.Util.substituteStart = function (state, target) {
11874	var element_trace, display, bib_first, func, choose_start, if_start, nodetypes;
11875	func = function (state, Item) {
11876		for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) {
11877			if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) {
11878				state.tmp.strip_periods += 1;
11879				break;
11880			}
11881		}
11882	};
11883	this.execs.push(func);
11884	if (this.decorations && (state.opt.development_extensions.csl_reverse_lookup_support || state.sys.csl_reverse_lookup_support)) {
11885		this.decorations.reverse();
11886		this.decorations.push(["@showid","true", this.cslid]);
11887		this.decorations.reverse();
11888	}
11889	nodetypes = ["number", "date", "names"];
11890	if (("text" === this.name && !this.postponed_macro) || nodetypes.indexOf(this.name) > -1) {
11891		element_trace = function (state, Item, item) {
11892			if (state.tmp.element_trace.value() === "author" || "names" === this.name) {
11893				if (item && item["author-only"]) {
11894					state.tmp.element_trace.push("do-not-suppress-me");
11895				} else if (item && item["suppress-author"]) {
11896				}
11897			} else {
11898				if (item && item["author-only"]) {
11899					state.tmp.element_trace.push("suppress-me");
11900				} else if (item && item["suppress-author"]) {
11901					state.tmp.element_trace.push("do-not-suppress-me");
11902				}
11903			}
11904		};
11905		this.execs.push(element_trace);
11906	}
11907	display = this.strings.cls;
11908	this.strings.cls = false;
11909	if (state.build.render_nesting_level === 0) {
11910		if (state.build.area === "bibliography" && state.bibliography.opt["second-field-align"]) {
11911			bib_first = new CSL.Token("group", CSL.START);
11912			bib_first.decorations = [["@display", "left-margin"]];
11913			func = function (state, Item) {
11914				if (!state.tmp.render_seen) {
11915					bib_first.strings.first_blob = Item.id;
11916					state.output.startTag("bib_first", bib_first);
11917				}
11918			};
11919			bib_first.execs.push(func);
11920			target.push(bib_first);
11921		} else if (CSL.DISPLAY_CLASSES.indexOf(display) > -1) {
11922			bib_first = new CSL.Token("group", CSL.START);
11923			bib_first.decorations = [["@display", display]];
11924			func = function (state, Item) {
11925				bib_first.strings.first_blob = Item.id;
11926				state.output.startTag("bib_first", bib_first);
11927			};
11928			bib_first.execs.push(func);
11929			target.push(bib_first);
11930		}
11931		state.build.cls = display;
11932	}
11933	state.build.render_nesting_level += 1;
11934	if (state.build.substitute_level.value() === 1) {
11935		choose_start = new CSL.Token("choose", CSL.START);
11936		CSL.Node.choose.build.call(choose_start, state, target);
11937		if_start = new CSL.Token("if", CSL.START);
11938		func = function (Item,item) {
11939			if (state.tmp.can_substitute.value()) {
11940				return true;
11941			}
11942			return false;
11943		};
11944		if_start.tests.push(func);
11945		if_start.test = state.fun.match.any(this, state, if_start.tests);
11946		target.push(if_start);
11947	}
11948	if (state.sys.variableWrapper
11949		&& this.variables_real
11950		&& this.variables_real.length) {
11951		func = function (state, Item, item) {
11952			if (!state.tmp.just_looking && !state.tmp.suppress_decorations) {
11953				variable_entry = new CSL.Token("text", CSL.START);
11954				variable_entry.decorations = [["@showid", "true"]];
11955				state.output.startTag("variable_entry", variable_entry);
11956				var position = null;
11957				if (item) {
11958					position = item.position;
11959				}
11960				if (!position) position = 0;
11961				var positionMap = [
11962					"first",
11963					"subsequent",
11964					"ibid",
11965					"ibid-with-locator"
11966				]
11967				var noteNumber = 0;
11968				if (item && item.noteIndex) {
11969					noteNumber = item.noteIndex;
11970				}
11971				var firstReferenceNoteNumber = 0;
11972				if (item && item['first-reference-note-number']) {
11973					firstReferenceNoteNumber = item['first-reference-note-number'];
11974				}
11975				var citationNumber = 0;
11976				if (item && item['citation-number']) {
11977					citationNumber = item['citation-number'];
11978				}
11979				var index = 0;
11980				if (item && item.index) {
11981					index = item.index;
11982				}
11983				var params = {
11984					itemData: Item,
11985					variableNames: this.variables,
11986					context: state.tmp.area,
11987					xclass: state.opt.xclass,
11988					position: positionMap[position],
11989					"note-number": noteNumber,
11990					"first-reference-note-number": firstReferenceNoteNumber,
11991					"citation-number": citationNumber,
11992					"index": index,
11993					"mode": state.opt.mode
11994				};
11995				state.output.current.value().params = params;
11996			}
11997		}
11998		this.execs.push(func);
11999	}
12000};
12001CSL.Util.substituteEnd = function (state, target) {
12002	var func, bib_first_end, bib_other, if_end, choose_end, toplevel, hasval, author_substitute, str;
12003	if (state.sys.variableWrapper
12004		&& (this.hasVariable || (this.variables_real && this.variables_real.length))) {
12005		func = function (state,Item) {
12006			if (!state.tmp.just_looking && !state.tmp.suppress_decorations) {
12007				state.output.endTag("variable_entry");
12008			}
12009		}
12010		this.execs.push(func);
12011	}
12012	func = function (state, Item) {
12013		for (var i = 0, ilen = this.decorations.length; i < ilen; i += 1) {
12014			if ("@strip-periods" === this.decorations[i][0] && "true" === this.decorations[i][1]) {
12015				state.tmp.strip_periods += -1;
12016				break;
12017			}
12018		}
12019	};
12020	this.execs.push(func);
12021	state.build.render_nesting_level += -1;
12022	if (state.build.render_nesting_level === 0) {
12023		if (state.build.cls) {
12024			func = function (state, Item) {
12025				state.output.endTag("bib_first");
12026			};
12027			this.execs.push(func);
12028			state.build.cls = false;
12029		} else if (state.build.area === "bibliography" && state.bibliography.opt["second-field-align"]) {
12030			bib_first_end = new CSL.Token("group", CSL.END);
12031			func = function (state, Item) {
12032				if (!state.tmp.render_seen) {
12033					state.output.endTag(); // closes bib_first
12034				}
12035			};
12036			bib_first_end.execs.push(func);
12037			target.push(bib_first_end);
12038			bib_other = new CSL.Token("group", CSL.START);
12039			bib_other.decorations = [["@display", "right-inline"]];
12040			func = function (state, Item) {
12041				if (!state.tmp.render_seen) {
12042					state.tmp.render_seen = true;
12043					state.output.startTag("bib_other", bib_other);
12044				}
12045			};
12046			bib_other.execs.push(func);
12047			target.push(bib_other);
12048		}
12049	}
12050	if (state.build.substitute_level.value() === 1) {
12051		if_end = new CSL.Token("if", CSL.END);
12052		target.push(if_end);
12053		choose_end = new CSL.Token("choose", CSL.END);
12054		CSL.Node.choose.build.call(choose_end, state, target);
12055	}
12056	toplevel = "names" === this.name && state.build.substitute_level.value() === 0;
12057	hasval = "string" === typeof state[state.build.area].opt["subsequent-author-substitute"];
12058	var subrule = state[state.build.area].opt["subsequent-author-substitute-rule"];
12059	if (toplevel && hasval) {
12060		author_substitute = new CSL.Token("text", CSL.SINGLETON);
12061		func = function (state, Item) {
12062			var i, ilen;
12063			var printing = !state.tmp.suppress_decorations;
12064			if (printing && state.tmp.area === "bibliography" && state.tmp.subsequent_author_substitute_ok) {
12065				if (state.tmp.rendered_name) {
12066					if ("partial-each" === subrule || "partial-first" === subrule) {
12067						var dosub = true;
12068						var rendered_name = [];
12069						for (i = 0, ilen = state.tmp.name_node.children.length; i < ilen; i += 1) {
12070							var name = state.tmp.rendered_name[i];
12071							if (dosub
12072								&& state.tmp.last_rendered_name && state.tmp.last_rendered_name.length > (i - 1)
12073								&& name && !name.localeCompare(state.tmp.last_rendered_name[i])) {
12074								str = new CSL.Blob(state[state.tmp.area].opt["subsequent-author-substitute"]);
12075								state.tmp.name_node.children[i].blobs = [str];
12076								if ("partial-first" === subrule) {
12077									dosub = false;
vendor: 5,845 bytes, lines 12078-12263
12078								}
12079							} else {
12080								dosub = false;
12081							}
12082							rendered_name.push(name);
12083						}
12084						state.tmp.last_rendered_name = rendered_name;
12085					} else if ("complete-each" === subrule) {
12086						var rendered_name = state.tmp.rendered_name.join(",");
12087						if (rendered_name) {
12088							if (!rendered_name.localeCompare(state.tmp.last_rendered_name)) {
12089								for (i = 0, ilen = state.tmp.name_node.children.length; i < ilen; i += 1) {
12090									str = new CSL.Blob(state[state.tmp.area].opt["subsequent-author-substitute"]);
12091									state.tmp.name_node.children[i].blobs = [str];
12092								}
12093							}
12094							state.tmp.last_rendered_name = rendered_name;
12095						}
12096					} else {
12097						var rendered_name = state.tmp.rendered_name.join(",");
12098						if (rendered_name) {
12099							if (!rendered_name.localeCompare(state.tmp.last_rendered_name)) {
12100								str = new CSL.Blob(state[state.tmp.area].opt["subsequent-author-substitute"]);
12101								if (state.tmp.label_blob) {
12102									state.tmp.name_node.top.blobs = [str,state.tmp.label_blob];
12103								} else {
12104									state.tmp.name_node.top.blobs = [str];
12105								}
12106							}
12107							state.tmp.last_rendered_name = rendered_name;
12108						}
12109					}
12110				}
12111			}
12112		};
12113		author_substitute.execs.push(func);
12114		target.push(author_substitute);
12115	}
12116	if (("text" === this.name && !this.postponed_macro) || ["number", "date", "names"].indexOf(this.name) > -1) {
12117		func = function (state, Item) {
12118			state.tmp.element_trace.pop();
12119		};
12120		this.execs.push(func);
12121	}
12122};
12123CSL.Util.padding = function (num) {
12124	var m = num.match(/\s*(-{0,1}[0-9]+)/);
12125	if (m) {
12126		num = parseInt(m[1], 10);
12127		if (num < 0) {
12128			num = 99999999999999999999 + num;
12129		}
12130		num = "" + num;
12131		while (num.length < 20) {
12132			num = "0" + num;
12133		}
12134	}
12135	return num;
12136};
12137CSL.Util.LongOrdinalizer = function () {};
12138CSL.Util.LongOrdinalizer.prototype.init = function (state) {
12139	this.state = state;
12140};
12141CSL.Util.LongOrdinalizer.prototype.format = function (num, gender) {
12142	if (num < 10) {
12143		num = "0" + num;
12144	}
12145	var ret = CSL.Engine.getField(
12146		CSL.LOOSE,
12147		this.state.locale[this.state.opt.lang].terms,
12148		"long-ordinal-" + num,
12149		"long",
12150		0,
12151		gender
12152	);
12153	if (!ret) {
12154		ret = this.state.fun.ordinalizer.format(num, gender);
12155	}
12156	this.state.tmp.cite_renders_content = true;
12157	return ret;
12158};
12159CSL.Util.Ordinalizer = function (state) {
12160	this.state = state;
12161	this.suffixes = {};
12162};
12163CSL.Util.Ordinalizer.prototype.init = function () {
12164	if (!this.suffixes[this.state.opt.lang]) {
12165		this.suffixes[this.state.opt.lang] = {};
12166		for (var i = 0, ilen = 3; i < ilen; i += 1) {
12167			var gender = [undefined, "masculine", "feminine"][i];
12168			this.suffixes[this.state.opt.lang][gender] = [];
12169			for (var j = 1; j < 5; j += 1) {
12170				var ordinal = this.state.getTerm("ordinal-0" + j, "long", false, gender);
12171				if ("undefined" === typeof ordinal) {
12172					delete this.suffixes[this.state.opt.lang][gender];
12173					break;
12174				}
12175				this.suffixes[this.state.opt.lang][gender].push(ordinal);
12176			}
12177		}
12178	}
12179};
12180CSL.Util.Ordinalizer.prototype.format = function (num, gender) {
12181	var str;
12182	num = parseInt(num, 10);
12183	str = "" + num;
12184	var suffix = "";
12185	var trygenders = [];
12186	if (gender) {
12187		trygenders.push(gender);
12188	}
12189	trygenders.push("neuter");
12190	if (this.state.locale[this.state.opt.lang].ord["1.0.1"]) {
12191		suffix = this.state.getTerm("ordinal",false,0,gender);
12192		var trygender;
12193		for (var i = 0, ilen = trygenders.length; i < ilen; i += 1) {
12194			trygender = trygenders[i];
12195			var ordinfo = this.state.locale[this.state.opt.lang].ord["1.0.1"];
12196			if (ordinfo["whole-number"][str] && ordinfo["whole-number"][str][trygender]) {
12197				suffix = this.state.getTerm(this.state.locale[this.state.opt.lang].ord["1.0.1"]["whole-number"][str][trygender],false,0,gender);
12198			} else if (ordinfo["last-two-digits"][str.slice(str.length - 2)] && ordinfo["last-two-digits"][str.slice(str.length - 2)][trygender]) {
12199				suffix = this.state.getTerm(this.state.locale[this.state.opt.lang].ord["1.0.1"]["last-two-digits"][str.slice(str.length - 2)][trygender],false,0,gender);
12200			} else if (ordinfo["last-digit"][str.slice(str.length - 1)] && ordinfo["last-digit"][str.slice(str.length - 1)][trygender]) {
12201				suffix = this.state.getTerm(this.state.locale[this.state.opt.lang].ord["1.0.1"]["last-digit"][str.slice(str.length - 1)][trygender],false,0,gender);
12202			}
12203			if (suffix) {
12204				break;
12205			}
12206		}
12207	} else {
12208		if (!gender) {
12209			gender = undefined;
12210		}
12211		this.state.fun.ordinalizer.init();
12212		if ((num / 10) % 10 === 1 || (num > 10 && num < 20)) {
12213			suffix = this.suffixes[this.state.opt.lang][gender][3];
12214		} else if (num % 10 === 1 && num % 100 !== 11) {
12215			suffix = this.suffixes[this.state.opt.lang][gender][0];
12216		} else if (num % 10 === 2 && num % 100 !== 12) {
12217			suffix = this.suffixes[this.state.opt.lang][gender][1];
12218		} else if (num % 10 === 3 && num % 100 !== 13) {
12219			suffix = this.suffixes[this.state.opt.lang][gender][2];
12220		} else {
12221			suffix = this.suffixes[this.state.opt.lang][gender][3];
12222		}
12223	}
12224	str = str += suffix;
12225	return str;
12226};
12227CSL.Util.Romanizer = function () {};
12228CSL.Util.Romanizer.prototype.format = function (num) {
12229	var ret, pos, n, numstr, len;
12230	ret = "";
12231	if (num < 6000) {
12232		numstr = num.toString().split("");
12233		numstr.reverse();
12234		pos = 0;
12235		n = 0;
12236		len = numstr.length;
12237		for (pos = 0; pos < len; pos += 1) {
12238			n = parseInt(numstr[pos], 10);
12239			ret = CSL.ROMAN_NUMERALS[pos][n] + ret;
12240		}
12241	}
12242	return ret;
12243};
12244CSL.Util.Suffixator = function (slist) {
12245	if (!slist) {
12246		slist = CSL.SUFFIX_CHARS;
12247	}
12248	this.slist = slist.split(",");
12249};
12250CSL.Util.Suffixator.prototype.format = function (N) {
12251	var X;
12252	N += 1;
12253	var key = "";
12254	do {
12255		X = ((N % 26) === 0) ? 26 : (N % 26);
12256		key = this.slist[X-1] + key;
12257		N = (N - X) / 26;
12258	} while ( N !== 0 );
12259	return key;
12260};
12261CSL.Engine.prototype.processNumber = function (node, ItemObject, variable, type) {
12262	var num, m, i, ilen, j, jlen;
12263	var debug = false;
12264	if (this.tmp.shadow_numbers[variable]) {
12265		if (this.tmp.shadow_numbers[variable].numeric) {
12266			for (var i = 0, ilen = this.tmp.shadow_numbers[variable].values.length; i < ilen; i += 2) {
12267				this.tmp.shadow_numbers[variable].values[i][2] = node;
12268			}
12269		}
12270		return;
12271	}
12272	this.tmp.shadow_numbers[variable] = {};
12273	this.tmp.shadow_numbers[variable].values = [];
12274	this.tmp.shadow_numbers[variable].plural = 0;
12275	this.tmp.shadow_numbers[variable].numeric = false;
12276	this.tmp.shadow_numbers[variable].label = false;
12277	if (!ItemObject) {
12278		return;
12279	}
12280	var languageRole = CSL.LangPrefsMap[variable];
12281	if (languageRole) {
12282		var localeType = this.opt["cite-lang-prefs"][languageRole][0];
12283		num = this.transform.getTextSubField(ItemObject, variable, "locale-"+localeType, true);
12284		num = num.name;
12285	} else {
12286		num = ItemObject[variable];
12287	}
12288	if (num && this.sys.getAbbreviation) {
12289		num = ("" + num).replace(/^\"/, "").replace(/\"$/, "");
12290		var jurisdiction = this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", num);
12291		if (this.transform.abbrevs[jurisdiction].number[num]) {
12292			num = this.transform.abbrevs[jurisdiction].number[num];
12293		} else {
12294			if ("undefined" !== typeof this.transform.abbrevs[jurisdiction].number[num]) {
12295				delete this.transform.abbrevs[jurisdiction].number[num];
12296			}
12297		}
12298	}
12299	if ("undefined" !== typeof num) {
12300		if ("number" === typeof num) {
12301			num = "" + num;
12302		}
12303		this.tmp.shadow_numbers[variable].label = variable;
12304		if (num.slice(0, 1) === '"' && num.slice(-1) === '"') {
12305			num = num.slice(1, -1);
12306		}
12307		if (num && ["number-of-volumes","number-of-pages"].indexOf(variable) > -1) {
12308			var m = num.match(/[^0-9]*([0-9]+).*/);
12309			if (m) {
12310				this.tmp.shadow_numbers[variable].numeric = true;
12311				if (m[1] !== "1") {
12312					this.tmp.shadow_numbers[variable].plural = 1;
12313				}
12314			}
12315		}
12316		if ("locator" === variable
12317			&& ["bill","gazette","legislation","treaty"].indexOf(type) > -1) {
12318			num = num.split(CSL.STATUTE_SUBDIV_PLAIN_REGEX)[0];
12319		}
12320		var rangeType = "page";
12321		if (["bill","gazette","legislation","legal_case","treaty"].indexOf(type) > -1
12322			&& variable === "collection-number") {
12323			rangeType = "year";
12324		}
12325		if (["page", "page-first"].indexOf(variable) > -1) {
12326			var m = num.split(" ")[0].match(CSL.STATUTE_SUBDIV_GROUPED_REGEX);
12327			if (m){
12328				if (this.opt.development_extensions.static_statute_locator) {
12329					this.tmp.shadow_numbers[variable].label = CSL.STATUTE_SUBDIV_STRINGS[m[0]];
12330				}
12331				var mm = num.match(/[^ ]+\s+(.*)/);
12332				if (mm) {
12333					num = mm[1];
12334				}
12335			}
12336		}
12337		var lst = num.split(/(?:,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/);
12338		var m = num.match(/(,\s+|\s*\\*[\-\u2013]+\s*|\s*&\s*)/g);
12339		var elements = [];
12340		for (var i = 0, ilen = lst.length - 1; i < ilen; i += 1) {
12341			elements.push(lst[i]);
12342			elements.push(m[i]);
12343		}
12344		elements.push(lst[lst.length - 1]);
12345		var count = 0;
12346		var numeric = true;
12347		for (var i = 0, ilen = elements.length; i < ilen; i += 1) {
12348			var odd = ((i%2) === 0);
12349			if (odd) {
12350				if (elements[i]) {
12351					if (elements[i].match(/(?:[0-9]|[xivcmlXIVCML])/)) {
12352						if (elements[i - 1] && elements[i - 1].match(/^\s*\\*[\-\u2013]+\s*$/)) {
12353							var middle = this.tmp.shadow_numbers[variable].values.slice(-1);
12354							if (middle[0][1].indexOf("\\") == -1) {
12355								if (elements[i - 2] && ("" + elements[i - 2]).match(/(:?[a-zA-Z]*[0-9]+$|^[ivxlcmIVXLCM]+$)/)
12356									&& elements[i].match(/(?:^[a-zA-Z]*[0-9]+|^[ivxlcmIVXLCM]+$)/)) {
12357									var start = this.tmp.shadow_numbers[variable].values.slice(-2);
12358									middle[0][1] = this.getTerm(rangeType + "-range-delimiter");
12359									if (this.opt[rangeType + "-range-format"] ) {
12360										var newstr = this.fun[rangeType + "_mangler"](start[0][1] +"-"+elements[i]);
12361										newstr = newstr.split(this.getTerm(rangeType + "-range-delimiter"));
12362										elements[i] = newstr[1];
12363									}
12364									count = count + 1;
12365								}
12366								if (middle[0][1].indexOf("--") > -1) {
12367									middle[0][1] = middle[0][1].replace(/--*/, "\u2013");
12368								}
12369							} else {
12370								middle[0][1] = middle[0][1].replace(/\\/, "", "g");
12371							}
12372						} else if (elements[i].indexOf(" ") === -1) {
12373							count = count + 1;
12374						}
12375					}
12376					var subelements = elements[i].split(/\s+/);
12377					for (var j = 0, jlen = subelements.length; j < jlen; j += 1) {
12378						if (this.opt.development_extensions.strict_page_numbers
12379							&& variable === "page"
12380							&& !subelements[j].match(/^-*[0-9]/)) {
12381							numeric = false;
12382						} else if (!subelements[j].match(/[-0-9]/)) {
12383							numeric = false;
12384						}
12385					}
12386					if (elements[i].match(/^[1-9][0-9]*$/)) {
12387						elements[i] = parseInt(elements[i], 10);
12388						if (node && "undefined" === typeof node.gender) {
12389							node.gender = this.locale[this.opt.lang]["noun-genders"][variable];
12390							if (!node.gender) {
12391								node.gender = "";
12392							}
12393						}
12394						this.tmp.shadow_numbers[variable].values.push(["NumericBlob", elements[i], node]);
12395					} else {
12396						var str = elements[i];
12397						this.tmp.shadow_numbers[variable].values.push(["Blob", str, node]);
12398					}
12399				}
12400			} else {
12401				if (elements[i]) {
12402					this.tmp.shadow_numbers[variable].values.push(["Blob", elements[i], undefined]);
12403				}
12404			}
12405		};
12406		if (this.opt.development_extensions.strict_page_numbers && variable === "page") {
12407			if (num.indexOf(" ") === -1 && num.match(/^-*[0-9]/)) {
12408				this.tmp.shadow_numbers[variable].numeric = true;
12409			} else {
12410				this.tmp.shadow_numbers[variable].numeric = numeric;
12411			}
12412		} else {
12413			if (num.indexOf(" ") === -1 && num.match(/[0-9]/)) {
12414				this.tmp.shadow_numbers[variable].numeric = true;
12415			} else {
12416				this.tmp.shadow_numbers[variable].numeric = numeric;
12417			}
12418		}
12419		if (!this.tmp.shadow_numbers[variable].numeric) {
12420			this.transform.loadAbbreviation(ItemObject.jurisdiction, "number", num);
12421		}
12422		if (count > 1) {
12423			this.tmp.shadow_numbers[variable].plural = 1;
12424		}
12425		if (ItemObject.force_pluralism === 1) {
12426			this.tmp.shadow_numbers[variable].plural = 1;
12427		} else if (ItemObject.force_pluralism === 0) {
12428			this.tmp.shadow_numbers[variable].plural = 0;
12429		}
12430	}
12431};
12432CSL.Util.PageRangeMangler = {};
12433CSL.Util.PageRangeMangler.getFunction = function (state, rangeType) {
12434	var rangerex, pos, len, stringify, listify, expand, minimize, minimize_internal, chicago, lst, m, b, e, ret, begin, end, ret_func, ppos, llen;
12435	var range_delimiter = state.getTerm(rangeType + "-range-delimiter");
12436	rangerex = /([a-zA-Z]*)([0-9]+)\s*(?:\u2013|-)\s*([a-zA-Z]*)([0-9]+)/;
12437	stringify = function (lst) {
12438		len = lst.length;
12439		for (pos = 1; pos < len; pos += 2) {
12440			if ("object" === typeof lst[pos]) {
12441				lst[pos] = lst[pos].join("");
12442			}
12443		}
12444		var ret = lst.join("");
12445		ret = ret.replace(/([^\\])\-/g, "$1"+state.getTerm(rangeType + "-range-delimiter"));
12446		return ret;
12447	};
12448	listify = function (str) {
12449		var m, lst, ret;
12450		var hyphens = "\\s+\\-\\s+";
12451		var this_range_delimiter = range_delimiter === "-" ? "" : range_delimiter;
12452		var delimRex = new RegExp("([^\\\\])[-" + this_range_delimiter + "\\u2013]", "g");
12453		str = str.replace(delimRex, "$1 - ").replace(/\s+-\s+/g, " - ");
12454		var rexm = new RegExp("([a-zA-Z]*[0-9]+" + hyphens + "[a-zA-Z]*[0-9]+)", "g");
12455		var rexlst = new RegExp("[a-zA-Z]*[0-9]+" + hyphens + "[a-zA-Z]*[0-9]+");
12456		m = str.match(rexm);
12457		lst = str.split(rexlst);
12458		if (lst.length === 0) {
12459			ret = m;
12460		} else {
12461			ret = [lst[0]];
12462			for (pos = 1, len = lst.length; pos < len; pos += 1) {
12463				ret.push(m[pos - 1].replace(/\s*\-\s*/, "-", "g"));
12464				ret.push(lst[pos]);
12465			}
12466		}
12467		return ret;
12468	};
12469	expand = function (str) {
12470		str = "" + str;
12471		lst = listify(str);
12472		len = lst.length;
12473		for (pos = 1; pos < len; pos += 2) {
12474			m = lst[pos].match(rangerex);
12475			if (m) {
12476				if (!m[3] || m[1] === m[3]) {
12477					if (m[4].length < m[2].length) {
12478						m[4] = m[2].slice(0, (m[2].length - m[4].length)) + m[4];
12479					}
12480					if (parseInt(m[2], 10) < parseInt(m[4], 10)) {
12481						m[3] = range_delimiter + m[1];
12482						lst[pos] = m.slice(1);
12483					}
12484				}
12485			}
12486			if ("string" === typeof lst[pos]) {
12487				lst[pos] = lst[pos].replace("-", range_delimiter, "g");
12488			}
12489		}
12490		return lst;
12491	};
12492	minimize = function (lst, minchars, isyear) {
12493		len = lst.length;
12494		for (var i = 1, ilen = lst.length; i < ilen; i += 2) {
12495			lst[i][3] = minimize_internal(lst[i][1], lst[i][3], minchars, isyear);
12496			if (lst[i][2].slice(1) === lst[i][0]) {
12497				lst[i][2] = range_delimiter;
12498			}
12499		}
12500		return stringify(lst);
12501	};
12502	minimize_internal = function (begin, end, minchars, isyear) {
12503		if (!minchars) {
12504			minchars = 0;
12505		}
12506		b = ("" + begin).split("");
12507		e = ("" + end).split("");
12508		ret = e.slice();
12509		ret.reverse();
12510		if (b.length === e.length) {
12511			for (var i = 0, ilen = b.length; i < ilen; i += 1) {
12512				if (b[i] === e[i] && ret.length > minchars) {
12513					ret.pop();
12514				} else {
12515					if (minchars && isyear && ret.length === 3) {
12516						var front = b.slice(0, i);
12517						front.reverse();
12518						ret = ret.concat(front);
12519					}
12520					break;
12521				}
12522			}
12523		}
12524		ret.reverse();
12525		return ret.join("");
12526	};
12527	chicago = function (lst) {
12528		len = lst.length;
12529		for (pos = 1; pos < len; pos += 2) {
12530			if ("object" === typeof lst[pos]) {
12531				m = lst[pos];
12532				begin = parseInt(m[1], 10);
12533				end = parseInt(m[3], 10);
12534				if (begin > 100 && begin % 100 && parseInt((begin / 100), 10) === parseInt((end / 100), 10)) {
12535					m[3] = "" + (end % 100);
12536				} else if (begin >= 10000) {
12537					m[3] = "" + (end % 1000);
12538				}
12539			}
12540			if (m[2].slice(1) === m[0]) {
12541				m[2] = range_delimiter;
12542			}
12543		}
12544		return stringify(lst);
12545	};
12546	var sniff = function (str, func, minchars, isyear) {
12547		var ret;
12548		str = "" + str;
12549		var lst = expand(str);
12550		var ret = func(lst, minchars, isyear);
12551		return ret;
12552	}
12553	if (!state.opt[rangeType + "-range-format"]) {
12554		ret_func = function (str) {
12555			return str;
12556		};
12557	} else if (state.opt[rangeType + "-range-format"] === "expanded") {
12558		ret_func = function (str) {
12559			return sniff(str, stringify);
12560		};
12561	} else if (state.opt[rangeType + "-range-format"] === "minimal") {
12562		ret_func = function (str) {
12563			return sniff(str, minimize);
12564		};
12565	} else if (state.opt[rangeType + "-range-format"] === "minimal-two") {
12566		ret_func = function (str, isyear) {
12567			return sniff(str, minimize, 2, isyear);
12568		};
12569	} else if (state.opt[rangeType + "-range-format"] === "chicago") {
12570		ret_func = function (str) {
12571			return sniff(str, chicago);
12572		};
12573	}
12574	return ret_func;
12575};
12576CSL.Util.FlipFlopper = function (state) {
12577	var tagdefs, pos, len, p, entry, allTags, ret, def, esc, makeHashes, closeTags, flipTags, openToClose, openToDecorations, okReverse, hashes, allTagsLst, lst;
12578	this.state = state;
12579	this.blob = false;
12580	this.quotechars = ['"', "'"];
12581	tagdefs = [
12582		["<i>", "</i>", "italics", "@font-style", ["italic", "normal","normal"], true],
12583		["<b>", "</b>", "bold", "@font-weight", ["bold", "normal","normal"], true],
12584		["<sup>", "</sup>", "superscript", "@vertical-align", ["sup", "sup","baseline"], true],
12585		["<sub>", "</sub>", "subscript", "@vertical-align", ["sub", "sub","baseline"], true],
12586		["<sc>", "</sc>", "smallcaps", "@font-variant", ["small-caps", "small-caps","normal"], true],
12587		["<span style=\"font-variant:small-caps;\">", "</span>", "smallcaps", "@font-variant", ["small-caps", "normal","normal"], true],
12588		["<span class=\"nocase\">", "</span>", "passthrough", "@passthrough", ["true", "true","true"], true],
12589		["<span class=\"nodecor\">", "</span>", "passthrough", "@passthrough", ["true", "true","true"], true],
12590		['"',  '"',  "quotes",  "@quotes",  ["true",  "inner","true"],  "'"],
12591		[" '",  "'",  "quotes",  "@quotes",  ["inner",  "true","true"],  '"']
12592	];
12593	for (pos = 0; pos < 2; pos += 1) {
12594		p = ["-", "-inner-"][pos];
12595		entry = [];
12596		var openq = state.getTerm(("open" + p + "quote"));
12597		entry.push(openq);
12598		this.quotechars.push(openq);
12599		var closeq = state.getTerm(("close" + p + "quote"));
12600		entry.push(closeq);
12601		this.quotechars.push(closeq);
12602		entry.push(("quote" + "s"));
12603		entry.push(("@" + "quote" + "s"));
12604		if ("-" === p) {
12605			entry.push(["true", "inner"]);
12606		} else {
12607			entry.push(["inner", "true"]);
12608		}
12609		entry.push(true);
12610		if ("-" === p) {
12611			entry.push(state.getTerm(("close-inner-quote")));
12612		} else {
12613			entry.push(state.getTerm(("close-quote")));
12614		}
12615		tagdefs.push(entry);
12616	}
12617	allTags = function (tagdefs) {
12618		ret = [];
12619		len = tagdefs.length;
12620		for (pos = 0; pos < len; pos += 1) {
12621			def = tagdefs[pos];
12622			if (ret.indexOf(def[0]) === -1) {
12623				esc = "";
12624				if (["(", ")", "[", "]"].indexOf(def[0]) > -1) {
12625					esc = "\\";
12626				}
12627				ret.push(esc + def[0]);
12628			}
12629			if (ret.indexOf(def[1]) === -1) {
12630				esc = "";
12631				if (["(", ")", "[", "]"].indexOf(def[1]) > -1) {
12632					esc = "\\";
12633				}
12634				ret.push(esc + def[1]);
12635			}
12636		}
12637		return ret;
12638	};
12639	allTagsLst = allTags(tagdefs);
12640	lst = [];
12641	for (pos = 0, len = allTagsLst.length; pos < len; pos += 1) {
12642		if (allTagsLst[pos]) {
12643			lst.push(allTagsLst[pos]);
12644		}
12645	}
12646	allTagsLst = lst.slice();
12647	this.allTagsRexMatch = new RegExp("(" + allTagsLst.join("|") + ")", "g");
12648	this.allTagsRexSplit = new RegExp("(?:" + allTagsLst.join("|") + ")");
12649	makeHashes = function (tagdefs) {
12650		closeTags = {};
12651		flipTags = {};
12652		openToClose = {};
12653		openToDecorations = {};
12654		okReverse = {};
12655		len = tagdefs.length;
12656		for (pos = 0; pos < len; pos += 1) {
12657			closeTags[tagdefs[pos][1]] = true;
12658			flipTags[tagdefs[pos][1]] = tagdefs[pos][5];
12659			openToClose[tagdefs[pos][0]] = tagdefs[pos][1];
12660			openToDecorations[tagdefs[pos][0]] = [tagdefs[pos][3], tagdefs[pos][4]];
12661			okReverse[tagdefs[pos][3]] = [tagdefs[pos][3], [tagdefs[pos][4][2], tagdefs[pos][1]]];
12662		}
12663		return [closeTags, flipTags, openToClose, openToDecorations, okReverse];
12664	};
12665	hashes = makeHashes(tagdefs);
12666	this.closeTagsHash = hashes[0];
12667	this.flipTagsHash = hashes[1];
12668	this.openToCloseHash = hashes[2];
12669	this.openToDecorations = hashes[3];
12670	this.okReverseHash = hashes[4];
12671};
12672CSL.Util.FlipFlopper.prototype.init = function (str, blob) {
12673	this.txt_esc = CSL.getSafeEscape(this.state);
12674	if (!blob) {
12675		this.strs = this.getSplitStrings(str);
12676		this.blob = new CSL.Blob();
12677	} else {
12678		this.blob = blob;
12679		this.strs = this.getSplitStrings(this.blob.blobs);
12680		this.blob.blobs = [];
12681	}
12682	this.blobstack = new CSL.Stack(this.blob);
12683};
12684CSL.Util.FlipFlopper.prototype._normalizeString = function (str) {
12685	var i, ilen;
12686	str = str.replace(/\s+'\s+/g," ’ ");
12687	if (str.indexOf(this.quotechars[0]) > -1) {
12688		for (i = 0, ilen = 2; i < ilen; i += 1) {
12689			if (this.quotechars[i + 2]) {
12690				str = str.replace(this.quotechars[i + 2], this.quotechars[0]);
12691			}
12692		}
12693	}
12694	if (str.indexOf(this.quotechars[1]) > -1) {
12695		for (i = 0, ilen = 2; i < ilen; i += 1) {
12696			if (this.quotechars[i + 4]) {
12697				if (i === 0) {
12698					str = str.replace(this.quotechars[i + 4], " " + this.quotechars[1]);
12699				} else {
12700					str = str.replace(this.quotechars[i + 4], this.quotechars[1]);
12701				}
12702			}
12703		}
12704	}
12705	return str;
12706};
12707CSL.Util.FlipFlopper.prototype.getSplitStrings = function (str) {
12708	var strs, pos, len, newstr, head, tail, expected_closers, expected_openers, expected_flips, tagstack, badTagStack, posA, sameAsOpen, openRev, flipRev, tag, ibeenrunned, posB, wanted_closer, posC, sep, resplice, params, lenA, lenB, lenC, badTagPos, mx, myret;
12709	str = this._normalizeString(str);
12710	mx = str.match(this.allTagsRexMatch);
12711	strs = str.split(this.allTagsRexSplit);
12712	myret = [strs[0]];
12713	for (pos = 1, len = strs.length; pos < len; pos += 1) {
12714		myret.push(mx[pos - 1]);
12715		myret.push(strs[pos]);
12716	}
12717	strs = myret.slice();
12718	len = strs.length - 2;
12719	for (pos = len; pos > 0; pos += -2) {
12720		if (strs[(pos - 1)].slice((strs[(pos - 1)].length - 1)) === "\\") {
12721			newstr = strs[(pos - 1)].slice(0, (strs[(pos - 1)].length - 1)) + strs[pos] + strs[(pos + 1)];
12722			head = strs.slice(0, (pos - 1));
12723			tail = strs.slice((pos + 2));
12724			head.push(newstr);
12725			strs = head.concat(tail);
12726		}
12727	}
12728	expected_closers = [];
12729	expected_openers = [];
12730	expected_flips = [];
12731	tagstack = [];
12732	badTagStack = [];
12733	lenA = strs.length - 1;
12734	for (posA = 1; posA < lenA; posA += 2) {
12735		tag = strs[posA];
12736		if (this.closeTagsHash[tag]) {
12737			expected_closers.reverse();
12738			sameAsOpen = this.openToCloseHash[tag];
12739			openRev = expected_closers.indexOf(tag);
12740			flipRev = expected_flips.indexOf(tag);
12741			expected_closers.reverse();
12742			if (!sameAsOpen || (openRev > -1 && (openRev < flipRev || flipRev === -1))) {
12743				ibeenrunned = false;
12744				lenB = expected_closers.length - 1;
12745				for (posB = lenB; posB > -1; posB += -1) {
12746					ibeenrunned = true;
12747					wanted_closer = expected_closers[posB];
12748					if (tag === wanted_closer) {
12749						expected_closers.pop();
12750						expected_openers.pop();
12751						expected_flips.pop();
12752						tagstack.pop();
12753						break;
12754					}
12755					badTagStack.push(posA);
12756				}
12757				if (!ibeenrunned) {
12758					badTagStack.push(posA);
12759				}
12760				continue;
12761			}
12762		}
12763		if (this.openToCloseHash[tag]) {
12764			expected_closers.push(this.openToCloseHash[tag]);
12765			expected_openers.push(tag);
12766			expected_flips.push(this.flipTagsHash[tag]);
12767			tagstack.push(posA);
12768		}
12769	}
12770	lenC = expected_closers.length - 1;
12771	for (posC = lenC; posC > -1; posC += -1) {
12772		expected_closers.pop();
12773		expected_flips.pop();
12774		expected_openers.pop();
12775		badTagStack.push(tagstack.pop());
12776	}
12777	badTagStack.sort(
12778		function (a, b) {
12779			if (a < b) {
12780				return 1;
12781			} else if (a > b) {
12782				return -1;
12783			}
12784			return 0;
12785		}
12786	);
12787	len = badTagStack.length;
12788	for (pos = 0; pos < len; pos += 1) {
12789		badTagPos = badTagStack[pos];
12790		head = strs.slice(0, (badTagPos - 1));
12791		tail = strs.slice((badTagPos + 2));
12792		sep = strs[badTagPos];
12793		if (sep.length && sep[0] !== "<" && this.openToDecorations[sep] && this.quotechars.indexOf(sep.replace(/\s+/g,"")) === -1) {
12794			params = this.openToDecorations[sep];
12795			sep = this.state.fun.decorate[params[0]][params[1][0]](this.state);
12796		}
12797		resplice = strs[(badTagPos - 1)] + sep + strs[(badTagPos + 1)];
12798		head.push(resplice);
12799		strs = head.concat(tail);
12800	}
12801	len = strs.length;
12802	for (pos = 0; pos < len; pos += 2) {
12803		strs[pos] = strs[pos].replace("'", "\u2019", "g");
12804		strs[pos] = strs[pos].replace("  \u2019", " \u2019", "g");
12805	}
12806	return strs;
12807};
12808CSL.Util.FlipFlopper.prototype.processTags = function () {
12809	var expected_closers, expected_openers, expected_flips, expected_rendering, str, posA, tag, prestr, newblob, blob, sameAsOpen, openRev, flipRev, posB, wanted_closer, newblobnest, param, fulldecor, level, decor, lenA, lenB, posC, lenC;
12810	expected_closers = [];
12811	expected_openers = [];
12812	expected_flips = [];
12813	expected_rendering = [];
12814	str = "";
12815	if (this.strs.length === 1) {
12816		this.blob.blobs = this.strs[0];
12817	} else if (this.strs.length > 2) {
12818		lenA = (this.strs.length - 1);
12819		for (posA = 1; posA < lenA; posA += 2) {
12820			tag = this.strs[posA];
12821			prestr = this.strs[(posA - 1)];
12822			if (prestr) {
12823				newblob = new CSL.Blob(prestr);
12824				blob = this.blobstack.value();
12825				blob.push(newblob);
12826			}
12827			if (this.closeTagsHash[tag]) {
12828				expected_closers.reverse();
12829				sameAsOpen = this.openToCloseHash[tag];
12830				openRev = expected_closers.indexOf(tag);
12831				flipRev = expected_flips.indexOf(tag);
12832				expected_closers.reverse();
12833				if (!sameAsOpen || (openRev > -1 && (openRev < flipRev || flipRev === -1))) {
12834					lenB = expected_closers.length;
12835					for (posB = lenB; posB > -1; posB += -1) {
12836						wanted_closer = expected_closers[posB];
12837						if (tag === wanted_closer) {
12838							expected_closers.pop();
12839							expected_openers.pop();
12840							expected_flips.pop();
12841							expected_rendering.pop();
12842							this.blobstack.pop();
12843							break;
12844						}
12845					}
12846					continue;
12847				}
12848			}
12849			if (this.openToCloseHash[tag]) {
12850				expected_closers.push(this.openToCloseHash[tag]);
12851				expected_openers.push(tag);
12852				expected_flips.push(this.flipTagsHash[tag]);
12853				blob = this.blobstack.value();
12854				newblobnest = new CSL.Blob();
12855				blob.push(newblobnest);
12856				param = this.addFlipFlop(newblobnest, this.openToDecorations[tag]);
12857				if (tag === "<span class=\"nodecor\">") {
12858					fulldecor = this.state[this.state.tmp.area].opt.topdecor.concat(this.blob.alldecor).concat([[["@quotes", "inner"]]]);
12859					lenB = fulldecor.length;
12860					for (posB = 0; posB < lenB; posB += 1) {
12861						level = fulldecor[posB];
12862						lenC = level.length;
12863						for (posC = 0; posC < lenC; posC += 1) {
12864							decor = level[posC];
12865							if (["@font-style", "@font-weight", "@font-variant"].indexOf(decor[0]) > -1) {
12866								param = this.addFlipFlop(newblobnest, this.okReverseHash[decor[0]]);
12867							}
12868						}
12869					}
12870				}
12871				expected_rendering.push(this.state.fun.decorate[param[0]][param[1]](this.state));
12872				this.blobstack.push(newblobnest);
12873			}
12874		}
12875		if (this.strs.length > 2) {
12876			str = this.strs[(this.strs.length - 1)];
12877			if (str) {
12878				blob = this.blobstack.value();
12879				newblob = new CSL.Blob(str);
12880				blob.push(newblob);
12881			}
12882		}
12883	}
12884	return this.blob;
12885};
12886CSL.Util.FlipFlopper.prototype.addFlipFlop = function (blob, fun) {
12887	var posA, posB, fulldecor, lenA, decorations, breakme, decor, posC, newdecor, lenC;
12888	posB = 0;
12889	fulldecor = this.state[this.state.tmp.area].opt.topdecor.concat(blob.alldecor).concat([[["@quotes", "inner"]]]);
12890	lenA = fulldecor.length;
12891	for (posA = 0; posA < lenA; posA += 1) {
12892		decorations = fulldecor[posA];
12893		breakme = false;
12894		lenC = decorations.length - 1;
12895		for (posC = lenC; posC > -1; posC += -1) {
12896			decor = decorations[posC];
12897			if (decor[0] === fun[0]) {
12898				if (decor[1] === fun[1][0]) {
12899					posB = 1;
12900				}
12901				breakme = true;
12902				break;
12903			}
12904		}
12905		if (breakme) {
12906			break;
12907		}
12908	}
12909	newdecor = [fun[0], fun[1][posB]];
12910	blob.decorations.reverse();
12911	blob.decorations.push(newdecor);
12912	blob.decorations.reverse();
12913	return newdecor;
12914};
12915CSL.Output.Formatters = {};
12916CSL.getSafeEscape = function(state) {
12917	if (["bibliography", "citation"].indexOf(state.tmp.area) > -1) {
12918		var callbacks = [];
12919		if (state.opt.development_extensions.thin_non_breaking_space_html_hack && state.opt.mode === "html") {
12920			callbacks.push(function (txt) {
12921				return txt.replace(/\u202f/g, '<span style="white-space:nowrap">&thinsp;</span>');
12922			});
12923		}
12924		if (callbacks.length) {
12925			return function (txt) {
12926				for (var i = 0, ilen = callbacks.length; i < ilen; i += 1) {
12927					txt = callbacks[i](txt);
12928				}
12929				return CSL.Output.Formats[state.opt.mode].text_escape(txt);
12930			}
12931		} else {
12932			return CSL.Output.Formats[state.opt.mode].text_escape;
12933		}
12934	} else {
12935		return function (txt) { return txt; };
12936	}
12937};
12938CSL.Output.Formatters.passthrough = function (state, string) {
12939	return string;
12940};
12941CSL.Output.Formatters.lowercase = function (state, string) {
12942	var str = CSL.Output.Formatters.doppelString(string, CSL.TAG_USEALL);
12943	str.string = str.string.toLowerCase();
12944	return CSL.Output.Formatters.undoppelString(str);
12945};
12946CSL.Output.Formatters.uppercase = function (state, string) {
12947	var str = CSL.Output.Formatters.doppelString(string, CSL.TAG_USEALL);
12948	str.string = str.string.toUpperCase();
12949	return CSL.Output.Formatters.undoppelString(str);
12950};
12951CSL.Output.Formatters["capitalize-first"] = function (state, string) {
12952	var str = CSL.Output.Formatters.doppelString(string, CSL.TAG_ESCAPE);
12953	if (str.string.length) {
12954		str.string = str.string.slice(0, 1).toUpperCase() + str.string.substr(1);
12955		return CSL.Output.Formatters.undoppelString(str);
12956	} else {
12957		return "";
12958	}
12959};
12960CSL.Output.Formatters.sentence = function (state, string) {
12961	var str = CSL.Output.Formatters.doppelString(string, CSL.TAG_ESCAPE);
12962	str.string = str.string.slice(0, 1).toUpperCase() + str.string.substr(1).toLowerCase();
12963	return CSL.Output.Formatters.undoppelString(str);
12964};
12965CSL.Output.Formatters["capitalize-all"] = function (state, string) {
12966	var str = CSL.Output.Formatters.doppelString(string, CSL.TAG_ESCAPE);
12967	var strings = str.string.split(" ");
12968	for (var i = 0, ilen = strings.length; i < ilen; i += 1) {
12969		if (strings[i].length > 1) {
12970			if (state.opt.development_extensions.allow_force_lowercase) {
12971				strings[i] = strings[i].slice(0, 1).toUpperCase() + strings[i].substr(1).toLowerCase();
12972			} else {
12973				strings[i] = strings[i].slice(0, 1).toUpperCase() + strings[i].substr(1);
12974			}
12975		} else if (strings[i].length === 1) {
12976			strings[i] = strings[i].toUpperCase();
12977		}
12978	}
12979	str.string = strings.join(" ");
12980	return CSL.Output.Formatters.undoppelString(str);
12981};
12982CSL.Output.Formatters.title = function (state, string) {
12983	var str, words, isAllUpperCase, newString, lastWordIndex, previousWordIndex, upperCaseVariant, lowerCaseVariant, pos, skip, notfirst, notlast, aftercolon, len, idx, tmp, skipword, ppos, mx, lst, myret;
12984	var SKIP_WORDS = state.locale[state.opt.lang].opts["skip-words"];
12985	if (!string) {
12986		return "";
12987	}
12988	var doppel = CSL.Output.Formatters.doppelString(string, CSL.TAG_ESCAPE);
12989	function capitalise (word) {
12990		var m = word.match(/([:?!]+\s+|-|^)(.)(.*)/);
12991		if (m) {
12992			return m[1] + m[2].toUpperCase() + m[3];
12993		}
12994		return word;
12995	}
12996	var str = doppel.string;
12997	var lst = str.split(state.locale[state.opt.lang].opts["skip-words-regexp"])
12998	for (i=1,ilen=lst.length;i<ilen;i+=2) {
12999		if (lst[i].match(/^[:?!]/)) {
13000			lst[i] = capitalise(lst[i]);
13001		}
13002	}
13003	if (!lst[0]) {
13004		lst[1] = capitalise(lst[1]);
13005	}
13006	if (lst.length > 2 && !lst[lst.length-1]) {
13007		lst[lst.length-2] = capitalise(lst[lst.length-2]);
13008	}
13009	for (var i=0,ilen=lst.length;i<ilen;i+=2) {
13010		var words = lst[i].split(/([:?!]*\s+|-)/);
13011		for (var k=0,klen=words.length;k<klen;k+=2) {
13012			if (words[k].length !== 0) {
13013				upperCaseVariant = words[k].toUpperCase();
13014				lowerCaseVariant = words[k].toLowerCase();
13015				if (words[k].match(/[0-9]/)) {
13016					continue;
13017				}
13018				if (words[k] === lowerCaseVariant) {
13019					words[k] = capitalise(words[k]);
13020				}
13021			}
13022		}
13023		lst[i] = words.join("");
13024	}
13025	doppel.string = lst.join("");
13026	var ret = CSL.Output.Formatters.undoppelString(doppel);
13027	return ret;
13028};
13029CSL.Output.Formatters.doppelString = function (string, rex) {
13030	var ret, pos, len;
13031	ret = {};
13032	ret.array = rex(string);
13033	ret.string = "";
13034	for (var i=0,ilen=ret.array.length; i<ilen; i += 2) {
13035		if (ret.array[i-1] === "-" && false) {
13036			ret.string += " " + ret.array[i];
13037		} else {
13038			ret.string += ret.array[i];
13039		}
13040	}
13041	return ret;
13042};
13043CSL.Output.Formatters.undoppelString = function (str) {
13044	var ret, len, pos;
13045	ret = "";
13046	for (var i=0,ilen=str.array.length; i<ilen; i+=1) {
13047		if ((i % 2)) {
13048			ret += str.array[i];
13049		} else {
13050			if (str.array[i-1] === "-" && false) {
13051				ret += str.string.slice(0, str.array[i].length+1).slice(1);
13052				str.string = str.string.slice(str.array[i].length+1);
13053			} else {
13054				ret += str.string.slice(0, str.array[i].length);
13055				str.string = str.string.slice(str.array[i].length);
13056			}
13057		}
13058	}
13059	return ret;
13060};
13061CSL.Output.Formatters.serializeItemAsRdf = function (Item) {
13062	return "";
13063};
13064CSL.Output.Formatters.serializeItemAsRdfA = function (Item) {
13065	return "";
13066};
13067CSL.demoteNoiseWords = function (state, fld, drop_or_demote) {
13068	var SKIP_WORDS = state.locale[state.opt.lang].opts["leading-noise-words"];
13069	if (fld && drop_or_demote) {
13070		fld = fld.split(/\s+/);
13071		fld.reverse();
13072		var toEnd = [];
13073		for (var j  = fld.length - 1; j > -1; j += -1) {
13074			if (SKIP_WORDS.indexOf(fld[j].toLowerCase()) > -1) {
13075				toEnd.push(fld.pop());
13076			} else {
13077				break;
13078			}
13079		}
13080		fld.reverse();
13081		var start = fld.join(" ");
13082		var end = toEnd.join(" ");
13083		if ("drop" === drop_or_demote || !end) {
13084			fld = start;
13085		} else if ("demote" === drop_or_demote) {
13086			fld = [start, end].join(", ");
13087		}
13088	}
13089	return fld;
13090};
13091CSL.Output.Formats = function () {};
13092CSL.Output.Formats.prototype.html = {
13093	"text_escape": function (text) {
13094		if (!text) {
13095			text = "";
13096		}
13097		return text.replace(/&/g, "&#38;")
13098			.replace(/</g, "&#60;")
13099			.replace(/>/g, "&#62;")
13100			.replace("  ", "&#160; ", "g")
13101			.replace(CSL.SUPERSCRIPTS_REGEXP,
13102					 function(aChar) {
13103						 return "<sup>" + CSL.SUPERSCRIPTS[aChar] + "</sup>";
13104					 });
13105	},
13106	"bibstart": "<div class=\"csl-bib-body\">\n",
13107	"bibend": "</div>",
13108	"@font-style/italic": "<i>%%STRING%%</i>",
13109	"@font-style/oblique": "<em>%%STRING%%</em>",
13110	"@font-style/normal": "<span style=\"font-style:normal;\">%%STRING%%</span>",
13111	"@font-variant/small-caps": "<span style=\"font-variant:small-caps;\">%%STRING%%</span>",
13112	"@passthrough/true": CSL.Output.Formatters.passthrough,
13113	"@font-variant/normal": "<span style=\"font-variant:normal;\">%%STRING%%</span>",
13114	"@font-weight/bold": "<b>%%STRING%%</b>",
13115	"@font-weight/normal": "<span style=\"font-weight:normal;\">%%STRING%%</span>",
13116	"@font-weight/light": false,
13117	"@text-decoration/none": "<span style=\"text-decoration:none;\">%%STRING%%</span>",
13118	"@text-decoration/underline": "<span style=\"text-decoration:underline;\">%%STRING%%</span>",
13119	"@vertical-align/sup": "<sup>%%STRING%%</sup>",
13120	"@vertical-align/sub": "<sub>%%STRING%%</sub>",
13121	"@vertical-align/baseline": "<span style=\"baseline\">%%STRING%%</span>",
13122	"@strip-periods/true": CSL.Output.Formatters.passthrough,
13123	"@strip-periods/false": CSL.Output.Formatters.passthrough,
13124	"@quotes/true": function (state, str) {
13125		if ("undefined" === typeof str) {
13126			return state.getTerm("open-quote");
13127		}
13128		return state.getTerm("open-quote") + str + state.getTerm("close-quote");
13129	},
13130	"@quotes/inner": function (state, str) {
13131		if ("undefined" === typeof str) {
13132			return "\u2019";
13133		}
13134		return state.getTerm("open-inner-quote") + str + state.getTerm("close-inner-quote");
13135	},
13136	"@quotes/false": false,
13137	"@cite/entry": function (state, str) {
13138		return state.sys.wrapCitationEntry(str, this.item_id, this.locator_txt, this.suffix_txt);
13139	},
13140	"@bibliography/entry": function (state, str) {
13141		var insert = "";
13142		if (state.sys.embedBibliographyEntry) {
13143			insert = state.sys.embedBibliographyEntry(this.item_id) + "\n";
13144		}
13145		return "  <div class=\"csl-entry\">" + str + "</div>\n" + insert;
13146	},
13147	"@display/block": function (state, str) {
13148		return "\n\n    <div class=\"csl-block\">" + str + "</div>\n";
13149	},
13150	"@display/left-margin": function (state, str) {
13151		return "\n    <div class=\"csl-left-margin\">" + str + "</div>";
13152	},
13153	"@display/right-inline": function (state, str) {
13154		return "<div class=\"csl-right-inline\">" + str + "</div>\n  ";
13155	},
13156	"@display/indent": function (state, str) {
13157		return "<div class=\"csl-indent\">" + str + "</div>\n  ";
13158	},
13159	"@showid/true": function (state, str, cslid) {
13160		if (!state.tmp.just_looking && ! state.tmp.suppress_decorations) {
13161			if (cslid) {
13162				return "<span class=\"" + state.opt.nodenames[cslid] + "\" cslid=\"" + cslid + "\">" + str + "</span>";
13163			} else if ("string" === typeof str) {
13164				var prePunct = "";
13165				if (str) {
13166					var m = str.match(CSL.VARIABLE_WRAPPER_PREPUNCT_REX);
13167					prePunct = m[1];
13168					str = m[2];
13169				}
13170				var postPunct = "";
13171				if (str && CSL.SWAPPING_PUNCTUATION.indexOf(str.slice(-1)) > -1) {
13172					postPunct = str.slice(-1);
13173					str = str.slice(0,-1);
13174				}
13175				return state.sys.variableWrapper(this.params, prePunct, str, postPunct);
13176			} else {
13177				return str;
13178			}
13179		} else {
13180			return str;
13181		}
13182	},
13183	"@URL/true": function (state, str) {
13184		return "<a href=\"" + str + "\">" + str + "</a>";
13185	},
13186	"@DOI/true": function (state, str) {
13187		return "<a href=\"http://dx.doi.org/" + str + "\">" + str + "</a>";
13188	}
13189};
13190CSL.Output.Formats.prototype.text = {
13191	"text_escape": function (text) {
13192		if (!text) {
13193			text = "";
13194		}
13195		return text;
13196	},
13197	"bibstart": "",
13198	"bibend": "",
13199	"@font-style/italic": false,
13200	"@font-style/oblique": false,
13201	"@font-style/normal": false,
13202	"@font-variant/small-caps": false,
13203	"@passthrough/true": CSL.Output.Formatters.passthrough,
13204	"@font-variant/normal": false,
13205	"@font-weight/bold": false,
13206	"@font-weight/normal": false,
13207	"@font-weight/light": false,
13208	"@text-decoration/none": false,
13209	"@text-decoration/underline": false,
13210	"@vertical-align/baseline": false,
13211	"@vertical-align/sup": false,
13212	"@vertical-align/sub": false,
13213	"@strip-periods/true": CSL.Output.Formatters.passthrough,
13214	"@strip-periods/false": CSL.Output.Formatters.passthrough,
13215	"@quotes/true": function (state, str) {
13216		if ("undefined" === typeof str) {
13217			return state.getTerm("open-quote");
13218		}
13219		return state.getTerm("open-quote") + str + state.getTerm("close-quote");
13220	},
13221	"@quotes/inner": function (state, str) {
13222		if ("undefined" === typeof str) {
13223			return "\u2019";
13224		}
13225		return state.getTerm("open-inner-quote") + str + state.getTerm("close-inner-quote");
13226	},
13227	"@quotes/false": false,
13228	"@cite/entry": function (state, str) {
13229		return state.sys.wrapCitationEntry(str, this.item_id, this.locator_txt, this.suffix_txt);
13230	},
13231	"@bibliography/entry": function (state, str) {
13232		return str+"\n";
13233	},
13234	"@display/block": function (state, str) {
13235		return "\n"+str;
13236	},
13237	"@display/left-margin": function (state, str) {
13238		return str;
13239	},
13240	"@display/right-inline": function (state, str) {
13241		return str;
13242	},
13243	"@display/indent": function (state, str) {
13244		return "\n    "+str;
13245	},
13246	"@showid/true": function (state, str, cslid) {
13247		return str;
13248	},
13249	"@URL/true": function (state, str) {
13250		return str;
13251	},
13252	"@DOI/true": function (state, str) {
13253		return str;
13254	}
13255};
13256CSL.Output.Formats.prototype.rtf = {
13257	"text_escape": function (text) {
13258		if (!text) {
13259			text = "";
13260		}
13261		return text
13262		.replace(/([\\{}])/g, "\\$1", "g")
13263		.replace(CSL.SUPERSCRIPTS_REGEXP,
13264				 function(aChar) {
13265					 return "\\super " + CSL.SUPERSCRIPTS[aChar] + "\\nosupersub{}";
13266				 })
13267		.replace(/[\u007F-\uFFFF]/g,
13268				 function(aChar) { return "\\uc0\\u"+aChar.charCodeAt(0).toString()+"{}"; })
13269		.replace("\t", "\\tab{}", "g");
13270	},
13271	"@passthrough/true": CSL.Output.Formatters.passthrough,
13272	"@font-style/italic":"\\i %%STRING%%\\i0{}",
13273	"@font-style/normal":"\\i0{}%%STRING%%\\i{}",
13274	"@font-style/oblique":"\\i %%STRING%%\\i0{}",
13275	"@font-variant/small-caps":"\\scaps %%STRING%%\\scaps0{}",
13276	"@font-variant/normal":"\\scaps0{}%%STRING%%\\scaps{}",
13277	"@font-weight/bold":"\\b %%STRING%%\\b0{}",
13278	"@font-weight/normal":"\\b0{}%%STRING%%\\b{}",
13279	"@font-weight/light":false,
13280	"@text-decoration/none":false,
13281	"@text-decoration/underline":"\\ul %%STRING%%\\ul0{}",
13282	"@vertical-align/baseline":false,
13283	"@vertical-align/sup":"\\super %%STRING%%\\nosupersub{}",
13284	"@vertical-align/sub":"\\sub %%STRING%%\\nosupersub{}",
13285	"@strip-periods/true": CSL.Output.Formatters.passthrough,
13286	"@strip-periods/false": CSL.Output.Formatters.passthrough,
13287	"@quotes/true": function (state, str) {
13288		if ("undefined" === typeof str) {
13289			return CSL.Output.Formats.rtf.text_escape(state.getTerm("open-quote"));
13290		}
13291		return CSL.Output.Formats.rtf.text_escape(state.getTerm("open-quote")) + str + CSL.Output.Formats.rtf.text_escape(state.getTerm("close-quote"));
13292	},
13293	"@quotes/inner": function (state, str) {
13294		if ("undefined" === typeof str) {
13295			return CSL.Output.Formats.rtf.text_escape("\u2019");
13296		}
13297		return CSL.Output.Formats.rtf.text_escape(state.getTerm("open-inner-quote")) + str + CSL.Output.Formats.rtf.text_escape(state.getTerm("close-inner-quote"));
13298	},
13299	"@quotes/false": false,
13300	"bibstart":"{\\rtf ",
13301	"bibend":"}",
13302	"@display/block": "\\line{}%%STRING%%\\line\r\n",
13303	"@cite/entry": function (state, str) {
13304		return str;
13305	},
13306	"@cite/entry": function (state, str) {
13307		return state.sys.wrapCitationEntry(str, this.item_id, this.locator_txt, this.suffix_txt);
13308	},
13309	"@bibliography/entry": function(state,str){
13310		return str;
13311	},
13312	"@display/left-margin": function(state,str){
13313		return str+"\\tab ";
13314	},
13315	"@display/right-inline": function (state, str) {
13316		return str+"\\line\r\n";
13317	},
13318	"@display/indent": function (state, str) {
13319		return "\n\\tab "+str+"\\line\r\n";
13320	},
13321	"@showid/true": function (state, str, cslid) {
13322		if (!state.tmp.just_looking && ! state.tmp.suppress_decorations) {
13323			var prePunct = "";
13324			if (str) {
13325				var m = str.match(CSL.VARIABLE_WRAPPER_PREPUNCT_REX);
13326				prePunct = m[1];
13327				str = m[2];
13328			}
13329			var postPunct = "";
13330			if (str && CSL.SWAPPING_PUNCTUATION.indexOf(str.slice(-1)) > -1) {
13331				postPunct = str.slice(-1);
13332				str = str.slice(0,-1);
13333			}
13334			return state.sys.variableWrapper(this.params, prePunct, str, postPunct);
13335		} else {
13336			return str;
13337		}
13338	},
13339	"@URL/true": function (state, str) {
13340		return str;
13341	},
13342	"@DOI/true": function (state, str) {
13343		return str;
13344	}
13345};
13346CSL.Output.Formats = new CSL.Output.Formats();
13347CSL.Registry = function (state) {
13348	var pos, len, ret, i, ilen;
13349	this.debug = false;
13350	this.state = state;
13351	this.registry = {};
13352	this.reflist = [];
13353	this.namereg = new CSL.Registry.NameReg(state);
13354	this.citationreg = new CSL.Registry.CitationReg(state);
13355	this.authorstrings = {};
13356	this.mylist = [];
13357	this.myhash = {};
13358	this.deletes = [];
13359	this.inserts = [];
13360	this.uncited = {};
13361	this.refreshes = {};
13362	this.akeys = {};
13363	this.oldseq = {};
13364	this.return_data = {};
13365	this.ambigcites = {};
13366	this.ambigresets = {};
13367	this.sorter = new CSL.Registry.Comparifier(state, "bibliography_sort");
13368	this.getSortedIds = function () {
13369		ret = [];
13370		for (i = 0, ilen = this.reflist.length; i < ilen; i += 1) {
13371			ret.push("" + this.reflist[i].id);
13372		}
13373		return ret;
13374	};
13375	this.getSortedRegistryItems = function () {
13376		ret = [];
13377		for (i = 0, ilen = this.reflist.length; i < ilen; i += 1) {
13378			ret.push(this.reflist[i]);
13379		}
13380		return ret;
13381	};
13382};
13383CSL.Registry.prototype.init = function (itemIDs, uncited_flag) {
13384	var i, ilen;
13385	this.oldseq = {};
13386	if (uncited_flag) {
13387		this.uncited = {};
13388		for (var i=0,ilen=itemIDs.length;i<ilen; i += 1) {
13389			if (!this.myhash[itemIDs[i]]) {
13390				this.mylist.push("" + itemIDs[i]);
13391			}
13392			this.uncited[itemIDs[i]] = true;
13393			this.myhash[itemIDs[i]] = true;
13394		}
13395	} else {
13396		for (var key in this.uncited) {
13397			itemIDs.push(key);
13398		}
13399		var myhash = {};
13400		for (i=itemIDs.length-1;i>-1; i += -1) {
13401			if (myhash[itemIDs[i]]) {
13402				itemIDs = itemIDs.slice(0, i).concat(itemIDs.slice(i + 1));
13403			} else {
13404				myhash[itemIDs[i]] = true;
13405			}
13406		}
13407		this.mylist = [];
13408		for (var i=0,ilen=itemIDs.length;i<ilen;i+=1) {
13409			this.mylist.push("" + itemIDs[i]);
13410		}
13411		this.myhash = myhash;
13412	}
13413	this.refreshes = {};
13414	this.touched = {};
13415	this.ambigsTouched = {};
13416	this.ambigresets = {};
13417};
13418CSL.Registry.prototype.dopurge = function (myhash) {
13419	for (var i=this.mylist.length-1;i>-1;i+=-1) {
13420		if (this.citationreg.citationsByItemId) {
13421			if (!this.citationreg.citationsByItemId[this.mylist[i]] && !myhash[this.mylist[i]]) {
13422				delete this.myhash[this.mylist[i]];
13423				this.mylist = this.mylist.slice(0,i).concat(this.mylist.slice(i+1));
13424			}
13425		}
13426	}
13427	this.dodeletes(this.myhash);
13428};
13429CSL.Registry.prototype.dodeletes = function (myhash) {
13430	var otheritems, key, ambig, pos, len, items, kkey, mypos, id;
13431	if ("string" === typeof myhash) {
13432		myhash = {};
13433		myhash[myhash] = true;
13434	}
13435	for (key in this.registry) {
13436		if (!myhash[key]) {
13437			if (this.uncited[key]) {
13438				continue;
13439			}
13440			otheritems = this.namereg.delitems(key);
13441			for (kkey in otheritems) {
13442				this.refreshes[kkey] = true;
13443			}
13444			ambig = this.registry[key].ambig;
13445			mypos = this.ambigcites[ambig].indexOf(key);
13446			if (mypos > -1) {
13447				items = this.ambigcites[ambig].slice();
13448				this.ambigcites[ambig] = items.slice(0, mypos).concat(items.slice(mypos+1, items.length));
13449				this.ambigresets[ambig] = this.ambigcites[ambig].length;
13450			}
13451			len = this.ambigcites[ambig].length;
13452			for (pos = 0; pos < len; pos += 1) {
13453				id = "" + this.ambigcites[ambig][pos];
13454				this.refreshes[id] = true;
13455			}
13456			if (this.registry[key].siblings) {
13457				if (this.registry[key].siblings.length == 1) {
13458					var loneSiblingID = this.registry[key].siblings[0];
13459					this.registry[loneSiblingID].master = true;
13460					this.registry[loneSiblingID].siblings.pop();
13461					this.registry[loneSiblingID].parallel = false;
13462				} else if (this.registry[key].siblings.length > 1) {
13463					var removeIDs = [key];
13464					if (this.registry[key].master) {
13465						var newmasterID = this.registry[key].siblings[0];
13466						var newmaster = this.registry[newmasterID];
13467						newmaster.master = true;
13468						newmaster.parallel = false;
13469						removeIDs.push(newmasterID);
13470						for (var k = 0, klen = this.registry[key].siblings.length; k < klen; k += 1) {
13471							this.registry[this.registry[key].siblings[k]].parallel = newmasterID;
13472						}
13473					}
13474					var buffer = [];
13475					for (var k = this.registry[key].siblings.length - 1; k > -1; k += -1) {
13476						var siblingID = this.registry[key].siblings.pop();
13477						if (removeIDs.indexOf(siblingID) === -1) {
13478							buffer.push(siblingID)
13479						}
13480					}
13481					for (var k = buffer.length - 1; k > -1; k += -1) {
13482						this.registry[key].siblings.push(buffer[k]);
13483					}
13484				}
13485			}
13486			delete this.registry[key];
13487			this.return_data.bibchange = true;
13488		}
13489	}
13490};
13491CSL.Registry.prototype.doinserts = function (mylist) {
13492	var len, pos, item, Item, akey, newitem, abase, j, jlen, k, klen, i, ilen;
13493	if ("string" === typeof mylist) {
13494		mylist = [mylist];
13495	}
13496	for (i = 0, ilen = mylist.length; i < ilen; i += 1) {
13497		item = mylist[i];
13498		if (!this.registry[item]) {
13499			Item = this.state.retrieveItem(item);
13500			akey = CSL.getAmbiguousCite.call(this.state, Item);
13501			this.ambigsTouched[akey] = true;
13502			if (!Item.legislation_id) {
13503				this.akeys[akey] = true;
13504			}
13505			newitem = {
13506				"id": "" + item,
13507				"seq": 0,
13508				"offset": 0,
13509				"sortkeys": false,
13510				"ambig": false,
13511				"rendered": false,
13512				"disambig": false,
13513				"ref": Item
13514			};
13515			this.registry[item] = newitem;
13516			if (this.citationreg.citationsByItemId && this.citationreg.citationsByItemId[item]) {
13517				this.registry[item]["first-reference-note-number"] = this.citationreg.citationsByItemId[item][0].properties.noteIndex;
13518			}
13519			abase = CSL.getAmbigConfig.call(this.state);
13520			this.registerAmbigToken(akey, item, abase);
13521			this.touched[item] = true;
13522			this.return_data.bibchange = true;
13523		}
13524	}
13525};
13526CSL.Registry.prototype.rebuildlist = function () {
13527	var count, len, pos, item;
13528	this.reflist = [];
13529	if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING
13530		 && this.state.opt.citation_number_sort_used) {
13531	}
13532	len = this.mylist.length;
13533	for (pos = 0; pos < len; pos += 1) {
13534		item = this.mylist[pos];
13535		this.reflist.push(this.registry[item]);
13536		this.oldseq[item] = this.registry[item].seq;
13537		this.registry[item].seq = (pos + 1);
13538	}
13539	if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING
13540		 && this.state.opt.citation_number_sort_used) {
13541	}
13542};
13543CSL.Registry.prototype.dorefreshes = function () {
13544	var key, regtoken, Item, old_akey, akey, abase;
13545	for (key in this.refreshes) {
13546		regtoken = this.registry[key];
13547		if (!regtoken) {
13548			continue;
13549		}
13550		regtoken.sortkeys = undefined;
13551		Item = this.state.retrieveItem(key);
13552		var akey = regtoken.ambig;
13553		if ("undefined" === typeof akey) {
13554			this.state.tmp.disambig_settings = false;
13555			akey = CSL.getAmbiguousCite.call(this.state, Item);
13556			abase = CSL.getAmbigConfig.call(this.state);
13557			this.registerAmbigToken(akey, key, abase);
13558		}
13559		for (var akkey in this.ambigresets) {
13560			if (this.ambigresets[akkey] === 1) {
13561				var loneKey = this.ambigcites[akey][0];
13562				var Item = this.state.retrieveItem(loneKey);
13563				this.registry[loneKey].disambig = new CSL.AmbigConfig;
13564				this.state.tmp.disambig_settings = false;
13565				var akey = CSL.getAmbiguousCite.call(this.state, Item);
13566				var abase = CSL.getAmbigConfig.call(this.state);
13567				this.registerAmbigToken(akey, loneKey, abase);
13568			}
13569		}
13570		this.state.tmp.taintedItemIDs[key] = true;
13571		this.ambigsTouched[akey] = true;
13572		if (!Item.legislation_id) {
13573			this.akeys[akey] = true;
13574		}
13575		this.touched[key] = true;
13576	}
13577};
13578CSL.Registry.prototype.setdisambigs = function () {
13579	var akey, leftovers, key, pos, len, id;
13580	this.leftovers = [];
13581	for (akey in this.ambigsTouched) {
13582		this.state.disambiguate.run(akey);
13583	}
13584	this.ambigsTouched = {};
13585	this.akeys = {};
13586};
13587CSL.Registry.prototype.renumber = function () {
13588	var len, pos, item;
13589	if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING
13590		 && this.state.opt.citation_number_sort_used) {
13591	}
13592	len = this.reflist.length;
13593	for (pos = 0; pos < len; pos += 1) {
13594		item = this.reflist[pos];
13595		item.seq = (pos + 1);
13596		if (this.state.opt.update_mode === CSL.NUMERIC && item.seq != this.oldseq[item.id]) {
13597			this.state.tmp.taintedItemIDs[item.id] = true;
13598		}
13599		if (this.state.opt.bib_mode === CSL.NUMERIC && item.seq != this.oldseq[item.id]) {
13600			this.return_data.bibchange = true;
13601		}
13602	}
13603	if (this.state.opt.citation_number_sort_direction === CSL.DESCENDING
13604		 && this.state.opt.citation_number_sort_used) {
13605		this.reflist.reverse();
13606	}
13607};
13608CSL.Registry.prototype.setsortkeys = function () {
13609	var key;
13610	for (var i = 0, ilen = this.mylist.length; i < ilen; i += 1) {
13611		var key = this.mylist[i];
13612		if (this.touched[key] || this.state.tmp.taintedItemIDs[key] || !this.registry[key].sortkeys) {
13613			this.registry[key].sortkeys = CSL.getSortKeys.call(this.state, this.state.retrieveItem(key), "bibliography_sort");
13614		}
13615	}
13616};
13617CSL.Registry.prototype.sorttokens = function () {
13618	this.reflist.sort(this.sorter.compareKeys);
13619};
13620CSL.Registry.Comparifier = function (state, keyset) {
13621	var sort_directions, len, pos, compareKeys;
13622	var sortCompare = CSL.getSortCompare(state.opt["default-locale-sort"]);
13623	sort_directions = state[keyset].opt.sort_directions;
13624	this.compareKeys = function (a, b) {
13625		len = a.sortkeys ? a.sortkeys.length : 0;
13626		for (pos = 0; pos < len; pos += 1) {
13627			var cmp = 0;
13628			if (a.sortkeys[pos] === b.sortkeys[pos]) {
13629				cmp = 0;
13630			} else if ("undefined" === typeof a.sortkeys[pos]) {
13631				cmp = sort_directions[pos][1];
13632			} else if ("undefined" === typeof b.sortkeys[pos]) {
13633				cmp = sort_directions[pos][0];
13634			} else {
13635				cmp = sortCompare(a.sortkeys[pos], b.sortkeys[pos]);
13636			}
13637			if (0 < cmp) {
13638				return sort_directions[pos][1];
13639			} else if (0 > cmp) {
13640				return sort_directions[pos][0];
13641			}
13642		}
13643		if (a.seq > b.seq) {
13644			return 1;
13645		} else if (a.seq < b.seq) {
13646			return -1;
13647		}
13648		return 0;
13649	};
13650	compareKeys = this.compareKeys;
13651	this.compareCompositeKeys = function (a, b) {
13652		return compareKeys(a[1], b[1]);
13653	};
13654};
13655CSL.Registry.prototype.compareRegistryTokens = function (a, b) {
13656	if (a.seq > b.seq) {
13657		return 1;
13658	} else if (a.seq < b.seq) {
13659		return -1;
13660	}
13661	return 0;
13662};
13663CSL.Registry.prototype.registerAmbigToken = function (akey, id, ambig_config) {
13664	if (this.registry[id] && this.registry[id].disambig && this.registry[id].disambig.names) {
13665		for (var i = 0, ilen = ambig_config.names.length; i < ilen; i += 1) {
13666			var new_names_params = ambig_config.names[i];
13667			var old_names_params = this.registry[id].disambig.names[i];
13668			if (new_names_params !== old_names_params) {
13669				this.state.tmp.taintedItemIDs[id] = true;
13670			}
13670 else if (ambig_config.givens[i]) {
13671				for (var j=0,jlen=ambig_config.givens[i].length;j<jlen;j+=1) {
13672					var new_gnames_params = ambig_config.givens[i][j];
13673					var old_gnames_params = this.registry[id].disambig.givens[i][j];
13674					if (new_gnames_params !== old_gnames_params) {
13675						this.state.tmp.taintedItemIDs[id] = true;
13676					}
13677				}
13678			}
13679		}
13680	}
13681	if (!this.ambigcites[akey]) {
13682		this.ambigcites[akey] = [];
13683	}
13684	if (this.ambigcites[akey].indexOf("" + id) === -1) {
13685		this.ambigcites[akey].push("" + id);
13686	}
13687	this.registry[id].ambig = akey;
13688	var dome = false;
13689	this.registry[id].disambig = CSL.cloneAmbigConfig(ambig_config);
13690};
13691CSL.getSortKeys = function (Item, key_type) {
13692	var area, extension, strip_prepositions, use_parallels, len, pos;
13693	area = this.tmp.area;
13694	extension = this.tmp.extension;
13695	strip_prepositions = CSL.Util.Sort.strip_prepositions;
13696	this.tmp.area = key_type;
13697	this.tmp.extension = "_sort";
13698	this.tmp.disambig_override = true;
13699	this.tmp.disambig_request = false;
13700	use_parallels = this.parallel.use_parallels;
13701	this.parallel.use_parallels = false;
13702	this.tmp.suppress_decorations = true;
13703	CSL.getCite.call(this, Item);
13704	this.tmp.suppress_decorations = false;
13705	this.parallel.use_parallels = use_parallels;
13706	this.tmp.disambig_override = false;
13707	len = this[key_type].keys.length;
13708	for (pos = 0; pos < len; pos += 1) {
13709		this[key_type].keys[pos] = strip_prepositions(this[key_type].keys[pos]);
13710	}
13711	this.tmp.area = area;
13712	this.tmp.extension = extension;
13713	return this[key_type].keys;
13714};
13715CSL.Registry.NameReg = function (state) {
13716	var pkey, ikey, skey, floor, ceiling, dagopt, gdropt, ret, pos, items, strip_periods, set_keys, evalname, delitems, addname, key, myitems, i, ilen;
13717	this.state = state;
13718	this.namereg = {};
13719	this.nameind = {};
13720	this.nameindpkeys = {};
13721	this.itemkeyreg = {};
13722	strip_periods = function (str) {
13723		if (!str) {
13724			str = "";
13725		}
13726		return str.replace(".", " ", "g").replace(/\s+/g, " ").replace(/\s+$/,"");
13727	};
13728	set_keys = function (state, itemid, nameobj) {
13729		pkey = strip_periods(nameobj.family);
13730		skey = strip_periods(nameobj.given);
13731		var m = skey.match(/[,\!]* ([^,]+)$/);
13732		if (m && m[1] === m[1].toLowerCase()) {
13733			skey = skey.replace(/[,\!]* [^,]+$/, "");
13734		}
13735		ikey = CSL.Util.Names.initializeWith(state, skey, "%s");
13736		if (state.citation.opt["givenname-disambiguation-rule"] === "by-cite") {
13737			pkey = "" + itemid + pkey;
13738		}
13739	};
13740	evalname = function (item_id, nameobj, namenum, request_base, form, initials) {
13741		var pos, len, items, param;
13742		if (state.tmp.area.slice(0, 12) === "bibliography" && !form) {
13743			if ("string" === typeof initials) {
13744				return 1;
13745			} else {
13746				return 2;
13747			}
13748		}
13749		var res = state.nameOutput.getName(nameobj, "locale-translit", true);
13750		nameobj = res.name;
13751		set_keys(this.state, "" + item_id, nameobj);
13752		param = 2;
13753		dagopt = state.opt["disambiguate-add-givenname"];
13754		gdropt = state.citation.opt["givenname-disambiguation-rule"];
13755		var gdropt_orig = gdropt;
13756		if (gdropt === "by-cite") {
13757			gdropt = "all-names";
13758		}
13759		if ("short" === form) {
13760			param = 0;
13761		} else if ("string" === typeof initials) {
13762			param = 1;
13763		}
13764		if ("undefined" === typeof this.namereg[pkey] || "undefined" === typeof this.namereg[pkey].ikey[ikey]) {
13765			return param;
13766		}
13767		if (gdropt_orig === "by-cite" && param <= request_base) {
13768			return request_base;
13769		}
13770		if (!dagopt) {
13771			return param;
13772		}
13773		if ("string" === typeof gdropt && gdropt.slice(0, 12) === "primary-name" && namenum > 0) {
13774			return param;
13775		}
13776		if (!gdropt || gdropt === "all-names" || gdropt === "primary-name") {
13777			if (this.namereg[pkey].count > 1) {
13778				param = 1;
13779			}
13780			if ((this.namereg[pkey].ikey
13781				 && this.namereg[pkey].ikey[ikey].count > 1)
13782				|| (this.namereg[pkey].count > 1
13783					&& "string" !== typeof initials)) {
13784				param = 2;
13785			}
13786		} else if (gdropt === "all-names-with-initials" || gdropt === "primary-name-with-initials") {
13787			if (this.namereg[pkey].count > 1) {
13788				param = 1;
13789			} else {
13790				param = 0;
13791			}
13792		}
13793		if (!state.registry.registry[item_id]) {
13794			if (form == "short") {
13795				return 0;
13796			} else if ("string" == typeof initials) {
13797				return 1;
13798			}
13799		} else {
13800			return param;
13801		}
13802	};
13803	delitems = function (ids) {
13804		var item, pos, len, posA, posB, id, fullkey, llen, ppos, otherid;
13805		if ("string" === typeof ids || "number" === typeof ids) {
13806			ids = ["" + ids];
13807		}
13808		ret = {};
13809		len = ids.length;
13810		for (pos = 0; pos < len; pos += 1) {
13811			id = "" + ids[pos];
13812			if (!this.nameind[id]) {
13813				continue;
13814			}
13815			for (fullkey in this.nameind[id]) {
13816				if (this.nameind[id].hasOwnProperty(fullkey)) {
13817					key = fullkey.split("::");
13818					pkey = key[0];
13819					ikey = key[1];
13820					skey = key[2];
13821					if ("undefined" === typeof this.namereg[pkey]) {
13822						continue;
13823					}
13824					items = this.namereg[pkey].items;
13825					if (skey && this.namereg[pkey].ikey[ikey] && this.namereg[pkey].ikey[ikey].skey[skey]) {
13826						myitems = this.namereg[pkey].ikey[ikey].skey[skey].items;
13827						posB = myitems.indexOf("" + id);
13828						if (posB > -1) {
13829							this.namereg[pkey].ikey[ikey].skey[skey].items = myitems.slice(0, posB).concat(myitems.slice([(posB + 1)]));
13830						}
13831						if (this.namereg[pkey].ikey[ikey].skey[skey].items.length === 0) {
13832							delete this.namereg[pkey].ikey[ikey].skey[skey];
13833							this.namereg[pkey].ikey[ikey].count += -1;
13834							if (this.namereg[pkey].ikey[ikey].count < 2) {
13835								for (i = 0, ilen = this.namereg[pkey].ikey[ikey].items.length; i < ilen; i += 1) {
13836									state.tmp.taintedItemIDs[this.namereg[pkey].ikey[ikey].items[i]] = true;
13837								}
13838							}
13839						}
13840					}
13841					if (ikey && this.namereg[pkey].ikey[ikey]) {
13842						posB = this.namereg[pkey].ikey[ikey].items.indexOf("" + id);
13843						if (posB > -1) {
13844							items = this.namereg[pkey].ikey[ikey].items.slice();
13845							this.namereg[pkey].ikey[ikey].items = items.slice(0, posB).concat(items.slice([posB + 1])
vendor: 16,145 bytes, lines 13845-14309
13845);
13846						}
13847						if (this.namereg[pkey].ikey[ikey].items.length === 0) {
13848							delete this.namereg[pkey].ikey[ikey];
13849							this.namereg[pkey].count += -1;
13850							if (this.namereg[pkey].count < 2) {
13851								for (i = 0, ilen = this.namereg[pkey].items.length; i < ilen; i += 1) {
13852									state.tmp.taintedItemIDs[this.namereg[pkey].items[i]] = true;
13853								}
13854							}
13855						}
13856					}
13857					if (pkey) {
13858						posB = this.namereg[pkey].items.indexOf("" + id);
13859						if (posB > -1) {
13860							items = this.namereg[pkey].items.slice();
13861							this.namereg[pkey].items = items.slice(0, posB).concat(items.slice([posB + 1], items.length));
13862						}
13863						if (this.namereg[pkey].items.length < 2) {
13864							delete this.namereg[pkey];
13865						}
13866					}
13867					delete this.nameind[id][fullkey];
13868				}
13869			}
13870			delete this.nameind[id];
13871			delete this.nameindpkeys[id];
13872		}
13873		return ret;
13874	};
13875	addname = function (item_id, nameobj, pos) {
13876		var i, ilen;
13877		var res = state.nameOutput.getName(nameobj, "locale-translit", true);
13878		nameobj = res.name;
13879		if (state.citation.opt["givenname-disambiguation-rule"]
13880			&& state.citation.opt["givenname-disambiguation-rule"].slice(0, 8) === "primary-"
13881			&& pos !== 0) {
13882				return;
13883		}
13884		set_keys(this.state, "" + item_id, nameobj);
13885		if (pkey) {
13886			if ("undefined" === typeof this.namereg[pkey]) {
13887				this.namereg[pkey] = {};
13888				this.namereg[pkey].count = 0;
13889				this.namereg[pkey].ikey = {};
13890				this.namereg[pkey].items = [item_id];
13891			} else if (this.namereg[pkey].items.indexOf(item_id) === -1) {
13892				this.namereg[pkey].items.push(item_id);
13893			}
13894		}
13895		if (pkey && ikey) {
13896			if ("undefined" === typeof this.namereg[pkey].ikey[ikey]) {
13897				this.namereg[pkey].ikey[ikey] = {};
13898				this.namereg[pkey].ikey[ikey].count = 0;
13899				this.namereg[pkey].ikey[ikey].skey = {};
13900				this.namereg[pkey].ikey[ikey].items = [item_id];
13901				this.namereg[pkey].count += 1;
13902				if (this.namereg[pkey].count === 2) {
13903					for (i = 0, ilen = this.namereg[pkey].items.length; i < ilen; i += 1) {
13904						state.tmp.taintedItemIDs[this.namereg[pkey].items[i]] = true;
13905					}
13906				}
13907			} else if (this.namereg[pkey].ikey[ikey].items.indexOf(item_id) === -1) {
13908				this.namereg[pkey].ikey[ikey].items.push(item_id);
13909			}
13910		}
13911		if (pkey && ikey && skey) {
13912			if ("undefined" === typeof this.namereg[pkey].ikey[ikey].skey[skey]) {
13913				this.namereg[pkey].ikey[ikey].skey[skey] = {};
13914				this.namereg[pkey].ikey[ikey].skey[skey].items = [item_id];
13915				this.namereg[pkey].ikey[ikey].count += 1;
13916				if (this.namereg[pkey].ikey[ikey].count === 2) {
13917					for (i = 0, ilen = this.namereg[pkey].ikey[ikey].items.length; i < ilen; i += 1) {
13918						state.tmp.taintedItemIDs[this.namereg[pkey].ikey[ikey].items[i]] = true;
13919					}
13920				}
13921			} else if (this.namereg[pkey].ikey[ikey].skey[skey].items.indexOf(item_id) === -1) {
13922				this.namereg[pkey].ikey[ikey].skey[skey].items.push(item_id);
13923			}
13924		}
13925		if ("undefined" === typeof this.nameind[item_id]) {
13926			this.nameind[item_id] = {};
13927			this.nameindpkeys[item_id] = {};
13928		}
13929		if (pkey) {
13930			this.nameind[item_id][pkey + "::" + ikey + "::" + skey] = true;
13931			this.nameindpkeys[item_id][pkey] = this.namereg[pkey];
13932		}
13933	};
13934	this.addname = addname;
13935	this.delitems = delitems;
13936	this.evalname = evalname;
13937};
13938CSL.Registry.CitationReg = function (state) {
13939	this.citationById = {};
13940	this.citationByIndex = [];
13941};
13942CSL.Disambiguation = function (state) {
13943	this.state = state;
13944	this.sys = this.state.sys;
13945	this.registry = state.registry.registry;
13946	this.ambigcites = state.registry.ambigcites;
13947	this.configModes();
13948	this.debug = false;
13949};
13950CSL.Disambiguation.prototype.run = function(akey) {
13951	if (!this.modes.length) {
13952		return;
13953	}
13954	this.akey = akey;
13955	if (this.initVars(akey)) {
13956		this.runDisambig();
13957	}
13958};
13959CSL.Disambiguation.prototype.runDisambig = function () {
13960	var pos, len, ppos, llen, pppos, lllen, ismax;
13961	this.initGivens = true;
13962	while (this.lists.length) {
13963		this.gnameset = 0;
13964		this.gname = 0;
13965		this.clashes = [1, 0];
13966		while(this.lists[0][1].length) {
13967			this.listpos = 0;
13968			if (!this.base) {
13969				this.base = this.lists[0][0];
13970			}
13971			var names_used = [];
13972			ismax = this.incrementDisambig();
13973			this.scanItems(this.lists[0]);
13974			this.evalScan(ismax);
13975		}
13976		this.lists = this.lists.slice(1);
13977	}
13978};
13979CSL.Disambiguation.prototype.scanItems = function (list) {
13980	var pos, len, Item, otherItem, ItemCite, ignore, base;
13981	this.Item = list[1][0];
13982	this.ItemCite = CSL.getAmbiguousCite.call(this.state, this.Item, this.base, true);
13983	this.scanlist = list[1];
13984	this.partners = [];
13985	this.partners.push(this.Item);
13986	this.nonpartners = [];
13987	var clashes = 0;
13988	for (pos = 1, len = list[1].length; pos < len; pos += 1) {
13989		otherItem = list[1][pos];
13990		var otherItemCite = CSL.getAmbiguousCite.call(this.state, otherItem, this.base, true);
13991		if (this.ItemCite === otherItemCite) {
13992			clashes += 1;
13993			this.partners.push(otherItem);
13994		} else {
13995			this.nonpartners.push(otherItem);
13996		}
13997	}
13998	this.clashes[0] = this.clashes[1];
13999	this.clashes[1] = clashes;
14000};
14001CSL.Disambiguation.prototype.evalScan = function (maxed) {
14002	this[this.modes[this.modeindex]](maxed);
14003	if (maxed) {
14004		if (this.modeindex < this.modes.length - 1) {
14005			this.modeindex += 1;
14006		} else {
14007			this.lists[this.listpos + 1] = [this.base, []];
14008		}
14009	}
14010};
14011CSL.Disambiguation.prototype.disNames = function (ismax) {
14012	var pos, len, mybase, i, ilen;
14013	if (this.clashes[1] === 0 && this.nonpartners.length === 1) {
14014		this.captureStepToBase();
14015		this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.betterbase);
14016		this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, this.betterbase);
14017		this.lists[this.listpos] = [this.betterbase, []];
14018	} else if (this.clashes[1] === 0) {
14019		this.captureStepToBase();
14020		this.state.registry.registerAmbigToken(this.akey, "" + this.partners[0].id, this.betterbase);
14021		this.lists[this.listpos] = [this.betterbase, this.nonpartners];
14022		if (this.nonpartners.length) {
14023			this.initGivens = true;
14024		}
14025	} else if (this.nonpartners.length === 1) {
14026		this.captureStepToBase();
14027		this.state.registry.registerAmbigToken(this.akey, "" + this.nonpartners[0].id, this.betterbase);
14028		this.lists[this.listpos] = [this.betterbase, this.partners];
14029	} else if (this.clashes[1] < this.clashes[0]) {
14030		this.captureStepToBase();
14031		this.lists[this.listpos] = [this.betterbase, this.partners];
14032		this.lists.push([this.betterbase, this.nonpartners]);
14033	} else {
14034		if (ismax) {
14035			this.lists[this.listpos] = [this.betterbase, this.nonpartners];
14036			this.lists.push([this.betterbase, this.partners]);
14037			if (this.modeindex === this.modes.length - 1) {
14038				for (i = 0, ilen = this.partners.length; i < ilen; i += 1) {
14039					this.state.registry.registerAmbigToken(this.akey, "" + this.partners[i].id, this.betterbase);
14040				}
14041				this.lists[this.listpos] = [this.betterbase, []];
14042			}
14043		}
14044	}
14045};
14046CSL.Disambiguation.prototype.disExtraText = function () {
14047	var pos, len, mybase;
14048	var done = false;
14049	if (this.clashes[1] === 0 && this.nonpartners.length < 2) {
14050		done = true;
14051	}
14052	if (!done && (!this.base.disambiguate || this.state.tmp.disambiguate_count !== this.state.tmp.disambiguate_maxMax)) {
14053		this.modeindex = 0;
14054		this.base.disambiguate = this.state.tmp.disambiguate_count;
14055		this.betterbase.disambiguate = this.state.tmp.disambiguate_count;
14056		if (!this.base.disambiguate) {
14057			this.initGivens = true;
14058			this.base.disambiguate = 1;
14059			for (var i = 0, ilen = this.lists[this.listpos][1].length; i < ilen; i += 1) {
14060				this.state.tmp.taintedItemIDs[this.lists[this.listpos][1][i].id] = true;
14061			}
14062		} else {
14063			this.disNames();
14064		}
14065	} else if (done || this.state.tmp.disambiguate_count === this.state.tmp.disambiguate_maxMax) {
14066		if (done || this.modeindex === this.modes.length - 1) {
14067			var base = this.lists[this.listpos][0];
14068			for (var i = 0, ilen = this.lists[this.listpos][1].length; i < ilen; i += 1) {
14069				this.state.tmp.taintedItemIDs[this.lists[this.listpos][1][i].id] = true;
14070				this.state.registry.registerAmbigToken(this.akey, "" + this.lists[this.listpos][1][i].id, base);
14071			}
14072			this.lists[this.listpos] = [this.betterbase, []];
14073		} else {
14074			this.modeindex = this.modes.length - 1;
14075			var base = this.lists[this.listpos][0];
14076			base.disambiguate = true;
14077			for (var i = 0, ilen = this.lists[this.listpos][1].length; i < ilen; i += 1) {
14078				this.state.tmp.taintedItemIDs[this.lists[this.listpos][1][i].id] = true;
14079				this.state.registry.registerAmbigToken(this.akey, "" + this.lists[this.listpos][1][i].id, base);
14080			}
14081		}
14082	}
14083};
14084CSL.Disambiguation.prototype.disYears = function () {
14085	var pos, len, tokens, token, item;
14086	tokens = [];
14087	var base = this.lists[this.listpos][0];
14088	if (this.clashes[1]) {
14089		for (var i = 0, ilen = this.state.registry.mylist.length; i < ilen; i += 1) {
14090			var origid = this.state.registry.mylist[i];
14091			for (var j = 0, jlen = this.lists[this.listpos][1].length; j < jlen; j += 1) {
14092				var token = this.lists[this.listpos][1][j];
14093				if (token.id == origid) {
14094					tokens.push(this.registry[token.id]);
14095					break;
14096				}
14097			}
14098		}
14099	}
14100	tokens.sort(this.state.registry.sorter.compareKeys);
14101	for (pos = 0, len = tokens.length; pos < len; pos += 1) {
14102		base.year_suffix = ""+pos;
14103		var oldBase = this.state.registry.registry[tokens[pos].id].disambig;
14104		this.state.registry.registerAmbigToken(this.akey, "" + tokens[pos].id, base);
14105		if (CSL.ambigConfigDiff(oldBase,base)) {
14106			this.state.tmp.taintedItemIDs[tokens[pos].id] = true;
14107		}
14108	}
14109	this.lists[this.listpos] = [this.betterbase, []];
14110};
14111CSL.Disambiguation.prototype.incrementDisambig = function () {
14112	var val;
14113	if (this.initGivens) {
14114		this.initGivens = false;
14115		return false;
14116	}
14117	var maxed = false;
14118	var increment_names = true;
14119	var increment_givens = true;
14120	if ("disNames" === this.modes[this.modeindex]) {
14121		increment_names = false;
14122		if ("number" !== typeof this.givensMax) {
14123			increment_names = true;
14124		}
14125		var increment_namesets = false;
14126		if ("number" !== typeof this.namesMax) {
14127			increment_namesets = true;
14128		}
14129		if ("number" === typeof this.givensMax) {
14130			if (this.base.givens.length && this.base.givens[this.gnameset][this.gname] < this.givensMax) {
14131				this.base.givens[this.gnameset][this.gname] += 1;
14132			} else {
14133				increment_names = true;
14134			}
14135		}
14136		if ("number" === typeof this.namesMax
14137			&& increment_names) {
14138			if (this.state.opt["disambiguate-add-names"]) {
14139				increment_namesets = false;
14140				if (this.gname < this.namesMax) {
14141					this.base.names[this.gnameset] += 1;
14142					this.gname += 1;
14143				} else {
14144					increment_namesets = true;
14145				}
14146			} else {
14147				increment_namesets = true;
14148			}
14149		}
14150		if ("number" === typeof this.namesetsMax && increment_namesets) {
14151			if (this.gnameset < this.namesetsMax) {
14152				this.gnameset += 1;
14153				this.base.names[this.gnameset] = 1;
14154				this.gname = 0;
14155			} else {
14156				var increment_mode = true;
14157			}
14158		}
14159		if (("number" !== typeof this.namesetsMax || this.namesetsMax === -1 || this.gnameset === this.namesetsMax)
14160			&& (!this.state.opt["disambiguate-add-names"] || "number" !== typeof this.namesMax || this.gname === this.namesMax)
14161			&& ("number" != typeof this.givensMax || "undefined" === typeof this.base.givens[this.gnameset] || "undefined" === typeof this.base.givens[this.gnameset][this.gname] || this.base.givens[this.gnameset][this.gname] === this.givensMax)) {
14162			maxed = true;
14163		}
14164	} else if ("disExtraText" === this.modes[this.modeindex]) {
14165		this.base.disambiguate += 1;
14166		this.betterbase.disambiguate += 1;
14167	}
14168	return maxed;
14169};
14170CSL.Disambiguation.prototype.initVars = function (akey) {
14171	var i, ilen, myIds, myItemBundles, myItems;
14172	this.lists = [];
14173	this.base = false;
14174	this.betterbase = false;
14175	this.akey = akey;
14176	this.maxNamesByItemId = {};
14177	myItemBundles = [];
14178	myIds = this.ambigcites[akey];
14179	if (!myIds || !myIds.length) {
14180		return false;
14181	}
14182	var Item = false;
14183	var myItem = this.state.retrieveItem("" + myIds[0]);
14184	this.getCiteData(myItem);
14185	this.base = CSL.getAmbigConfig.call(this.state);
14186	if (myIds && myIds.length > 1) {
14187		myItemBundles.push([this.maxNamesByItemId[myItem.id], myItem]);
14188		for (i = 1, ilen = myIds.length; i < ilen; i += 1) {
14189			myItem = this.state.retrieveItem("" + myIds[i]);
14190			this.getCiteData(myItem, this.base);
14191			myItemBundles.push([this.maxNamesByItemId[myItem.id], myItem]);
14192		}
14193		myItemBundles.sort(
14194			function (a, b) {
14195				if (a[0] > b[0]) {
14196					return 1;
14197				} else if (a[0] < b[0]) {
14198					return -1;
14199				} else {
14200					if (a[1].id > b[1].id) {
14201						return 1;
14202					} else if (a[1].id < b[1].id) {
14203						return -1;
14204					} else {
14205						return 0;
14206					}
14207				}
14208			}
14209		);
14210		myItems = [];
14211		for (i = 0, ilen = myItemBundles.length; i < ilen; i += 1) {
14212			myItems.push(myItemBundles[i][1]);
14213		}
14214		this.lists.push([this.base, myItems]);
14215		this.Item = this.lists[0][1][0];
14216	} else {
14217		this.Item = this.state.retrieveItem("" + myIds[0]);
14218	}
14219	this.modeindex = 0;
14220	if (this.state.citation.opt["disambiguate-add-names"] || true) {
14221		this.namesMax = this.maxNamesByItemId[this.Item.id][0];
14222	} else {
14223		var namesMax = this.base.names[0];
14224		for (var i=1,ilen=this.base.names.length;i<ilen;i+=1){
14225			namesMax = Math.max(namesMax,this.base.names.names[i]);
14226		}
14227	}
14228	this.padBase(this.base);
14229	this.padBase(this.betterbase);
14230	this.base.year_suffix = false;
14231	this.base.disambiguate = false;
14232	this.betterbase.year_suffix = false;
14233	this.betterbase.disambiguate = false;
14234	if (this.state.citation.opt["givenname-disambiguation-rule"] === "by-cite"
14235		 && this.state.opt["disambiguate-add-givenname"]) {
14236		this.givensMax = 2;
14237	}
14238	return true;
14239};
14240CSL.Disambiguation.prototype.padBase = function (base) {
14241	for (var i = 0, ilen = base.names.length; i < ilen; i += 1) {
14242		if (!base.givens[i]) {
14243			base.givens[i] = [];
14244		}
14245		for (var j=0,jlen=base.names[i];j<jlen;j+=1) {
14246			if (!base.givens[i][j]) {
14247				base.givens[i][j] = 0;
14248			}
14249		}
14250	}
14251}
14252CSL.Disambiguation.prototype.configModes = function () {
14253	var dagopt, gdropt;
14254	this.modes = [];
14255	dagopt = this.state.opt["disambiguate-add-givenname"];
14256	gdropt = this.state.citation.opt["givenname-disambiguation-rule"];
14257	if (this.state.opt['disambiguate-add-names'] || (dagopt && gdropt === "by-cite")) {
14258		this.modes.push("disNames");
14259	}
14260	if (this.state.opt.has_disambiguate) {
14261		this.modes.push("disExtraText");
14262	}
14263	if (this.state.opt["disambiguate-add-year-suffix"]) {
14264		this.modes.push("disYears");
14265	}
14266};
14267CSL.Disambiguation.prototype.getCiteData = function(Item, base) {
14268	if (!this.maxNamesByItemId[Item.id]) {
14269		CSL.getAmbiguousCite.call(this.state, Item, base);
14270		base = CSL.getAmbigConfig.call(this.state);
14271		this.maxNamesByItemId[Item.id] = CSL.getMaxVals.call(this.state);
14272		this.state.registry.registry[Item.id].disambig.givens = this.state.tmp.disambig_settings.givens.slice();
14273		for (var i=0,ilen=this.state.registry.registry[Item.id].disambig.givens.length;i<ilen;i+=1) {
14274			this.state.registry.registry[Item.id].disambig.givens[i] = this.state.tmp.disambig_settings.givens[i].slice();
14275		}
14276		this.namesetsMax = this.state.registry.registry[Item.id].disambig.names.length - 1;
14277		if (!this.base) {
14278			this.base = base;
14279			this.betterbase = CSL.cloneAmbigConfig(base);
14280		}
14281		if (base.names.length < this.base.names.length) {
14282			this.base = base;
14283		}
14284		var update = false;
14285		for (var i = 0, ilen = base.names.length; i < ilen; i += 1) {
14286			if (base.names[i] > this.base.names[i]) {
14287				this.base.givens[i] = base.givens[i].slice();
14288				this.base.names[i] = base.names[i];
14289				this.betterbase.names = this.base.names.slice();
14290				this.betterbase.givens = this.base.givens.slice();
14291				this.padBase(this.base);
14292				this.padBase(this.betterbase);
14293			}
14294		}
14295		this.betterbase.givens = this.base.givens.slice();
14296		for (var j = 0, jlen = this.base.givens.length; j < jlen; j += 1) {
14297			this.betterbase.givens[j] = this.base.givens[j].slice();
14298		}
14299	}
14300};
14301CSL.Disambiguation.prototype.captureStepToBase = function() {
14302	if (this.state.citation.opt["givenname-disambiguation-rule"] === "by-cite"
14303		&& this.base.givens && this.base.givens.length) {
14304		if ("undefined" !== typeof this.base.givens[this.gnameset][this.gname]) {
14305			this.betterbase.givens[this.gnameset][this.gname] = this.base.givens[this.gnameset][this.gname];
14306		}
14307	}
14308	this.betterbase.names[this.gnameset] = this.base.names[this.gnameset];
14309};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.