]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/marcrecord.js
webstaff: fix bug in MARC21.Field.deleteSubfield()
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / marcrecord.js
1 /* ---------------------------------------------------------------------------
2  * Copyright (C) 2009-2015  Equinox Software, Inc.
3  * Mike Rylander <miker@esilibrary.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * ---------------------------------------------------------------------------
15  */
16
17 // !!! Head's up !!!
18 // This module requires a /real/ jQuery be used with your
19 // angularjs, so as to avoid using hand-rolled AJAX.
20
21 var MARC21 = {
22
23     Record : function(kwargs) {
24         if (!kwargs) kwargs = {};
25
26         this.generate008 = function () {
27             var f;
28             var s;
29             var orig008 = '                                        ';
30             var now = new Date();
31             var y = now.getUTCFullYear().toString().substr(2,2);
32             var m = now.getUTCMonth() + 1;
33             if (m < 10) m = '0' + m;
34             var d = now.getUTCDate();
35             if (d < 10) d = '0' + d;
36
37
38             if (f = this.field('008',true)[0]) {
39                 orig008 = f.data;
40             }
41         
42             /* lang code from 041a */
43             var lang = orig008.substr(35, 3);
44             
45             if (f = this.field('041',true)[0]) {
46                 if (s = f.subfield('a',true)[0]) {
47                     if(s[1]) lang = s[1];
48                 }
49             }
50         
51             /* country code from 044a */
52             var country = orig008.substr(15, 3);
53             if (f = this.field('044',true)[0]) {
54                 if (s = f.subfield('a',true)[0]) {
55                     if(s[1]) country = s[1];
56                 }
57             }
58             while (country.length < 3) country = country + ' ';
59             if (country.length > 3) country = country.substr(0,3);
60         
61             /* date1 from 260c */
62             var date1 = now.getUTCFullYear().toString();
63             if (f = this.field('260',true)[0]) {
64                 if (s = f.subfield('c',true)[0]) {
65                     if (s[1]) {
66                         var tmpd = s[1];
67                         tmpd = tmpd.replace(/[^0-9]/g, '');
68                         if (tmpd.match(/^\d\d\d\d/)) {
69                             date1 = tmpd.substr(0, 4);
70                         }
71                     }
72                 }
73             }
74         
75             var date2 = orig008.substr(11, 4);
76             var datetype = orig008.substr(6, 1);
77             var modded = orig008.substr(38, 1);
78             var catsrc = orig008.substr(39, 1);
79         
80             return '' + y + m + d + datetype + date1 + date2 + country + '                 ' + lang + modded + catsrc;
81         
82         }
83
84         this.title = function () { return this.subfield('245','a')[1] }
85
86         this.field = function (spec, wantarray) {
87             var list = this.fields.filter(function (f) {
88                 if (f.tag.match(spec)) return true;
89                 return false;
90             });
91
92             if (!wantarray && list.length == 1) return list[0];
93             return list;
94         }
95
96         this.subfield = function (spec, code) {
97             var f = this.field(spec, true)[0];
98             if (f) return f.subfield(code)
99             return null;
100         }
101
102         this.appendFields = function () {
103             var me = this;
104             Array.prototype.slice.call(arguments).forEach( function (f) { f.position = me.fields.length; me.fields.push( f ) } );
105         }
106
107         this.deleteField = function (f) { return this.deleteFields(f) },
108
109         this.insertOrderedFields = function () {
110             var me = this;
111             for (var i = 0; i < arguments.length; i++) {
112                 var f = arguments[i];
113                 var done = false;
114                 for (var j = 0; j < this.fields.length; j++) {
115                     if (f.tag < this.fields[j].tag) {
116                         this.insertFieldsBefore(this.fields[j], f);
117                         done = true;
118                         break;
119                     }
120                 }
121                 if (!done) this.appendFields(f);
122             }
123         }
124
125         this.insertFieldsBefore = function (target) {
126             var args = Array.prototype.slice.call(arguments);
127             args.splice(0,1);
128             var me = this;
129             for (var j = 0; j < this.fields.length; j++) {
130                 if (target === this.fields[j]) {
131                     args.forEach( function (f) {
132                         f.record = me;
133                         me.fields.splice(j++,0,f);
134                     });
135                     break;
136                 }
137             }
138             for (var j = 0; j < this.fields.length; j++) {
139                 this.fields[j].position = j;
140             }
141         }
142
143         this.insertFieldsAfter = function (target) {
144             var args = Array.prototype.slice.call(arguments);
145             args.splice(0,1);
146             var me = this;
147             for (var j = 0; j < this.fields.length; j++) {
148                 if (target === this.fields[j]) {
149                     args.forEach( function (f) {
150                         f.record = me;
151                         me.fields.splice(++j,0,f);
152                     });
153                     break;
154                 }
155             }
156             for (var j = 0; j < this.fields.length; j++) {
157                 this.fields[j].position = j;
158             }
159         }
160
161         this.deleteFields = function () {
162             var me = this;
163             var counter = 0;
164             for ( var i in arguments ) {
165                 var f = arguments[i];
166                 for (var j = 0; j < me.fields.length; j++) {
167                     if (f === me.fields[j]) {
168                         me.fields[j].record = null;
169                         me.fields.splice(j,1);
170                         counter++
171                         break;
172                     }
173                 }
174             }
175             for (var j = 0; j < this.fields.length; j++) {
176                 this.fields[j].position = j;
177             }
178             return counter;
179         }
180
181         // this.clone = function () { return dojo.clone(this) } // maybe implement later...
182
183         this.fromXmlURL = function (url) {
184             var me = this;
185             return $.get( // This is a Promise
186                 url,
187                 function (mxml) {
188                     me.fromXmlDocument($('record', mxml)[0]);
189                     if (me.onLoad) me.onLoad();
190             });
191         }
192
193         this.fromXmlString = function (mxml) {
194                 this.fromXmlDocument( $( $.parseXML( mxml ) ).find('record')[0] );
195         }
196
197         this.fromXmlDocument = function (mxml) {
198             var me = this;
199             me.leader = $($('leader',mxml)[0]).text() || '00000cam a2200205Ka 4500';
200
201             $('controlfield', mxml).each(function (ind) {
202                 var cf=$(this);
203                 me.fields.push(
204                     new MARC21.Field({
205                           record : me,
206                           tag    : cf.attr('tag'),
207                           data   : cf.text(),
208                     })
209                 )
210             });
211
212             $('datafield', mxml).each(function (ind) {
213                 var df=$(this);
214                 me.fields.push(
215                     new MARC21.Field({
216                         record    : me,
217                         tag       : df.attr('tag'),
218                         ind1      : df.attr('ind1'),
219                         ind2      : df.attr('ind2'),
220                         subfields : $('subfield', df).map(
221                             function (i, sf) {
222                                 return [[ $(sf).attr('code'), $(sf).text(), i ]];
223                             }
224                         ).get()
225                     })
226                 )
227             });
228
229             for (var j = 0; j < this.fields.length; j++) {
230                 this.fields[j].position = j;
231             }
232
233             me.ready = true;
234
235         }
236
237         this.toXmlDocument = function () {
238
239             var doc = $.parseXML('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
240             var rec_node = $('record', doc)[0];
241
242             var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
243             ldr.textContent = this.leader;
244             rec_node.appendChild( ldr );
245
246             this.fields.forEach(function (f) {
247                 var element = f.isControlfield() ? 'controlfield' : 'datafield';
248                 var f_node = doc.createElementNS( 'http://www.loc.gov/MARC21/slim', element );
249                 f_node.setAttribute('tag', f.tag);
250                 
251                 if (f.isControlfield()) {
252                     if (f.data) f_node.textContent = f.data;
253                 } else {
254                     f_node.setAttribute('ind1', f.indicator(1));
255                     f_node.setAttribute('ind2', f.indicator(2));
256                     f.subfields.forEach( function (sf) {
257                         var sf_node = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'subfield');
258                         sf_node.setAttribute('code', sf[0]);
259                         sf_node.textContent = sf[1];
260                         f_node.appendChild(sf_node);
261                     });
262                 }
263
264                 rec_node.appendChild(f_node);
265             });
266
267             return doc;
268         }
269
270         this.toXmlString = function () {
271             return (new XMLSerializer()).serializeToString( this.toXmlDocument() );
272         }
273
274         this.fromBreaker = function (marctxt) {
275             var me = this;
276
277             function cf_line_data (l) { return l.substring(4) || '' };
278             function df_line_data (l) { return l.substring(6) || '' };
279             function line_tag (l) { return l.substring(0,3) };
280             function df_ind1 (l) { return l.substring(4,5).replace('\\',' ') };
281             function df_ind2 (l) { return l.substring(5,6).replace('\\',' ') };
282             function isControlField (l) {
283                 var x = line_tag(l);
284                 return (x == 'LDR' || x < '010') ? true : false;
285             }
286             
287             var lines = marctxt.replace(/^=/gm,'').split('\n');
288             lines.forEach(function (current_line, ind) {
289
290                 if (current_line.match(/^#/)) {
291                     // skip comment lines
292                 } else if (isControlField(current_line)) {
293                     if (line_tag(current_line) == 'LDR') {
294                         me.leader = cf_line_data(current_line) || '00000cam a2200205Ka 4500';
295                     } else {
296                         me.fields.push(
297                             new MARC21.Field({
298                                 record : me,
299                                 tag    : line_tag(current_line),
300                                 data   : cf_line_data(current_line).replace('\\',' ','g'),
301                             })
302                         );
303                     }
304                 } else {
305                     if (current_line.substring(4,5) == me.delimiter) // add delimiters if they were left out
306                         current_line = current_line.substring(0,3) + ' \\\\' + current_line.substring(4);
307
308                     var data = df_line_data(current_line);
309                     if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
310
311                     var sf_list = data.split(me.delimiter);
312                     sf_list.shift();
313
314                     me.fields.push(
315                         new MARC21.Field({
316                                 record    : me,
317                                 tag       : line_tag(current_line),
318                                 ind1      : df_ind1(current_line),
319                                 ind2      : df_ind2(current_line),
320                                 subfields : sf_list.map( function (sf, i) {
321                                                 var sf_data = sf.substring(1);
322                                                 if (me.delimiter == '$') sf_data = sf_data.replace(/\{dollar\}/g, '$');
323                                                 return [ sf.substring(0,1), sf_data, i ];
324                                             })
325                         })
326                     );
327                 }
328             });
329
330             for (var j = 0; j < this.fields.length; j++) {
331                 this.fields[j].position = j;
332             }
333
334             me.ready = true;
335             return this;
336         }
337
338         this.toBreaker = function () {
339
340             var me = this;
341             var mtxt = '=LDR ' + this.leader + '\n';
342
343             mtxt += this.fields.map( function (f) {
344                 if (f.isControlfield()) {
345                     if (f.data) return '=' + f.tag + ' ' + f.data.replace(' ','\\','g');
346                     return '=' + f.tag;
347                 } else {
348                     return '=' + f.tag + ' ' +
349                         f.indicator(1).replace(' ','\\') + 
350                         f.indicator(2).replace(' ','\\') + 
351                         f.subfields.map( function (sf) {
352                             var sf_data = sf[1];
353                             if (me.delimiter == '$') sf_data = sf_data.replace(/\$/g, '{dollar}');
354                             return me.delimiter + sf[0] + sf_data;
355                         }).join('');
356                 }
357             }).join('\n');
358
359             return mtxt;
360         }
361
362         this.recordType = function () {
363         
364             var _t = this.leader.substr(MARC21.Record._ff_pos.Type.ldr.BKS.start, MARC21.Record._ff_pos.Type.ldr.BKS.len);
365             var _b = this.leader.substr(MARC21.Record._ff_pos.BLvl.ldr.BKS.start, MARC21.Record._ff_pos.BLvl.ldr.BKS.len);
366         
367             for (var t in MARC21.Record._recType) {
368                 if (_t.match(MARC21.Record._recType[t].Type) && _b.match(MARC21.Record._recType[t].BLvl)) {
369                     return t;
370                 }
371             }
372             return 'BKS'; // default
373         }
374         
375         this.videorecordingFormatName = function () {
376             var _7 = this.field('007').data;
377         
378             if (_7 && _7.match(/^v/)) {
379                 var _v_e = _7.substr(
380                     MARC21.Record._physical_characteristics.v.subfields.e.start,
381                     MARC21.Record._physical_characteristics.v.subfields.e.len
382                 );
383         
384                 return MARC21.Record._physical_characteristics.v.subfields.e.values[ _v_e ];
385             }
386         
387             return null;
388         }
389         
390         this.videorecordingFormatCode = function () {
391             var _7 = this.field('007').data;
392         
393             if (_7 && _7.match(/^v/)) {
394                 return _7.substr(
395                     MARC21.Record._physical_characteristics.v.subfields.e.start,
396                     MARC21.Record._physical_characteristics.v.subfields.e.len
397                 );
398             }
399         
400             return null;
401         }
402         
403         this.extractFixedField = function (field, dflt) {
404         if (!MARC21.Record._ff_pos[field]) return null;
405         
406             var _l = this.leader;
407             var _8 = this.field('008').data;
408             var _6 = this.field('006').data;
409         
410             var rtype = this.recordType();
411         
412             var val;
413         
414             if (MARC21.Record._ff_pos[field].ldr && _l) {
415                 if (MARC21.Record._ff_pos[field].ldr[rtype]) {
416                     val = _l.substr(
417                         MARC21.Record._ff_pos[field].ldr[rtype].start,
418                         MARC21.Record._ff_pos[field].ldr[rtype].len
419                     );
420                 }
421             } else if (MARC21.Record._ff_pos[field]._8 && _8) {
422                 if (MARC21.Record._ff_pos[field]._8[rtype]) {
423                     val = _8.substr(
424                         MARC21.Record._ff_pos[field]._8[rtype].start,
425                         MARC21.Record._ff_pos[field]._8[rtype].len
426                     );
427                 }
428             }
429         
430             if (!val && MARC21.Record._ff_pos[field]._6 && _6) {
431                 if (MARC21.Record._ff_pos[field]._6[rtype]) {
432                     val = _6.substr(
433                         MARC21.Record._ff_pos[field]._6[rtype].start,
434                         MARC21.Record._ff_pos[field]._6[rtype].len
435                     );
436                 }
437             }
438     
439             if (!val && dflt) {
440                 val = '';
441                 var d;
442                 var p;
443                 if (MARC21.Record._ff_pos[field].ldr && MARC21.Record._ff_pos[field].ldr[rtype]) {
444                     d = MARC21.Record._ff_pos[field].ldr[rtype].def;
445                     p = 'ldr';
446                 }
447     
448                 if (MARC21.Record._ff_pos[field]._8 && MARC21.Record._ff_pos[field]._8[rtype]) {
449                     d = MARC21.Record._ff_pos[field]._8[rtype].def;
450                     p = '_8';
451                 }
452     
453                 if (!val && MARC21.Record._ff_pos[field]._6 && MARC21.Record._ff_pos[field]._6[rtype]) {
454                     d = MARC21.Record._ff_pos[field]._6[rtype].def;
455                     p = '_6';
456                 }
457     
458                 if (p) {
459                     for (var j = 0; j < MARC21.Record._ff_pos[field][p][rtype].len; j++) {
460                         val += d;
461                     }
462                 } else {
463                     val = null;
464                 }
465             }
466     
467             return val;
468         }
469     
470         this.setFixedField = function (field, value) {
471             if (!MARC21.Record._ff_pos[field]) return null;
472         
473             var _l = this.leader;
474             var _8 = this.field('008').data;
475             var _6 = this.field('006').data;
476         
477             var rtype = this.recordType();
478         
479             var done = false;
480             if (MARC21.Record._ff_pos[field].ldr && _l) {
481                 if (MARC21.Record._ff_pos[field].ldr[rtype]) { // It's in the leader
482                     if (value.length > MARC21.Record._ff_pos[field].ldr[rtype].len)
483                         value = value.substr(0, MARC21.Record._ff_pos[field].ldr[rtype].len);
484                     while (value.length < MARC21.Record._ff_pos[field].ldr[rtype].len)
485                         value += MARC21.Record._ff_pos[field].ldr[rtype].def;
486                     this.leader =
487                         _l.substring(0, MARC21.Record._ff_pos[field].ldr[rtype].start) +
488                         value +
489                         _l.substring(
490                             MARC21.Record._ff_pos[field].ldr[rtype].start
491                             + MARC21.Record._ff_pos[field].ldr[rtype].len
492                         );
493                     done = true;
494                 }
495             } else if (MARC21.Record._ff_pos[field]._8 && _8) {
496                 if (MARC21.Record._ff_pos[field]._8[rtype]) { // Nope, it's in the 008
497                     if (value.length > MARC21.Record._ff_pos[field]._8[rtype].len)
498                         value = value.substr(0, MARC21.Record._ff_pos[field]._8[rtype].len);
499                     while (value.length < MARC21.Record._ff_pos[field]._8[rtype].len)
500                         value += MARC21.Record._ff_pos[field]._8[rtype].def;
501                     this.field('008').update(
502                         _8.substring(0, MARC21.Record._ff_pos[field]._8[rtype].start) +
503                         value +
504                         _8.substring(
505                             MARC21.Record._ff_pos[field]._8[rtype].start
506                             + MARC21.Record._ff_pos[field]._8[rtype].len
507                         )
508                     );
509                     done = true;
510                 }
511             }
512         
513             if (!done && MARC21.Record._ff_pos[field]._6 && _6) {
514                 if (MARC21.Record._ff_pos[field]._6[rtype]) { // ok, maybe the 006?
515                     if (value.length > MARC21.Record._ff_pos[field]._6[rtype].len)
516                         value = value.substr(0, MARC21.Record._ff_pos[field]._6[rtype].len);
517                     while (value.length < MARC21.Record._ff_pos[field]._6[rtype].len)
518                         value += MARC21.Record._ff_pos[field]._6[rtype].def;
519                     this.field('006').update(
520                         _6.substring(0, MARC21.Record._ff_pos[field]._6[rtype].start) +
521                         value +
522                         _6.substring(
523                             MARC21.Record._ff_pos[field]._6[rtype].start
524                             + MARC21.Record._ff_pos[field]._6[rtype].len
525                         )
526                     );
527                 }
528             }
529     
530             return value;
531         }
532
533         this.ready = false;
534         this.fields = [];
535         this.delimiter = MARC21.Record.delimiter ? MARC21.Record.delimiter : '\u2021';
536         this.leader = '00000cam a2200205Ka 4500';
537
538         if (kwargs.delimiter) this.delimiter = kwargs.delimiter;
539         if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
540
541         if (kwargs.url) {
542             this.fromXmlURL(kwargs.url);
543         } else if (kwargs.marcxml) {
544             this.fromXmlString(kwargs.marcxml);
545             if (this.onLoad) this.onLoad();
546         } else if (kwargs.xml) {
547             this.fromXmlDocument(kwargs.xml);
548             if (this.onLoad) this.onLoad();
549         } else if (kwargs.marcbreaker) {
550             this.fromBreaker(kwargs.marcbreaker);
551             if (this.onLoad) this.onLoad();
552         }
553
554         if (kwargs.rtype == 'AUT') {
555             this.setFixedField('Type','z');
556         }
557
558     },
559
560     Field : function (kwargs) {
561         if (!kwargs) kwargs = {};
562
563         this.subfield = function (code, wantarray) {
564             var list = this.subfields.filter( function (s) {
565                 if (s[0] == code) return true; return false;
566             });
567             if (!wantarray && list.length == 1) return list[0];
568             return list;
569         }
570
571         this.addSubfields = function () {
572             for (var i = 0; i < arguments.length; i++) {
573                 var code = arguments[i];
574                 var value = arguments[++i];
575                 this.subfields.push( [ code, value ] );
576             }
577         }
578
579         this.deleteExactSubfields = function () {
580             var me = this;
581             var counter = 0;
582             var done = false;
583             for ( var i in arguments ) {
584                 var f = arguments[i];
585                 for (var j = 0; j < me.subfields.length; j++) {
586                     if (f === me.subfields[j]) {
587                         me.subfields.splice(j,1);
588                         counter++
589                         j++;
590                         done = true;
591                     }
592                     if (done && me.subfields[j])
593                         me.subfields[j][2] -= 1;
594                 }
595             }
596             return counter;
597         }
598
599
600         this.deleteSubfields = function (c) {
601             return this.deleteSubfield( { code : c } );
602         }
603
604         this.deleteSubfield = function (args) {
605             var me = this;
606             if (!Array.isArray( args.code )) {
607                 args.code = [ args.code ];
608             }
609
610             if (args.pos && !Array.isArray( args.pos )) {
611                 args.pos = [ args.pos ];
612             }
613
614             for (var i = 0; i < args.code.length; i++) {
615                 var sub_pos = {};
616                 for (var j = 0; j < me.subfields.length; j++) {
617                     if (me.subfields[j][0] == args.code[i]) {
618
619                         if (!sub_pos[args.code[i]]) sub_pos[args.code[j]] = 0;
620                         else sub_pos[args.code[i]]++;
621
622                         if (args.pos) {
623                             for (var k = 0; k < args.pos.length; k++) {
624                                 if (sub_pos[args.code[i]] == args.pos[k]) me.subfields.splice(j,1);
625                             }
626                         } else if (args.match && me.subfields[j][1].match( args.match )) {
627                             me.subfields.splice(j,1);
628                         } else {
629                             me.subfields.splice(j,1);
630                         }
631                     }
632                 }
633             }
634         }
635
636         this.update = function ( args ) {
637             if (this.isControlfield()) {
638                 this.data = args;
639             } else {
640                 if (args.ind1) this.ind1 = args.ind1;
641                 if (args.ind2) this.ind2 = args.ind2;
642                 if (args.tag) this.tag = args.tag;
643
644                 for (var i in args) {
645                     if (i == 'tag' || i == 'ind1' || i == 'ind2') continue;
646                     var done = 0;
647                     this.subfields.forEach( function (f) {
648                         if (!done && f[0] == i) {
649                             f[1] = args[i];
650                             done = 1;
651                         }
652                     });
653                 }
654             }
655         }
656
657         this.isControlfield = function () {
658             return this.tag < '010' ? true : false;
659         }
660
661         this.indicator = function (num, value) {
662             if (value !== undefined) {
663                 if (num == 1) this.ind1 = value;
664                 else if (num == 2) this.ind2 = value;
665                 else { this.error = true; return null; }
666             }
667             if (num == 1) return this.ind1;
668             else if (num == 2) return this.ind2;
669             else { this.error = true; return null; }
670         }
671
672         this.error = false; 
673         this.record = null; // MARC record pointer
674         this.tag = ''; // MARC tag
675         this.ind1 = ' '; // MARC indicator 1
676         this.ind2 = ' '; // MARC indicator 2
677         this.data = ''; // MARC data for a controlfield element
678         this.subfields = []; // list of MARC subfields for a datafield element
679
680         this.position = kwargs.position;
681         this.record = kwargs.record;
682         this.tag = kwargs.tag;
683         this.ind1 = kwargs.ind1 || ' ';
684         this.ind2 = kwargs.ind2 || ' ';
685         this.data = kwargs.data;
686
687         if (kwargs.subfields) this.subfields = kwargs.subfields;
688         else this.subfields = [];
689
690     },
691
692     Batch : function(kwargs) {
693
694         this.parse = function () {
695             if (this.source instanceof Object ) { // assume an xml collection document
696                 this.source = $('record', this.source);
697                 this.type = 'xml';
698             } else if (this.source.match(/^\s*</)) { // this is xml text
699                 this.source = $.parseXML( mxml ).find('record');
700                 this.type = 'xml';
701             } else { // must be a marcbreaker doc. split on blank lines
702                 this.source = this.source.split(/^$/);
703                 this.type = 'marcbreaker';
704             }
705         }
706
707         this.fetchURL = function (u) {
708             var me = this;
709             $.get( u, function (mrc) {
710                 me.source = mrc;
711                 me.ready = true;
712             });
713         }
714
715         this.next = function () {
716             var chunk = this.source[this.current_record++];
717
718             if (chunk) {
719                 var args = {};
720                 args[this.type] = chunk;
721                 if (this.delimiter) args.delimiter = this.delimiter;
722                 return new MARC21.Record(args);
723             }
724
725             return null;
726         }
727
728         this.ready = false;
729         this.records = [];
730         this.source = kwargs.source;
731         this.delimiter = kwargs.delimiter
732         this.current_record = 0;
733
734         if (this.source) this.ready = true;
735         if (!this.ready && kwargs.url) this.fetchURL( kwargs.url );
736
737         if (this.ready) this.parse();
738
739     },
740
741     AuthorityControlSet : function (kwargs) {
742     
743         kwargs = kwargs || {};
744     
745         if (!MARC21.AuthorityControlSet._remote_loaded) {
746     
747             // TODO -- push the raw tree into the oils cache for later reuse
748     
749             // fetch everything up front...
750             this._preFetchWithFielder({
751                 "acs": "_control_set_list",
752                 "at": "_thesaurus_list",
753                 "acsaf": "_authority_field_list",
754                 "acsbf": "_bib_field_list",
755                 "aba": "_browse_axis_list",
756                 "abaafm": "_browse_field_map_list"
757             });
758     
759             MARC21.AuthorityControlSet._remote_loaded = true;
760         }
761     
762         if (MARC21.AuthorityControlSet._remote_loaded && !MARC21.AuthorityControlSet._remote_parsed) {
763     
764             MARC21.AuthorityControlSet._browse_axis_by_code = {};
765             MARC21.AuthorityControlSet._browse_axis_list.forEach(function (ba) {
766                 ba.maps(
767                     MARC21.AuthorityControlSet._browse_field_map_list.filter(
768                         function (m) { return m.axis() == ba.code() }
769                     )
770                 );
771                 MARC21.AuthorityControlSet._browse_axis_by_code[ba.code()] = ba;
772             });
773     
774             // loop over each acs
775             MARC21.AuthorityControlSet._control_set_list.forEach(function (cs) {
776                 MARC21.AuthorityControlSet._controlsets[''+cs.id()] = {
777                     id : cs.id(),
778                     name : cs.name(),
779                     description : cs.description(),
780                     authority_tag_map : {},
781                     control_map : {},
782                     bib_fields : [],
783                     raw : cs
784                 };
785     
786                 // grab the authority fields
787                 var acsaf_list = MARC21.AuthorityControlSet._authority_field_list.filter(
788                     function (af) { return af.control_set() == cs.id() }
789                 );
790     
791                 var at_list = MARC21.AuthorityControlSet._thesaurus_list.filter(
792                     function (at) { return at.control_set() == cs.id() }
793                 );
794     
795                 MARC21.AuthorityControlSet._controlsets[''+cs.id()].raw.authority_fields( acsaf_list );
796                 MARC21.AuthorityControlSet._controlsets[''+cs.id()].raw.thesauri( at_list );
797     
798                 // and loop over each
799                 acsaf_list.forEach(function (csaf) {
800                     csaf.axis_maps([]);
801     
802                     // link the main entry if we're subordinate
803                     if (csaf.main_entry()) {
804                         csaf.main_entry(
805                             acsaf_list.filter(function (x) {
806                                 return x.id() == csaf.main_entry();
807                             })[0]
808                         );
809                     }
810     
811                     // link the sub entries if we're main
812                     csaf.sub_entries(
813                         acsaf_list.filter(function (x) {
814                             return x.main_entry() == csaf.id();
815                         })
816                     );
817     
818                     // now, bib fields
819                     var acsbf_list = MARC21.AuthorityControlSet._bib_field_list.filter(
820                         function (b) { return b.authority_field() == csaf.id() }
821                     );
822                     csaf.bib_fields( acsbf_list );
823     
824                     MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields = [].concat(
825                         MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields,
826                         acsbf_list
827                     );
828     
829                     acsbf_list.forEach(function (csbf) {
830                         // link the authority field to the bib field
831                         if (csbf.authority_field()) {
832                             csbf.authority_field(
833                                 acsaf_list.filter(function (x) {
834                                     return x.id() == csbf.authority_field();
835                                 })[0]
836                             );
837                         }
838     
839                     });
840     
841                     MARC21.AuthorityControlSet._browse_axis_list.forEach(
842                         function (ba) {
843                             ba.maps().filter(
844                                 function (m) { return m.field() == csaf.id() }
845                             ).forEach(
846                                 function (fm) { fm.field( csaf ); csaf.axis_maps().push( fm ) } // and set the field
847                             )
848                         }
849                     );
850     
851                 });
852     
853                 // build the authority_tag_map
854                 MARC21.AuthorityControlSet._controlsets[''+cs.id()].bib_fields.forEach(function (bf) {
855     
856                     if (!MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()])
857                         MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()] = {};
858     
859                     bf.authority_field().sf_list().split('').forEach(function (sf_code) {
860     
861                         if (!MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code])
862                             MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code] = {};
863     
864                         MARC21.AuthorityControlSet._controlsets[''+cs.id()].control_map[bf.tag()][sf_code][bf.authority_field().tag()] = sf_code;
865                     });
866                 });
867     
868             });
869     
870             if (this.controlSetList().length > 0)
871                 delete MARC21.AuthorityControlSet._controlsets['-1'];
872     
873             MARC21.AuthorityControlSet._remote_parsed = true;
874         }
875     
876         this._preFetchWithFielder = function(cmap) {
877             for (var hint in cmap) {
878                 var cache_key = cmap[hint];
879                 var method = "open-ils.fielder." + hint + ".atomic";
880                 var pkey = fieldmapper.IDL.fmclasses[hint].pkey;
881     
882                 var query = {};
883                 query[pkey] = {"!=": null};
884     
885                 MARC21.AuthorityControlSet[cache_key] = dojo.map(
886                     fieldmapper.standardRequest(
887                         ["open-ils.fielder", method],
888                         [{"cache": 1, "query" : query}]
889                     ),
890                     function(h) { return new fieldmapper[hint]().fromHash(h); }
891                 );
892             }
893         }
894     
895         this.controlSetId = function (x) {
896             if (x) this._controlset = ''+x;
897             return this._controlset;
898         }
899     
900         this.controlSet = function (x) {
901             return MARC21.AuthorityControlSet._controlsets[''+this.controlSetId(x)];
902         }
903     
904         this.controlSetByThesaurusCode = function (x) {
905             var thes = MARC21.AuthorityControlSet._thesaurus_list.filter(
906                 function (at) { return at.code() == x }
907             )[0];
908     
909             return this.controlSet(thes.control_set());
910         }
911     
912         this.browseAxisByCode = function(code) {
913             return MARC21.AuthorityControlSet._browse_axis_by_code[code];
914         }
915     
916         this.bibFieldByTag = function (x) {
917             var me = this;
918             return me.controlSet().bib_fields.filter(
919                 function (bf) { if (bf.tag() == x) return true }
920             )[0];
921         }
922     
923         this.bibFields = function (x) {
924             return this.controlSet(x).bib_fields;
925         }
926     
927         this.bibFieldBrowseAxes = function (t) {
928             var blist = [];
929             for (var bcode in MARC21.AuthorityControlSet._browse_axis_by_code) {
930                 MARC21.AuthorityControlSet._browse_axis_by_code[bcode].maps().forEach(
931                     function (m) {
932                         if (m.field().bib_fields().filter(
933                                 function (b) { return b.tag() == t }
934                             ).length > 0
935                         ) blist.push(bcode);
936                     }
937                 );
938             }
939             return blist;
940         }
941     
942         this.authorityFields = function (x) {
943             return this.controlSet(x).raw.authority_fields();
944         }
945     
946         this.thesauri = function (x) {
947             return this.controlSet(x).raw.thesauri();
948         }
949     
950         this.controlSetList = function () {
951             var l = [];
952             for (var i in MARC21.AuthorityControlSet._controlsets) {
953                 l.push(i);
954             }
955             return l;
956         }
957     
958         this.findControlSetsForTag = function (tag) {
959             var me = this;
960             var old_acs = this.controlSetId();
961             var acs_list = me.controlSetList().filter(
962                 function(acs_id) { return (me.controlSet(acs_id).control_map[tag]) }
963             );
964             this.controlSetId(old_acs);
965             return acs_list;
966         }
967     
968         this.findControlSetsForAuthorityTag = function (tag) {
969             var me = this;
970             var old_acs = this.controlSetId();
971     
972             var acs_list = me.controlSetList().filter(
973                 function(acs_id) {
974                     var a = me.controlSet(acs_id);
975                     for (var btag in a.control_map) {
976                         for (var sf in a.control_map[btag]) {
977                             if (a.control_map[btag][sf][tag]) return true;
978                         }
979                     }
980                     return false;
981                 }
982             );
983             this.controlSetId(old_acs);
984             return acs_list;
985         }
986     
987         this.bibToAuthority = function (field) {
988             var b_field = this.bibFieldByTag(field.tag);
989     
990             if (b_field) { // construct an marc authority record
991                 var af = b_field.authority_field();
992     
993                 var sflist = [];                
994                 for (var i = 0; i < field.subfields.length; i++) {
995                     if (af.sf_list().indexOf(field.subfields[i][0]) > -1) {
996                         sflist.push(field.subfields[i]);
997                     }
998                 }
999     
1000                 var m = new MARC21.Record ({rtype:'AUT'});
1001                 m.appendFields(
1002                     new MARC21.Field ({
1003                         tag : af.tag(),
1004                         ind1: field.ind1,
1005                         ind2: field.ind2,
1006                         subfields: sflist
1007                     })
1008                 );
1009     
1010                 return m.toXmlString();
1011             }
1012     
1013             return null;
1014         }
1015     
1016         this.bibToAuthorities = function (field) {
1017             var auth_list = [];
1018             var me = this;
1019     
1020             var old_acs = this.controlSetId();
1021             me.controlSetList().forEach(
1022                 function (acs_id) {
1023                     var acs = me.controlSet(acs_id);
1024                     var x = me.bibToAuthority(field);
1025                     if (x) { var foo = {}; foo[acs_id] = x; auth_list.push(foo); }
1026                 }
1027             );
1028             this.controlSetId(old_acs);
1029     
1030             return auth_list;
1031         }
1032     
1033         // This should not be used in an angular world.  Instead, the call
1034         // to open-ils.search.authority.simple_heading.from_xml.batch.atomic should
1035         // be performed by the code that wants to find matching authorities.
1036         this.findMatchingAuthorities = function (field) {
1037             return fieldmapper.standardRequest(
1038                 [ 'open-ils.search', 'open-ils.search.authority.simple_heading.from_xml.batch.atomic' ],
1039                 this.bibToAuthorities(field)
1040             );
1041         }
1042     
1043         if (kwargs.controlSet) {
1044             this.controlSetId( kwargs.controlSet );
1045         } else {
1046             this.controlSetId( this.controlSetList().sort(function(a,b){return (a - b)}) );
1047         }
1048     
1049     }
1050 };
1051
1052 MARC21.Record._recType = {
1053     BKS : { Type : /[at]{1}/,    BLvl : /[acdm]{1}/ },
1054     SER : { Type : /[a]{1}/,    BLvl : /[bsi]{1}/ },
1055     VIS : { Type : /[gkro]{1}/,    BLvl : /[abcdmsi]{1}/ },
1056     MIX : { Type : /[p]{1}/,    BLvl : /[cdi]{1}/ },
1057     MAP : { Type : /[ef]{1}/,    BLvl : /[abcdmsi]{1}/ },
1058     SCO : { Type : /[cd]{1}/,    BLvl : /[abcdmsi]{1}/ },
1059     REC : { Type : /[ij]{1}/,    BLvl : /[abcdmsi]{1}/ },
1060     COM : { Type : /[m]{1}/,    BLvl : /[abcdmsi]{1}/ },
1061     AUT : { Type : /[z]{1}/,    BLvl : /.{1}/ },
1062     MFHD : { Type : /[uvxy]{1}/,  BLvl : /.{1}/ }
1063 };
1064
1065 MARC21.Record._ff_pos = {
1066     AccM : {
1067         _8 : {
1068             SCO : {start: 24, len : 6, def : ' ' },
1069             REC : {start: 24, len : 6, def : ' ' }
1070         },
1071         _6 : {
1072             SCO : {start: 7, len : 6, def : ' ' },
1073             REC : {start: 7, len : 6, def : ' ' }
1074         }
1075     },
1076     Alph : {
1077         _8 : {
1078             SER : {start : 33, len : 1, def : ' ' }
1079         },
1080         _6 : {
1081             SER : {start : 16, len : 1, def : ' ' }
1082         }
1083     },
1084     Audn : {
1085         _8 : {
1086             BKS : {start : 22, len : 1, def : ' ' },
1087             SER : {start : 22, len : 1, def : ' ' },
1088             VIS : {start : 22, len : 1, def : ' ' },
1089             SCO : {start : 22, len : 1, def : ' ' },
1090             REC : {start : 22, len : 1, def : ' ' },
1091             COM : {start : 22, len : 1, def : ' ' }
1092         },
1093         _6 : {
1094             BKS : {start : 5, len : 1, def : ' ' },
1095             SER : {start : 5, len : 1, def : ' ' },
1096             VIS : {start : 5, len : 1, def : ' ' },
1097             SCO : {start : 5, len : 1, def : ' ' },
1098             REC : {start : 5, len : 1, def : ' ' },
1099             COM : {start : 5, len : 1, def : ' ' }
1100         }
1101     },
1102     Biog : {
1103         _8 : {
1104             BKS : {start : 34, len : 1, def : ' ' }
1105         },
1106         _6 : {
1107             BKS : {start : 17, len : 1, def : ' ' }
1108         }
1109     },
1110     BLvl : {
1111         ldr : {
1112             BKS : {start : 7, len : 1, def : 'm' },
1113             SER : {start : 7, len : 1, def : 's' },
1114             VIS : {start : 7, len : 1, def : 'm' },
1115             MIX : {start : 7, len : 1, def : 'c' },
1116             MAP : {start : 7, len : 1, def : 'm' },
1117             SCO : {start : 7, len : 1, def : 'm' },
1118             REC : {start : 7, len : 1, def : 'm' },
1119             COM : {start : 7, len : 1, def : 'm' }
1120         }
1121     },
1122     Comp : {
1123         _8 : {
1124             SCO : {start : 18, len : 2, def : 'uu'},
1125             REC : {start : 18, len : 2, def : 'uu'}
1126         },
1127         _6 : {
1128             SCO : {start : 1, len : 2, def : 'uu'},
1129             REC : {start : 1, len : 2, def : 'uu'}
1130         },
1131     },
1132     Conf : {
1133         _8 : {
1134             BKS : {start : 29, len : 1, def : '0' },
1135             SER : {start : 29, len : 1, def : '0' }
1136         },
1137         _6 : {
1138             BKS : {start : 11, len : 1, def : '0' },
1139             SER : {start : 11, len : 1, def : '0' }
1140         }
1141     },
1142     Cont : {
1143         _8 : {
1144             BKS : {start : 24, len : 4, def : ' ' },
1145             SER : {start : 25, len : 3, def : ' ' }
1146         },
1147         _6 : {
1148             BKS : {start : 7, len : 4, def : ' ' },
1149             SER : {start : 8, len : 3, def : ' ' }
1150         }
1151     },
1152     CrTp : {
1153         _8 : {
1154             MAP : {start: 25, len : 1, def : 'a' }
1155         },
1156         _6 : { 
1157             MAP : {start : 8, len : 1, def : 'a' }
1158         }
1159     },
1160     Ctrl : {
1161         ldr : {
1162             BKS : {start : 8, len : 1, def : ' ' },
1163             SER : {start : 8, len : 1, def : ' ' },
1164             VIS : {start : 8, len : 1, def : ' ' },
1165             MIX : {start : 8, len : 1, def : ' ' },
1166             MAP : {start : 8, len : 1, def : ' ' },
1167             SCO : {start : 8, len : 1, def : ' ' },
1168             REC : {start : 8, len : 1, def : ' ' },
1169             COM : {start : 8, len : 1, def : ' ' }
1170         }
1171     },
1172     Ctry : {
1173             _8 : {
1174                 BKS : {start : 15, len : 3, def : ' ' },
1175                 SER : {start : 15, len : 3, def : ' ' },
1176                 VIS : {start : 15, len : 3, def : ' ' },
1177                 MIX : {start : 15, len : 3, def : ' ' },
1178                 MAP : {start : 15, len : 3, def : ' ' },
1179                 SCO : {start : 15, len : 3, def : ' ' },
1180                 REC : {start : 15, len : 3, def : ' ' },
1181                 COM : {start : 15, len : 3, def : ' ' }
1182             }
1183         },
1184     Date1 : {
1185         _8 : {
1186             BKS : {start : 7, len : 4, def : ' ' },
1187             SER : {start : 7, len : 4, def : ' ' },
1188             VIS : {start : 7, len : 4, def : ' ' },
1189             MIX : {start : 7, len : 4, def : ' ' },
1190             MAP : {start : 7, len : 4, def : ' ' },
1191             SCO : {start : 7, len : 4, def : ' ' },
1192             REC : {start : 7, len : 4, def : ' ' },
1193             COM : {start : 7, len : 4, def : ' ' }
1194         }
1195     },
1196     Date2 : {
1197         _8 : {
1198             BKS : {start : 11, len : 4, def : ' ' },
1199             SER : {start : 11, len : 4, def : '9' },
1200             VIS : {start : 11, len : 4, def : ' ' },
1201             MIX : {start : 11, len : 4, def : ' ' },
1202             MAP : {start : 11, len : 4, def : ' ' },
1203             SCO : {start : 11, len : 4, def : ' ' },
1204             REC : {start : 11, len : 4, def : ' ' },
1205             COM : {start : 11, len : 4, def : ' ' }
1206         }
1207     },
1208     Desc : {
1209         ldr : {
1210             BKS : {start : 18, len : 1, def : ' ' },
1211             SER : {start : 18, len : 1, def : ' ' },
1212             VIS : {start : 18, len : 1, def : ' ' },
1213             MIX : {start : 18, len : 1, def : ' ' },
1214             MAP : {start : 18, len : 1, def : ' ' },
1215             SCO : {start : 18, len : 1, def : ' ' },
1216             REC : {start : 18, len : 1, def : ' ' },
1217             COM : {start : 18, len : 1, def : ' ' }
1218         }
1219     },
1220     DtSt : {
1221         _8 : {
1222             BKS : {start : 6, len : 1, def : ' ' },
1223             SER : {start : 6, len : 1, def : 'c' },
1224             VIS : {start : 6, len : 1, def : ' ' },
1225             MIX : {start : 6, len : 1, def : ' ' },
1226             MAP : {start : 6, len : 1, def : ' ' },
1227             SCO : {start : 6, len : 1, def : ' ' },
1228             REC : {start : 6, len : 1, def : ' ' },
1229             COM : {start : 6, len : 1, def : ' ' }
1230         }
1231     },
1232     ELvl : {
1233         ldr : {
1234             BKS : {start : 17, len : 1, def : ' ' },
1235             SER : {start : 17, len : 1, def : ' ' },
1236             VIS : {start : 17, len : 1, def : ' ' },
1237             MIX : {start : 17, len : 1, def : ' ' },
1238             MAP : {start : 17, len : 1, def : ' ' },
1239             SCO : {start : 17, len : 1, def : ' ' },
1240             REC : {start : 17, len : 1, def : ' ' },
1241             COM : {start : 17, len : 1, def : ' ' },
1242             AUT : {start : 17, len : 1, def : 'n' },
1243             MFHD : {start : 17, len : 1, def : 'u' }
1244         }
1245     },
1246     EntW : {
1247         _8 : {
1248             SER : {start : 24, len : 1, def : ' '}
1249         },
1250         _6 : {
1251             SER : {start : 7, len : 1, def : ' '}
1252         }
1253     },
1254     Fest : {
1255         _8 : {
1256             BKS : {start : 30, len : 1, def : '0' }
1257         },
1258         _6 : {
1259             BKS : {start : 13, len : 1, def : '0' }
1260         }
1261     },
1262     File : {
1263         _8 : {
1264             COM : {start: 26, len : 1, def : 'u' }
1265         },
1266         _6 : {
1267             COM : {start: 9, len : 1, def : 'u' }
1268         }
1269     },
1270     FMus : {
1271         _8 : {
1272             SCO : {start : 20, len : 1, def : 'u'},
1273             REC : {start : 20, len : 1, def : 'n'}
1274         },
1275         _6 : {
1276             SCO : {start : 3, len : 1, def : 'u'},
1277             REC : {start : 3, len : 1, def : 'n'}
1278         },
1279     },
1280     Form : {
1281         _8 : {
1282             BKS : {start : 23, len : 1, def : ' ' },
1283             SER : {start : 23, len : 1, def : ' ' },
1284             VIS : {start : 29, len : 1, def : ' ' },
1285             MIX : {start : 23, len : 1, def : ' ' },
1286             MAP : {start : 29, len : 1, def : ' ' },
1287             SCO : {start : 23, len : 1, def : ' ' },
1288             REC : {start : 23, len : 1, def : ' ' }
1289         },
1290         _6 : {
1291             BKS : {start : 6, len : 1, def : ' ' },
1292             SER : {start : 6, len : 1, def : ' ' },
1293             VIS : {start : 12, len : 1, def : ' ' },
1294             MIX : {start : 6, len : 1, def : ' ' },
1295             MAP : {start : 12, len : 1, def : ' ' },
1296             SCO : {start : 6, len : 1, def : ' ' },
1297             REC : {start : 6, len : 1, def : ' ' }
1298         }
1299     },
1300     Freq : {
1301         _8 : {
1302             SER : {start : 18, len : 1, def : ' '}
1303         },
1304         _6 : {
1305             SER : {start : 1, len : 1, def : ' '}
1306         }
1307     },
1308     GPub : {
1309         _8 : {
1310             BKS : {start : 28, len : 1, def : ' ' },
1311             SER : {start : 28, len : 1, def : ' ' },
1312             VIS : {start : 28, len : 1, def : ' ' },
1313             MAP : {start : 28, len : 1, def : ' ' },
1314             COM : {start : 28, len : 1, def : ' ' }
1315         },
1316         _6 : {
1317             BKS : {start : 11, len : 1, def : ' ' },
1318             SER : {start : 11, len : 1, def : ' ' },
1319             VIS : {start : 11, len : 1, def : ' ' },
1320             MAP : {start : 11, len : 1, def : ' ' },
1321             COM : {start : 11, len : 1, def : ' ' }
1322         }
1323     },
1324     Ills : {
1325         _8 : {
1326             BKS : {start : 18, len : 4, def : ' ' }
1327         },
1328         _6 : {
1329             BKS : {start : 1, len : 4, def : ' ' }
1330         }
1331     },
1332     Indx : {
1333         _8 : {
1334             BKS : {start : 31, len : 1, def : '0' },
1335             MAP : {start : 31, len : 1, def : '0' }
1336         },
1337         _6 : {
1338             BKS : {start : 14, len : 1, def : '0' },
1339             MAP : {start : 14, len : 1, def : '0' }
1340         }
1341     },
1342     Item : {
1343         ldr : {
1344             MFHD : {start : 18, len : 1, def : 'i' }
1345         }
1346     },
1347     Lang : {
1348         _8 : {
1349             BKS : {start : 35, len : 3, def : ' ' },
1350             SER : {start : 35, len : 3, def : ' ' },
1351             VIS : {start : 35, len : 3, def : ' ' },
1352             MIX : {start : 35, len : 3, def : ' ' },
1353             MAP : {start : 35, len : 3, def : ' ' },
1354             SCO : {start : 35, len : 3, def : ' ' },
1355             REC : {start : 35, len : 3, def : ' ' },
1356             COM : {start : 35, len : 3, def : ' ' }
1357         }
1358     },
1359     LitF : {
1360         _8 : {
1361             BKS : {start : 33, len : 1, def : '0' }
1362         },
1363         _6 : {
1364             BKS : {start : 16, len : 1, def : '0' }
1365         }
1366     },
1367     LTxt : {
1368         _8 : {
1369             SCO : {start : 30, len : 2, def : 'n'},
1370             REC : {start : 30, len : 2, def : ' '}
1371         },
1372         _6 : {
1373             SCO : {start : 13, len : 2, def : 'n'},
1374             REC : {start : 13, len : 2, def : ' '}
1375         },
1376     },
1377     MRec : {
1378         _8 : {
1379             BKS : {start : 38, len : 1, def : ' ' },
1380             SER : {start : 38, len : 1, def : ' ' },
1381             VIS : {start : 38, len : 1, def : ' ' },
1382             MIX : {start : 38, len : 1, def : ' ' },
1383             MAP : {start : 38, len : 1, def : ' ' },
1384             SCO : {start : 38, len : 1, def : ' ' },
1385             REC : {start : 38, len : 1, def : ' ' },
1386             COM : {start : 38, len : 1, def : ' ' }
1387         }
1388     },
1389     Orig : {
1390         _8 : {
1391             SER : {start : 22, len : 1, def : ' '}
1392         },
1393         _6 : {
1394             SER : {start: 5, len : 1, def: ' '}
1395         }
1396     },
1397     Part : {
1398         _8 : {
1399             SCO : {start : 21, len : 1, def : ' '},
1400             REC : {start : 21, len : 1, def : 'n'}
1401         },
1402         _6 : {
1403             SCO : {start : 4, len : 1, def : ' '},
1404             REC : {start : 4, len : 1, def : 'n'}
1405         },
1406     },
1407     Proj : {
1408         _8 : {
1409             MAP : {start : 22, len : 2, def : ' ' }
1410         },
1411         _6 : {
1412             MAP: {start : 5, len : 2, def : ' ' }
1413         }
1414     },
1415     RecStat : {
1416         ldr : {
1417             BKS : {start : 5, len : 1, def : 'n' },
1418             SER : {start : 5, len : 1, def : 'n' },
1419             VIS : {start : 5, len : 1, def : 'n' },
1420             MIX : {start : 5, len : 1, def : 'n' },
1421             MAP : {start : 5, len : 1, def : 'n' },
1422             SCO : {start : 5, len : 1, def : 'n' },
1423             REC : {start : 5, len : 1, def : 'n' },
1424             COM : {start : 5, len : 1, def : 'n' },
1425             MFHD: {start : 5, len : 1, def : 'n' },
1426             AUT : {start : 5, len : 1, def : 'n' }
1427         }
1428     },
1429     Regl : {
1430         _8 : {
1431             SER : {start : 19, len : 1, def : ' '}
1432         },
1433         _6 : {
1434             SER : {start : 2, len : 1, def : ' '}
1435         }
1436     },
1437     Relf : {
1438         _8 : {
1439             MAP : {start: 18, len : 4, def : ' '}
1440         },
1441         _6 : {
1442             MAP : {start: 1, len : 4, def : ' '}
1443         }
1444     },
1445     'S/L' : {
1446         _8 : {
1447             SER : {start : 34, len : 1, def : '0' }
1448         },
1449         _6 : {
1450             SER : {start : 17, len : 1, def : '0' }
1451         }
1452     },
1453     SpFM : {
1454         _8 : {
1455             MAP : {start: 33, len : 2, def : ' ' }
1456         },
1457         _6 : {
1458             MAP : {start: 16, len : 2, def : ' '}
1459         }
1460     },
1461     Srce : {
1462         _8 : {
1463             BKS : {start : 39, len : 1, def : 'd' },
1464             SER : {start : 39, len : 1, def : 'd' },
1465             VIS : {start : 39, len : 1, def : 'd' },
1466             SCO : {start : 39, len : 1, def : 'd' },
1467             REC : {start : 39, len : 1, def : 'd' },
1468             COM : {start : 39, len : 1, def : 'd' },
1469             MFHD : {start : 39, len : 1, def : 'd' },
1470             "AUT" : {"start" : 39, "len" : 1, "def" : 'd' }
1471         }
1472     },
1473     SrTp : {
1474         _8 : {
1475             SER : {start : 21, len : 1, def : ' '}
1476         },
1477         _6 : {
1478             SER : {start : 4, len : 1, def : ' '}
1479         }
1480     },
1481     Tech : {
1482         _8 : {
1483             VIS : {start : 34, len : 1, def : ' '}
1484         },
1485         _6 : {
1486             VIS : {start : 17, len : 1, def : ' '}
1487         }
1488     },
1489     Time : {
1490         _8 : {
1491             VIS : {start : 18, len : 3, def : ' '}
1492         },
1493         _6 : {
1494             VIS : {start : 1, len : 3, def : ' '}
1495         }
1496     },
1497     TMat : {
1498         _8 : {
1499             VIS : {start : 33, len : 1, def : ' ' }
1500         },
1501         _6 : {
1502             VIS : {start : 16, len : 1, def : ' ' }
1503         }
1504     },
1505     TrAr : {
1506         _8 : {
1507             SCO : {start : 33, len : 1, def : ' ' },
1508             REC : {start : 33, len : 1, def : 'n' }
1509         },
1510         _6 : {
1511             SCO : {start : 16, len : 1, def : ' ' },
1512             REC : {start : 16, len : 1, def : 'n' }
1513         }
1514     },
1515     Type : {
1516         ldr : {
1517             BKS : {start : 6, len : 1, def : 'a' },
1518             SER : {start : 6, len : 1, def : 'a' },
1519             VIS : {start : 6, len : 1, def : 'g' },
1520             MIX : {start : 6, len : 1, def : 'p' },
1521             MAP : {start : 6, len : 1, def : 'e' },
1522             SCO : {start : 6, len : 1, def : 'c' },
1523             REC : {start : 6, len : 1, def : 'i' },
1524             COM : {start : 6, len : 1, def : 'm' },
1525             AUT : {start : 6, len : 1, def : 'z' },
1526             MFHD : {start : 6, len : 1, def : 'y' }
1527         }
1528     },
1529     "GeoDiv" : {
1530          "_8" : {
1531              "AUT" : {"start" : 6, "len" : 1, "def" : ' ' }
1532          }
1533      },
1534      "Roman" : {
1535          "_8" : {
1536              "AUT" : {"start" : 7, "len" : 1, "def" : ' ' }
1537          }
1538      },
1539      "CatLang" : {
1540          "_8" : {
1541              "AUT" : {"start" : 8, "len" : 1, "def" : ' ' }
1542          }
1543      },
1544      "Kind" : {
1545          "_8" : {
1546              "AUT" : {"start" : 9, "len" : 1, "def" : ' ' }
1547          }
1548      },
1549      "Rules" : {
1550          "_8" : {
1551              "AUT" : {"start" : 10, "len" : 1, "def" : ' ' }
1552          }
1553      },
1554      "Subj" : {
1555          "_8" : {
1556              "AUT" : {"start" : 11, "len" : 1, "def" : ' ' }
1557          }
1558      },
1559      "Series" : {
1560          "_8" : {
1561              "AUT" : {"start" : 12, "len" : 1, "def" : ' ' }
1562          }
1563      },
1564      "SerNum" : {
1565          "_8" : {
1566              "AUT" : {"start" : 13, "len" : 1, "def" : ' ' }
1567          }
1568      },
1569      "NameUse" : {
1570          "_8" : {
1571              "AUT" : {"start" : 14, "len" : 1, "def" : ' ' }
1572          }
1573      },
1574      "SubjUse" : {
1575          "_8" : {
1576              "AUT" : {"start" : 15, "len" : 1, "def" : ' ' }
1577          }
1578      },
1579      "SerUse" : {
1580          "_8" : {
1581              "AUT" : {"start" : 16, "len" : 1, "def" : ' ' }
1582          }
1583      },
1584      "TypeSubd" : {
1585          "_8" : {
1586              "AUT" : {"start" : 17, "len" : 1, "def" : ' ' }
1587          }
1588      },
1589      "GovtAgn" : {
1590          "_8" : {
1591              "AUT" : {"start" : 28, "len" : 1, "def" : ' ' }
1592          }
1593      },
1594      "RefStatus" : {
1595          "_8" : {
1596              "AUT" : {"start" : 29, "len" : 1, "def" : ' ' }
1597          }
1598      },
1599      "UpdStatus" : {
1600          "_8" : {
1601              "AUT" : {"start" : 31, "len" : 1, "def" : ' ' }
1602          }
1603      },
1604      "Name" : {
1605          "_8" : {
1606              "AUT" : {"start" : 32, "len" : 1, "def" : ' ' }
1607          }
1608      },
1609      "Status" : {
1610          "_8" : {
1611              "AUT" : {"start" : 33, "len" : 1, "def" : ' ' }
1612          }
1613      },
1614      "ModRec" : {
1615          "_8" : {
1616              "AUT" : {"start" : 38, "len" : 1, "def" : ' ' }
1617          }
1618      },
1619      "Source" : {
1620          "_8" : {
1621              "AUT" : {"start" : 39, "len" : 1, "def" : ' ' }
1622          }
1623      }
1624 };
1625
1626 MARC21.Record._physical_characteristics = {
1627     c : {
1628         label     : "Electronic Resource",
1629         subfields : {
1630             b : {    start : 1,
1631                 len   : 1,
1632                 label : "SMD",
1633                 values: {    a : "Tape Cartridge",
1634                         b : "Chip cartridge",
1635                         c : "Computer optical disk cartridge",
1636                         f : "Tape cassette",
1637                         h : "Tape reel",
1638                         j : "Magnetic disk",
1639                         m : "Magneto-optical disk",
1640                         o : "Optical disk",
1641                         r : "Remote",
1642                         u : "Unspecified",
1643                         z : "Other"
1644                 }
1645             },
1646             d : {    start : 3,
1647                 len   : 1,
1648                 label : "Color",
1649                 values: {    a : "One color",
1650                         b : "Black-and-white",
1651                         c : "Multicolored",
1652                         g : "Gray scale",
1653                         m : "Mixed",
1654                         n : "Not applicable",
1655                         u : "Unknown",
1656                         z : "Other"
1657                 }
1658             },
1659             e : {    start : 4,
1660                 len   : 1,
1661                 label : "Dimensions",
1662                 values: {    a : "3 1/2 in.",
1663                         e : "12 in.",
1664                         g : "4 3/4 in. or 12 cm.",
1665                         i : "1 1/8 x 2 3/8 in.",
1666                         j : "3 7/8 x 2 1/2 in.",
1667                         n : "Not applicable",
1668                         o : "5 1/4 in.",
1669                         u : "Unknown",
1670                         v : "8 in.",
1671                         z : "Other"
1672                 }
1673             },
1674             f : {    start : 5,
1675                 len   : 1,
1676                 label : "Sound",
1677                 values: {    ' ' : "No sound (Silent)",
1678                         a   : "Sound",
1679                         u   : "Unknown"
1680                 }
1681             },
1682             g : {    start : 6,
1683                 len   : 3,
1684                 label : "Image bit depth",
1685                 values: {    mmm   : "Multiple",
1686                         nnn   : "Not applicable",
1687                         '---' : "Unknown"
1688                 }
1689             },
1690             h : {    start : 9,
1691                 len   : 1,
1692                 label : "File formats",
1693                 values: {    a : "One file format",
1694                         m : "Multiple file formats",
1695                         u : "Unknown"
1696                 }
1697             },
1698             i : {    start : 10,
1699                 len   : 1,
1700                 label : "Quality assurance target(s)",
1701                 values: {    a : "Absent",
1702                         n : "Not applicable",
1703                         p : "Present",
1704                         u : "Unknown"
1705                 }
1706             },
1707             j : {    start : 11,
1708                 len   : 1,
1709                 label : "Antecedent/Source",
1710                 values: {    a : "File reproduced from original",
1711                         b : "File reproduced from microform",
1712                         c : "File reproduced from electronic resource",
1713                         d : "File reproduced from an intermediate (not microform)",
1714                         m : "Mixed",
1715                         n : "Not applicable",
1716                         u : "Unknown"
1717                 }
1718             },
1719             k : {    start : 12,
1720                 len   : 1,
1721                 label : "Level of compression",
1722                 values: {    a : "Uncompressed",
1723                         b : "Lossless",
1724                         d : "Lossy",
1725                         m : "Mixed",
1726                         u : "Unknown"
1727                 }
1728             },
1729             l : {    start : 13,
1730                 len   : 1,
1731                 label : "Reformatting quality",
1732                 values: {    a : "Access",
1733                         n : "Not applicable",
1734                         p : "Preservation",
1735                         r : "Replacement",
1736                         u : "Unknown"
1737                 }
1738             }
1739         }
1740     },
1741     d : {
1742         label     : "Globe",
1743         subfields : {
1744             b : {    start : 1,
1745                 len   : 1,
1746                 label : "SMD",
1747                 values: {    a : "Celestial globe",
1748                         b : "Planetary or lunar globe",
1749                         c : "Terrestrial globe",
1750                         e : "Earth moon globe",
1751                         u : "Unspecified",
1752                         z : "Other"
1753                 }
1754             },
1755             d : {    start : 3,
1756                 len   : 1,
1757                 label : "Color",
1758                 values: {    a : "One color",
1759                         c : "Multicolored"
1760                 }
1761             },
1762             e : {    start : 4,
1763                 len   : 1,
1764                 label : "Physical medium",
1765                 values: {    a : "Paper",
1766                         b : "Wood",
1767                         c : "Stone",
1768                         d : "Metal",
1769                         e : "Synthetics",
1770                         f : "Skins",
1771                         g : "Textile",
1772                         p : "Plaster",
1773                         u : "Unknown",
1774                         z : "Other"
1775                 }
1776             },
1777             f : {    start : 5,
1778                 len   : 1,
1779                 label : "Type of reproduction",
1780                 values: {    f : "Facsimile",
1781                         n : "Not applicable",
1782                         u : "Unknown",
1783                         z : "Other"
1784                 }
1785             }
1786         }
1787     },
1788     a : {
1789         label     : "Map",
1790         subfields : {
1791             b : {    start : 1,
1792                 len   : 1,
1793                 label : "SMD",
1794                 values: {    d : "Atlas",
1795                         g : "Diagram",
1796                         j : "Map",
1797                         k : "Profile",
1798                         q : "Model",
1799                         r : "Remote-sensing image",
1800                         s : "Section",
1801                         u : "Unspecified",
1802                         y : "View",
1803                         z : "Other"
1804                 }
1805             },
1806             d : {    start : 3,
1807                 len   : 1,
1808                 label : "Color",
1809                 values: {    a : "One color",
1810                         c : "Multicolored"
1811                 }
1812             },
1813             e : {    start : 4,
1814                 len   : 1,
1815                 label : "Physical medium",
1816                 values: {    a : "Paper",
1817                         b : "Wood",
1818                         c : "Stone",
1819                         d : "Metal",
1820                         e : "Synthetics",
1821                         f : "Skins",
1822                         g : "Textile",
1823                         p : "Plaster",
1824                         q : "Flexible base photographic medium, positive",
1825                         r : "Flexible base photographic medium, negative",
1826                         s : "Non-flexible base photographic medium, positive",
1827                         t : "Non-flexible base photographic medium, negative",
1828                         u : "Unknown",
1829                         y : "Other photographic medium",
1830                         z : "Other"
1831                 }
1832             },
1833             f : {    start : 5,
1834                 len   : 1,
1835                 label : "Type of reproduction",
1836                 values: {    f : "Facsimile",
1837                         n : "Not applicable",
1838                         u : "Unknown",
1839                         z : "Other"
1840                 }
1841             },
1842             g : {    start : 6,
1843                 len   : 1,
1844                 label : "Production/reproduction details",
1845                 values: {    a : "Photocopy, blueline print",
1846                         b : "Photocopy",
1847                         c : "Pre-production",
1848                         d : "Film",
1849                         u : "Unknown",
1850                         z : "Other"
1851                 }
1852             },
1853             h : {    start : 7,
1854                 len   : 1,
1855                 label : "Positive/negative",
1856                 values: {    a : "Positive",
1857                         b : "Negative",
1858                         m : "Mixed",
1859                         n : "Not applicable"
1860                 }
1861             }
1862         }
1863     },
1864     h : {
1865         label     : "Microform",
1866         subfields : {
1867             b : {    start : 1,
1868                 len   : 1,
1869                 label : "SMD",
1870                 values: {    a : "Aperture card",
1871                         b : "Microfilm cartridge",
1872                         c : "Microfilm cassette",
1873                         d : "Microfilm reel",
1874                         e : "Microfiche",
1875                         f : "Microfiche cassette",
1876                         g : "Microopaque",
1877                         u : "Unspecified",
1878                         z : "Other"
1879                 }
1880             },
1881             d : {    start : 3,
1882                 len   : 1,
1883                 label : "Positive/negative",
1884                 values: {    a : "Positive",
1885                         b : "Negative",
1886                         m : "Mixed",
1887                         u : "Unknown"
1888                 }
1889             },
1890             e : {    start : 4,
1891                 len   : 1,
1892                 label : "Dimensions",
1893                 values: {    a : "8 mm.",
1894                         e : "16 mm.",
1895                         f : "35 mm.",
1896                         g : "70mm.",
1897                         h : "105 mm.",
1898                         l : "3 x 5 in. (8 x 13 cm.)",
1899                         m : "4 x 6 in. (11 x 15 cm.)",
1900                         o : "6 x 9 in. (16 x 23 cm.)",
1901                         p : "3 1/4 x 7 3/8 in. (9 x 19 cm.)",
1902                         u : "Unknown",
1903                         z : "Other"
1904                 }
1905             },
1906             f : {    start : 5,
1907                 len   : 4,
1908                 label : "Reduction ratio range/Reduction ratio",
1909                 values: {    a : "Low (1-16x)",
1910                         b : "Normal (16-30x)",
1911                         c : "High (31-60x)",
1912                         d : "Very high (61-90x)",
1913                         e : "Ultra (90x-)",
1914                         u : "Unknown",
1915                         v : "Reduction ratio varies"
1916                 }
1917             },
1918             g : {    start : 9,
1919                 len   : 1,
1920                 label : "Color",
1921                 values: {    b : "Black-and-white",
1922                         c : "Multicolored",
1923                         m : "Mixed",
1924                         u : "Unknown",
1925                         z : "Other"
1926                 }
1927             },
1928             h : {    start : 10,
1929                 len   : 1,
1930                 label : "Emulsion on film",
1931                 values: {    a : "Silver halide",
1932                         b : "Diazo",
1933                         c : "Vesicular",
1934                         m : "Mixed",
1935                         n : "Not applicable",
1936                         u : "Unknown",
1937                         z : "Other"
1938                 }
1939             },
1940             i : {    start : 11,
1941                 len   : 1,
1942                 label : "Quality assurance target(s)",
1943                 values: {    a : "1st gen. master",
1944                         b : "Printing master",
1945                         c : "Service copy",
1946                         m : "Mixed generation",
1947                         u : "Unknown"
1948                 }
1949             },
1950             j : {    start : 12,
1951                 len   : 1,
1952                 label : "Base of film",
1953                 values: {    a : "Safety base, undetermined",
1954                         c : "Safety base, acetate undetermined",
1955                         d : "Safety base, diacetate",
1956                         l : "Nitrate base",
1957                         m : "Mixed base",
1958                         n : "Not applicable",
1959                         p : "Safety base, polyester",
1960                         r : "Safety base, mixed",
1961                         t : "Safety base, triacetate",
1962                         u : "Unknown",
1963                         z : "Other"
1964                 }
1965             }
1966         }
1967     },
1968     m : {
1969         label     : "Motion Picture",
1970         subfields : {
1971             b : {    start : 1,
1972                 len   : 1,
1973                 label : "SMD",
1974                 values: {    a : "Film cartridge",
1975                         f : "Film cassette",
1976                         r : "Film reel",
1977                         u : "Unspecified",
1978                         z : "Other"
1979                 }
1980             },
1981             d : {    start : 3,
1982                 len   : 1,
1983                 label : "Color",
1984                 values: {    b : "Black-and-white",
1985                         c : "Multicolored",
1986                         h : "Hand-colored",
1987                         m : "Mixed",
1988                         u : "Unknown",
1989                         z : "Other"
1990                 }
1991             },
1992             e : {    start : 4,
1993                 len   : 1,
1994                 label : "Motion picture presentation format",
1995                 values: {    a : "Standard sound aperture, reduced frame",
1996                         b : "Nonanamorphic (wide-screen)",
1997                         c : "3D",
1998                         d : "Anamorphic (wide-screen)",
1999                         e : "Other-wide screen format",
2000                         f : "Standard. silent aperture, full frame",
2001                         u : "Unknown",
2002                         z : "Other"
2003                 }
2004             },
2005             f : {    start : 5,
2006                 len   : 1,
2007                 label : "Sound on medium or separate",
2008                 values: {    a : "Sound on medium",
2009                         b : "Sound separate from medium",
2010                         u : "Unknown"
2011                 }
2012             },
2013             g : {    start : 6,
2014                 len   : 1,
2015                 label : "Medium for sound",
2016                 values: {    a : "Optical sound track on motion picture film",
2017                         b : "Magnetic sound track on motion picture film",
2018                         c : "Magnetic audio tape in cartridge",
2019                         d : "Sound disc",
2020                         e : "Magnetic audio tape on reel",
2021                         f : "Magnetic audio tape in cassette",
2022                         g : "Optical and magnetic sound track on film",
2023                         h : "Videotape",
2024                         i : "Videodisc",
2025                         u : "Unknown",
2026                         z : "Other"
2027                 }
2028             },
2029             h : {    start : 7,
2030                 len   : 1,
2031                 label : "Dimensions",
2032                 values: {    a : "Standard 8 mm.",
2033                         b : "Super 8 mm./single 8 mm.",
2034                         c : "9.5 mm.",
2035                         d : "16 mm.",
2036                         e : "28 mm.",
2037                         f : "35 mm.",
2038                         g : "70 mm.",
2039                         u : "Unknown",
2040                         z : "Other"
2041                 }
2042             },
2043             i : {    start : 8,
2044                 len   : 1,
2045                 label : "Configuration of playback channels",
2046                 values: {    k : "Mixed",
2047                         m : "Monaural",
2048                         n : "Not applicable",
2049                         q : "Multichannel, surround or quadraphonic",
2050                         s : "Stereophonic",
2051                         u : "Unknown",
2052                         z : "Other"
2053                 }
2054             },
2055             j : {    start : 9,
2056                 len   : 1,
2057                 label : "Production elements",
2058                 values: {    a : "Work print",
2059                         b : "Trims",
2060                         c : "Outtakes",
2061                         d : "Rushes",
2062                         e : "Mixing tracks",
2063                         f : "Title bands/inter-title rolls",
2064                         g : "Production rolls",
2065                         n : "Not applicable",
2066                         z : "Other"
2067                 }
2068             }
2069         }
2070     },
2071     k : {
2072         label     : "Non-projected Graphic",
2073         subfields : {
2074             b : {    start : 1,
2075                 len   : 1,
2076                 label : "SMD",
2077                 values: {    c : "Collage",
2078                         d : "Drawing",
2079                         e : "Painting",
2080                         f : "Photo-mechanical print",
2081                         g : "Photonegative",
2082                         h : "Photoprint",
2083                         i : "Picture",
2084                         j : "Print",
2085                         l : "Technical drawing",
2086                         n : "Chart",
2087                         o : "Flash/activity card",
2088                         u : "Unspecified",
2089                         z : "Other"
2090                 }
2091             },
2092             d : {    start : 3,
2093                 len   : 1,
2094                 label : "Color",
2095                 values: {    a : "One color",
2096                         b : "Black-and-white",
2097                         c : "Multicolored",
2098                         h : "Hand-colored",
2099                         m : "Mixed",
2100                         u : "Unknown",
2101                         z : "Other"
2102                 }
2103             },
2104             e : {    start : 4,
2105                 len   : 1,
2106                 label : "Primary support material",
2107                 values: {    a : "Canvas",
2108                         b : "Bristol board",
2109                         c : "Cardboard/illustration board",
2110                         d : "Glass",
2111                         e : "Synthetics",
2112                         f : "Skins",
2113                         g : "Textile",
2114                         h : "Metal",
2115                         m : "Mixed collection",
2116                         o : "Paper",
2117                         p : "Plaster",
2118                         q : "Hardboard",
2119                         r : "Porcelain",
2120                         s : "Stone",
2121                         t : "Wood",
2122                         u : "Unknown",
2123                         z : "Other"
2124                 }
2125             },
2126             f : {    start : 5,
2127                 len   : 1,
2128                 label : "Secondary support material",
2129                 values: {    a : "Canvas",
2130                         b : "Bristol board",
2131                         c : "Cardboard/illustration board",
2132                         d : "Glass",
2133                         e : "Synthetics",
2134                         f : "Skins",
2135                         g : "Textile",
2136                         h : "Metal",
2137                         m : "Mixed collection",
2138                         o : "Paper",
2139                         p : "Plaster",
2140                         q : "Hardboard",
2141                         r : "Porcelain",
2142                         s : "Stone",
2143                         t : "Wood",
2144                         u : "Unknown",
2145                         z : "Other"
2146                 }
2147             }
2148         }
2149     },
2150     g : {
2151         label     : "Projected Graphic",
2152         subfields : {
2153             b : {    start : 1,
2154                 len   : 1,
2155                 label : "SMD",
2156                 values: {    c : "Film cartridge",
2157                         d : "Filmstrip",
2158                         f : "Film filmstrip type",
2159                         o : "Filmstrip roll",
2160                         s : "Slide",
2161                         t : "Transparency",
2162                         z : "Other"
2163                 }
2164             },
2165             d : {    start : 3,
2166                 len   : 1,
2167                 label : "Color",
2168                 values: {    b : "Black-and-white",
2169                         c : "Multicolored",
2170                         h : "Hand-colored",
2171                         m : "Mixed",
2172                         n : "Not applicable",
2173                         u : "Unknown",
2174                         z : "Other"
2175                 }
2176             },
2177             e : {    start : 4,
2178                 len   : 1,
2179                 label : "Base of emulsion",
2180                 values: {    d : "Glass",
2181                         e : "Synthetics",
2182                         j : "Safety film",
2183                         k : "Film base, other than safety film",
2184                         m : "Mixed collection",
2185                         o : "Paper",
2186                         u : "Unknown",
2187                         z : "Other"
2188                 }
2189             },
2190             f : {    start : 5,
2191                 len   : 1,
2192                 label : "Sound on medium or separate",
2193                 values: {    a : "Sound on medium",
2194                         b : "Sound separate from medium",
2195                         u : "Unknown"
2196                 }
2197             },
2198             g : {    start : 6,
2199                 len   : 1,
2200                 label : "Medium for sound",
2201                 values: {    a : "Optical sound track on motion picture film",
2202                         b : "Magnetic sound track on motion picture film",
2203                         c : "Magnetic audio tape in cartridge",
2204                         d : "Sound disc",
2205                         e : "Magnetic audio tape on reel",
2206                         f : "Magnetic audio tape in cassette",
2207                         g : "Optical and magnetic sound track on film",
2208                         h : "Videotape",
2209                         i : "Videodisc",
2210                         u : "Unknown",
2211                         z : "Other"
2212                 }
2213             },
2214             h : {    start : 7,
2215                 len   : 1,
2216                 label : "Dimensions",
2217                 values: {    a : "Standard 8 mm.",
2218                         b : "Super 8 mm./single 8 mm.",
2219                         c : "9.5 mm.",
2220                         d : "16 mm.",
2221                         e : "28 mm.",
2222                         f : "35 mm.",
2223                         g : "70 mm.",
2224                         j : "2 x 2 in. (5 x 5 cm.)",
2225                         k : "2 1/4 x 2 1/4 in. (6 x 6 cm.)",
2226                         s : "4 x 5 in. (10 x 13 cm.)",
2227                         t : "5 x 7 in. (13 x 18 cm.)",
2228                         v : "8 x 10 in. (21 x 26 cm.)",
2229                         w : "9 x 9 in. (23 x 23 cm.)",
2230                         x : "10 x 10 in. (26 x 26 cm.)",
2231                         y : "7 x 7 in. (18 x 18 cm.)",
2232                         u : "Unknown",
2233                         z : "Other"
2234                 }
2235             },
2236             i : {    start : 8,
2237                 len   : 1,
2238                 label : "Secondary support material",
2239                 values: {    c : "Cardboard",
2240                         d : "Glass",
2241                         e : "Synthetics",
2242                         h : "metal",
2243                         j : "Metal and glass",
2244                         k : "Synthetics and glass",
2245                         m : "Mixed collection",
2246                         u : "Unknown",
2247                         z : "Other"
2248                 }
2249             }
2250         }
2251     },
2252     r : {
2253         label     : "Remote-sensing Image",
2254         subfields : {
2255             b : {    start : 1,
2256                 len   : 1,
2257                 label : "SMD",
2258                 values: { u : "Unspecified" }
2259             },
2260             d : {    start : 3,
2261                 len   : 1,
2262                 label : "Altitude of sensor",
2263                 values: {    a : "Surface",
2264                         b : "Airborne",
2265                         c : "Spaceborne",
2266                         n : "Not applicable",
2267                         u : "Unknown",
2268                         z : "Other"
2269                 }
2270             },
2271             e : {    start : 4,
2272                 len   : 1,
2273                 label : "Attitude of sensor",
2274                 values: {    a : "Low oblique",
2275                         b : "High oblique",
2276                         c : "Vertical",
2277                         n : "Not applicable",
2278                         u : "Unknown"
2279                 }
2280             },
2281             f : {    start : 5,
2282                 len   : 1,
2283                 label : "Cloud cover",
2284                 values: {    0 : "0-09%",
2285                         1 : "10-19%",
2286                         2 : "20-29%",
2287                         3 : "30-39%",
2288                         4 : "40-49%",
2289                         5 : "50-59%",
2290                         6 : "60-69%",
2291                         7 : "70-79%",
2292                         8 : "80-89%",
2293                         9 : "90-100%",
2294                         n : "Not applicable",
2295                         u : "Unknown"
2296                 }
2297             },
2298             g : {    start : 6,
2299                 len   : 1,
2300                 label : "Platform construction type",
2301                 values: {    a : "Balloon",
2302                         b : "Aircraft-low altitude",
2303                         c : "Aircraft-medium altitude",
2304                         d : "Aircraft-high altitude",
2305                         e : "Manned spacecraft",
2306                         f : "Unmanned spacecraft",
2307                         g : "Land-based remote-sensing device",
2308                         h : "Water surface-based remote-sensing device",
2309                         i : "Submersible remote-sensing device",
2310                         n : "Not applicable",
2311                         u : "Unknown",
2312                         z : "Other"
2313                 }
2314             },
2315             h : {    start : 7,
2316                 len   : 1,
2317                 label : "Platform use category",
2318                 values: {    a : "Meteorological",
2319                         b : "Surface observing",
2320                         c : "Space observing",
2321                         m : "Mixed uses",
2322                         n : "Not applicable",
2323                         u : "Unknown",
2324                         z : "Other"
2325                 }
2326             },
2327             i : {    start : 8,
2328                 len   : 1,
2329                 label : "Sensor type",
2330                 values: {    a : "Active",
2331                         b : "Passive",
2332                         u : "Unknown",
2333                         z : "Other"
2334                 }
2335             },
2336             j : {    start : 9,
2337                 len   : 2,
2338                 label : "Data type",
2339                 values: {    nn : "Not applicable",
2340                         uu : "Unknown",
2341                         zz : "Other",
2342                         aa : "Visible light",
2343                         da : "Near infrared",
2344                         db : "Middle infrared",
2345                         dc : "Far infrared",
2346                         dd : "Thermal infrared",
2347                         de : "Shortwave infrared (SWIR)",
2348                         df : "Reflective infrared",
2349                         dv : "Combinations",
2350                         dz : "Other infrared data",
2351                         ga : "Sidelooking airborne radar (SLAR)",
2352                         gb : "Synthetic aperture radar (SAR-single frequency)",
2353                         gc : "SAR-multi-frequency (multichannel)",
2354                         gd : "SAR-like polarization",
2355                         ge : "SAR-cross polarization",
2356                         gf : "Infometric SAR",
2357                         gg : "Polarmetric SAR",
2358                         gu : "Passive microwave mapping",
2359                         gz : "Other microwave data",
2360                         ja : "Far ultraviolet",
2361                         jb : "Middle ultraviolet",
2362                         jc : "Near ultraviolet",
2363                         jv : "Ultraviolet combinations",
2364                         jz : "Other ultraviolet data",
2365                         ma : "Multi-spectral, multidata",
2366                         mb : "Multi-temporal",
2367                         mm : "Combination of various data types",
2368                         pa : "Sonar-water depth",
2369                         pb : "Sonar-bottom topography images, sidescan",
2370                         pc : "Sonar-bottom topography, near-surface",
2371                         pd : "Sonar-bottom topography, near-bottom",
2372                         pe : "Seismic surveys",
2373                         pz : "Other acoustical data",
2374                         ra : "Gravity anomales (general)",
2375                         rb : "Free-air",
2376                         rc : "Bouger",
2377                         rd : "Isostatic",
2378                         sa : "Magnetic field",
2379                         ta : "Radiometric surveys"
2380                 }
2381             }
2382         }
2383     },
2384     s : {
2385         label     : "Sound Recording",
2386         subfields : {
2387             b : {    start : 1,
2388                 len   : 1,
2389                 label : "SMD",
2390                 values: {    d : "Sound disc",
2391                         e : "Cylinder",
2392                         g : "Sound cartridge",
2393                         i : "Sound-track film",
2394                         q : "Roll",
2395                         s : "Sound cassette",
2396                         t : "Sound-tape reel",
2397                         u : "Unspecified",
2398                         w : "Wire recording",
2399                         z : "Other"
2400                 }
2401             },
2402             d : {    start : 3,
2403                 len   : 1,
2404                 label : "Speed",
2405                 values: {    a : "16 rpm",
2406                         b : "33 1/3 rpm",
2407                         c : "45 rpm",
2408                         d : "78 rpm",
2409                         e : "8 rpm",
2410                         f : "1.4 mps",
2411                         h : "120 rpm",
2412                         i : "160 rpm",
2413                         k : "15/16 ips",
2414                         l : "1 7/8 ips",
2415                         m : "3 3/4 ips",
2416                         o : "7 1/2 ips",
2417                         p : "15 ips",
2418                         r : "30 ips",
2419                         u : "Unknown",
2420                         z : "Other"
2421                 }
2422             },
2423             e : {    start : 4,
2424                 len   : 1,
2425                 label : "Configuration of playback channels",
2426                 values: {    m : "Monaural",
2427                         q : "Quadraphonic",
2428                         s : "Stereophonic",
2429                         u : "Unknown",
2430                         z : "Other"
2431                 }
2432             },
2433             f : {    start : 5,
2434                 len   : 1,
2435                 label : "Groove width or pitch",
2436                 values: {    m : "Microgroove/fine",
2437                         n : "Not applicable",
2438                         s : "Coarse/standard",
2439                         u : "Unknown",
2440                         z : "Other"
2441                 }
2442             },
2443             g : {    start : 6,
2444                 len   : 1,
2445                 label : "Dimensions",
2446                 values: {    a : "3 in.",
2447                         b : "5 in.",
2448                         c : "7 in.",
2449                         d : "10 in.",
2450                         e : "12 in.",
2451                         f : "16 in.",
2452                         g : "4 3/4 in. (12 cm.)",
2453                         j : "3 7/8 x 2 1/2 in.",
2454                         o : "5 1/4 x 3 7/8 in.",
2455                         s : "2 3/4 x 4 in.",
2456                         n : "Not applicable",
2457                         u : "Unknown",
2458                         z : "Other"
2459                 }
2460             },
2461             h : {    start : 7,
2462                 len   : 1,
2463                 label : "Tape width",
2464                 values: {    l : "1/8 in.",
2465                         m : "1/4in.",
2466                         n : "Not applicable",
2467                         o : "1/2 in.",
2468                         p : "1 in.",
2469                         u : "Unknown",
2470                         z : "Other"
2471                 }
2472             },
2473             i : {    start : 8,
2474                 len   : 1,
2475                 label : "Tape configuration ",
2476                 values: {    a : "Full (1) track",
2477                         b : "Half (2) track",
2478                         c : "Quarter (4) track",
2479                         d : "8 track",
2480                         e : "12 track",
2481                         f : "16 track",
2482                         n : "Not applicable",
2483                         u : "Unknown",
2484                         z : "Other"
2485                 }
2486             },
2487             m : {    start : 12,
2488                 len   : 1,
2489                 label : "Special playback",
2490                 values: {    a : "NAB standard",
2491                         b : "CCIR standard",
2492                         c : "Dolby-B encoded, standard Dolby",
2493                         d : "dbx encoded",
2494                         e : "Digital recording",
2495                         f : "Dolby-A encoded",
2496                         g : "Dolby-C encoded",
2497                         h : "CX encoded",
2498                         n : "Not applicable",
2499                         u : "Unknown",
2500                         z : "Other"
2501                 }
2502             },
2503             n : {    start : 13,
2504                 len   : 1,
2505                 label : "Capture and storage",
2506                 values: {    a : "Acoustical capture, direct storage",
2507                         b : "Direct storage, not acoustical",
2508                         d : "Digital storage",
2509                         e : "Analog electrical storage",
2510                         u : "Unknown",
2511                         z : "Other"
2512                 }
2513             }
2514         }
2515     },
2516     f : {
2517         label     : "Tactile Material",
2518         subfields : {
2519             b : {    start : 1,
2520                 len   : 1,
2521                 label : "SMD",
2522                 values: {    a : "Moon",
2523                         b : "Braille",
2524                         c : "Combination",
2525                         d : "Tactile, with no writing system",
2526                         u : "Unspecified",
2527                         z : "Other"
2528                 }
2529             },
2530             d : {    start : 3,
2531                 len   : 2,
2532                 label : "Class of braille writing",
2533                 values: {    a : "Literary braille",
2534                         b : "Format code braille",
2535                         c : "Mathematics and scientific braille",
2536                         d : "Computer braille",
2537                         e : "Music braille",
2538                         m : "Multiple braille types",
2539                         n : "Not applicable",
2540                         u : "Unknown",
2541                         z : "Other"
2542                 }
2543             },
2544             e : {    start : 4,
2545                 len   : 1,
2546                 label : "Level of contraction",
2547                 values: {    a : "Uncontracted",
2548                         b : "Contracted",
2549                         m : "Combination",
2550                         n : "Not applicable",
2551                         u : "Unknown",
2552                         z : "Other"
2553                 }
2554             },
2555             f : {    start : 6,
2556                 len   : 3,
2557                 label : "Braille music format",
2558                 values: {    a : "Bar over bar",
2559                         b : "Bar by bar",
2560                         c : "Line over line",
2561                         d : "Paragraph",
2562                         e : "Single line",
2563                         f : "Section by section",
2564                         g : "Line by line",
2565                         h : "Open score",
2566                         i : "Spanner short form scoring",
2567                         j : "Short form scoring",
2568                         k : "Outline",
2569                         l : "Vertical score",
2570                         n : "Not applicable",
2571                         u : "Unknown",
2572                         z : "Other"
2573                 }
2574             },
2575             g : {    start : 9,
2576                 len   : 1,
2577                 label : "Special physical characteristics",
2578                 values: {    a : "Print/braille",
2579                         b : "Jumbo or enlarged braille",
2580                         n : "Not applicable",
2581                         u : "Unknown",
2582                         z : "Other"
2583                 }
2584             }
2585         }
2586     },
2587     v : {
2588         label     : "Videorecording",
2589         subfields : {
2590             b : {    start : 1,
2591                 len   : 1,
2592                 label : "SMD",
2593                 values: {     c : "Videocartridge",
2594                         d : "Videodisc",
2595                         f : "Videocassette",
2596                         r : "Videoreel",
2597                         u : "Unspecified",
2598                         z : "Other"
2599                 }
2600             },
2601             d : {    start : 3,
2602                 len   : 1,
2603                 label : "Color",
2604                 values: {    b : "Black-and-white",
2605                         c : "Multicolored",
2606                         m : "Mixed",
2607                         n : "Not applicable",
2608                         u : "Unknown",
2609                         z : "Other"
2610                 }
2611             },
2612             e : {    start : 4,
2613                 len   : 1,
2614                 label : "Videorecording format",
2615                 values: {    a : "Beta",
2616                         b : "VHS",
2617                         c : "U-matic",
2618                         d : "EIAJ",
2619                         e : "Type C",
2620                         f : "Quadruplex",
2621                         g : "Laserdisc",
2622                         h : "CED",
2623                         i : "Betacam",
2624                         j : "Betacam SP",
2625                         k : "Super-VHS",
2626                         m : "M-II",
2627                         o : "D-2",
2628                         p : "8 mm.",
2629                         q : "Hi-8 mm.",
2630                         u : "Unknown",
2631                         v : "DVD",
2632                         z : "Other"
2633                 }
2634             },
2635             f : {    start : 5,
2636                 len   : 1,
2637                 label : "Sound on medium or separate",
2638                 values: {    a : "Sound on medium",
2639                         b : "Sound separate from medium",
2640                         u : "Unknown"
2641                 }
2642             },
2643             g : {    start : 6,
2644                 len   : 1,
2645                 label : "Medium for sound",
2646                 values: {    a : "Optical sound track on motion picture film",
2647                         b : "Magnetic sound track on motion picture film",
2648                         c : "Magnetic audio tape in cartridge",
2649                         d : "Sound disc",
2650                         e : "Magnetic audio tape on reel",
2651                         f : "Magnetic audio tape in cassette",
2652                         g : "Optical and magnetic sound track on motion picture film",
2653                         h : "Videotape",
2654                         i : "Videodisc",
2655                         u : "Unknown",
2656                         z : "Other"
2657                 }
2658             },
2659             h : {    start : 7,
2660                 len   : 1,
2661                 label : "Dimensions",
2662                 values: {    a : "8 mm.",
2663                         m : "1/4 in.",
2664                         o : "1/2 in.",
2665                         p : "1 in.",
2666                         q : "2 in.",
2667                         r : "3/4 in.",
2668                         u : "Unknown",
2669                         z : "Other"
2670                 }
2671             },
2672             i : {    start : 8,
2673                 len   : 1,
2674                 label : "Configuration of playback channel",
2675                 values: {    k : "Mixed",
2676                         m : "Monaural",
2677                         n : "Not applicable",
2678                         q : "Multichannel, surround or quadraphonic",
2679                         s : "Stereophonic",
2680                         u : "Unknown",
2681                         z : "Other"
2682                 }
2683             }
2684         }
2685     }
2686 };
2687
2688 MARC21.AuthorityControlSet._remote_loaded = false;
2689 MARC21.AuthorityControlSet._remote_parsed = false;
2690
2691 MARC21.AuthorityControlSet._controlsets = {
2692     // static sorta-LoC setup ... to be overwritten with server data 
2693     '-1' : {
2694         id : -1,
2695         name : 'Static LoC legacy mapping',
2696         description : 'Legacy mapping provided as a default',
2697         control_map : {
2698             100 : {
2699                 'a' : { 100 : 'a' },
2700                 'd' : { 100 : 'd' },
2701                 'e' : { 100 : 'e' },
2702                 'q' : { 100 : 'q' }
2703             },
2704             110 : {
2705                 'a' : { 110 : 'a' },
2706                 'd' : { 110 : 'd' }
2707             },
2708             111 : {
2709                 'a' : { 111 : 'a' },
2710                 'd' : { 111 : 'd' }
2711             },
2712             130 : {
2713                 'a' : { 130 : 'a' },
2714                 'd' : { 130 : 'd' }
2715             },
2716             240 : {
2717                 'a' : { 130 : 'a' },
2718                 'd' : { 130 : 'd' }
2719             },
2720             400 : {
2721                 'a' : { 100 : 'a' },
2722                 'd' : { 100 : 'd' }
2723             },
2724             410 : {
2725                 'a' : { 110 : 'a' },
2726                 'd' : { 110 : 'd' }
2727             },
2728             411 : {
2729                 'a' : { 111 : 'a' },
2730                 'd' : { 111 : 'd' }
2731             },
2732             440 : {
2733                 'a' : { 130 : 'a' },
2734                 'n' : { 130 : 'n' },
2735                 'p' : { 130 : 'p' }
2736             },
2737             700 : {
2738                 'a' : { 100 : 'a' },
2739                 'd' : { 100 : 'd' },
2740                 'q' : { 100 : 'q' },
2741                 't' : { 100 : 't' }
2742             },
2743             710 : {
2744                 'a' : { 110 : 'a' },
2745                 'd' : { 110 : 'd' }
2746             },
2747             711 : {
2748                 'a' : { 111 : 'a' },
2749                 'c' : { 111 : 'c' },
2750                 'd' : { 111 : 'd' }
2751             },
2752             730 : {
2753                 'a' : { 130 : 'a' },
2754                 'd' : { 130 : 'd' }
2755             },
2756             800 : {
2757                 'a' : { 100 : 'a' },
2758                 'd' : { 100 : 'd' }
2759             },
2760             810 : {
2761                 'a' : { 110 : 'a' },
2762                 'd' : { 110 : 'd' }
2763             },
2764             811 : {
2765                 'a' : { 111 : 'a' },
2766                 'd' : { 111 : 'd' }
2767             },
2768             830 : {
2769                 'a' : { 130 : 'a' },
2770                 'd' : { 130 : 'd' }
2771             },
2772             600 : {
2773                 'a' : { 100 : 'a' },
2774                 'd' : { 100 : 'd' },
2775                 'q' : { 100 : 'q' },
2776                 't' : { 100 : 't' },
2777                 'v' : { 180 : 'v',
2778                     100 : 'v',
2779                     181 : 'v',
2780                     182 : 'v',
2781                     185 : 'v'
2782                 },
2783                 'x' : { 180 : 'x',
2784                     100 : 'x',
2785                     181 : 'x',
2786                     182 : 'x',
2787                     185 : 'x'
2788                 },
2789                 'y' : { 180 : 'y',
2790                     100 : 'y',
2791                     181 : 'y',
2792                     182 : 'y',
2793                     185 : 'y'
2794                 },
2795                 'z' : { 180 : 'z',
2796                     100 : 'z',
2797                     181 : 'z',
2798                     182 : 'z',
2799                     185 : 'z'
2800                 }
2801             },
2802             610 : {
2803                 'a' : { 110 : 'a' },
2804                 'd' : { 110 : 'd' },
2805                 't' : { 110 : 't' },
2806                 'v' : { 180 : 'v',
2807                     110 : 'v',
2808                     181 : 'v',
2809                     182 : 'v',
2810                     185 : 'v'
2811                 },
2812                 'x' : { 180 : 'x',
2813                     110 : 'x',
2814                     181 : 'x',
2815                     182 : 'x',
2816                     185 : 'x'
2817                 },
2818                 'y' : { 180 : 'y',
2819                     110 : 'y',
2820                     181 : 'y',
2821                     182 : 'y',
2822                     185 : 'y'
2823                 },
2824                 'z' : { 180 : 'z',
2825                     110 : 'z',
2826                     181 : 'z',
2827                     182 : 'z',
2828                     185 : 'z'
2829                 }
2830             },
2831             611 : {
2832                 'a' : { 111 : 'a' },
2833                 'd' : { 111 : 'd' },
2834                 't' : { 111 : 't' },
2835                 'v' : { 180 : 'v',
2836                     111 : 'v',
2837                     181 : 'v',
2838                     182 : 'v',
2839                     185 : 'v'
2840                 },
2841                 'x' : { 180 : 'x',
2842                     111 : 'x',
2843                     181 : 'x',
2844                     182 : 'x',
2845                     185 : 'x'
2846                 },
2847                 'y' : { 180 : 'y',
2848                     111 : 'y',
2849                     181 : 'y',
2850                     182 : 'y',
2851                     185 : 'y'
2852                 },
2853                 'z' : { 180 : 'z',
2854                     111 : 'z',
2855                     181 : 'z',
2856                     182 : 'z',
2857                     185 : 'z'
2858                 }
2859             },
2860             630 : {
2861                 'a' : { 130 : 'a' },
2862                 'd' : { 130 : 'd' }
2863             },
2864             648 : {
2865                 'a' : { 148 : 'a' },
2866                 'v' : { 148 : 'v' },
2867                 'x' : { 148 : 'x' },
2868                 'y' : { 148 : 'y' },
2869                 'z' : { 148 : 'z' }
2870             },
2871             650 : {
2872                 'a' : { 150 : 'a' },
2873                 'b' : { 150 : 'b' },
2874                 'v' : { 180 : 'v',
2875                     150 : 'v',
2876                     181 : 'v',
2877                     182 : 'v',
2878                     185 : 'v'
2879                 },
2880                 'x' : { 180 : 'x',
2881                     150 : 'x',
2882                     181 : 'x',
2883                     182 : 'x',
2884                     185 : 'x'
2885                 },
2886                 'y' : { 180 : 'y',
2887                     150 : 'y',
2888                     181 : 'y',
2889                     182 : 'y',
2890                     185 : 'y'
2891                 },
2892                 'z' : { 180 : 'z',
2893                     150 : 'z',
2894                     181 : 'z',
2895                     182 : 'z',
2896                     185 : 'z'
2897                 }
2898             },
2899             651 : {
2900                 'a' : { 151 : 'a' },
2901                 'v' : { 180 : 'v',
2902                     151 : 'v',
2903                     181 : 'v',
2904                     182 : 'v',
2905                     185 : 'v'
2906                 },
2907                 'x' : { 180 : 'x',
2908                     151 : 'x',
2909                     181 : 'x',
2910                     182 : 'x',
2911                     185 : 'x'
2912                 },
2913                 'y' : { 180 : 'y',
2914                     151 : 'y',
2915                     181 : 'y',
2916                     182 : 'y',
2917                     185 : 'y'
2918                 },
2919                 'z' : { 180 : 'z',
2920                     151 : 'z',
2921                     181 : 'z',
2922                     182 : 'z',
2923                     185 : 'z'
2924                 }
2925             },
2926             655 : {
2927                 'a' : { 155 : 'a' },
2928                 'v' : { 180 : 'v',
2929                     155 : 'v',
2930                     181 : 'v',
2931                     182 : 'v',
2932                     185 : 'v'
2933                 },
2934                 'x' : { 180 : 'x',
2935                     155 : 'x',
2936                     181 : 'x',
2937                     182 : 'x',
2938                     185 : 'x'
2939                 },
2940                 'y' : { 180 : 'y',
2941                     155 : 'y',
2942                     181 : 'y',
2943                     182 : 'y',
2944                     185 : 'y'
2945                 },
2946                 'z' : { 180 : 'z',
2947                     155 : 'z',
2948                     181 : 'z',
2949                     182 : 'z',
2950                     185 : 'z'
2951                 }
2952             }
2953         }
2954     }
2955 };
2956