1 /* ---------------------------------------------------------------------------
2 * Copyright (C) 2009-2015 Equinox Software, Inc.
3 * Mike Rylander <miker@esilibrary.com>
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.
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 * ---------------------------------------------------------------------------
18 // This module requires a /real/ jQuery be used with your
19 // angularjs, so as to avoid using hand-rolled AJAX.
23 Record : function(kwargs) {
24 if (!kwargs) kwargs = {};
26 this.title = function () { return this.subfield('245','a')[1] }
28 this.field = function (spec) {
29 var list = this.fields.filter(function (f) {
30 if (f.tag.match(spec)) return true;
34 if (list.length == 1) return list[0];
38 this.subfield = function (spec, code) {
39 var f = this.field(spec);
40 if (Array.isArray(f)) {
41 if (!f.length) return f;
44 return f.subfield(code)
47 this.appendFields = function () {
49 Array.prototype.slice.call(arguments).forEach( function (f) { me.fields.push( f ) } );
52 this.deleteField = function (f) { return this.deleteFields(f) },
54 this.insertOrderedFields = function () {
56 for (var i = 0; i < arguments.length; i++) {
59 for (var j = 0; j < this.fields.length; j++) {
60 if (f.tag < this.fields[j].tag) {
61 this.insertFieldsBefore(this.fields[j], f);
66 if (!done) this.appendFields(f);
70 this.insertFieldsBefore = function (target) {
71 var args = Array.prototype.slice.call(arguments);
74 for (var j = 0; j < this.fields.length; j++) {
75 if (target === this.fields[j]) {
77 args.forEach( function (f) {
78 me.fields.splice(j++,0,f);
85 this.insertFieldsAfter = function (target) {
86 var args = Array.prototype.slice.call(arguments);
89 for (var j = 0; j < this.fields.length; j++) {
90 if (target === this.fields[j]) {
91 args.forEach( function (f) {
92 me.fields.splice(j++,0,f);
99 this.deleteFields = function () {
102 for ( var i in arguments ) {
103 var f = arguments[i];
104 for (var j = 0; j < me.fields.length; j++) {
105 if (f === me.fields[j]) {
106 me.fields[j].record = null;
107 me.fields.splice(j,0);
116 // this.clone = function () { return dojo.clone(this) } // maybe implement later...
118 this.fromXmlURL = function (url) {
120 return $.get( // This is a Promise
123 me.fromXmlDocument($('record', mxml)[0]);
124 if (me.onLoad) me.onLoad();
128 this.fromXmlString = function (mxml) {
129 this.fromXmlDocument( $( $.parseXML( mxml ) ).find('record')[0] );
132 this.fromXmlDocument = function (mxml) {
134 me.leader = $($('leader',mxml)[0]).text() || '00000cam a2200205Ka 4500';
136 $('controlfield', mxml).each(function (ind) {
141 tag : cf.attr('tag'),
148 var cfield_count = me.fields.length + 1;
150 $('datafield', mxml).each(function (ind) {
155 tag : df.attr('tag'),
156 ind1 : df.attr('ind1'),
157 ind2 : df.attr('ind2'),
158 position : ind + cfield_count,
159 subfields : $('subfield', df).map(
161 return [[ $(sf).attr('code'), $(sf).text(), i ]];
171 this.toXmlDocument = function () {
173 var doc = $.parseXML('<record xmlns="http://www.loc.gov/MARC21/slim"/>');
174 var rec_node = $('record', doc)[0];
176 var ldr = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'leader');
177 ldr.textContent = this.leader;
178 rec_node.appendChild( ldr );
180 this.fields.forEach(function (f) {
181 var element = f.isControlfield() ? 'controlfield' : 'datafield';
182 var f_node = doc.createElementNS( 'http://www.loc.gov/MARC21/slim', element );
183 f_node.setAttribute('tag', f.tag);
185 if (f.isControlfield()) {
186 if (f.data) f_node.textContent = f.data;
188 f_node.setAttribute('ind1', f.indicator(1));
189 f_node.setAttribute('ind2', f.indicator(2));
190 f.subfields.forEach( function (sf) {
191 var sf_node = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'subfield');
192 sf_node.setAttribute('code', sf[0]);
193 sf_node.textContent = sf[1];
194 f_node.appendChild(sf_node);
198 rec_node.appendChild(f_node);
204 this.toXmlString = function () {
205 return (new XMLSerializer()).serializeToString( this.toXmlDocument() );
208 this.fromBreaker = function (marctxt) {
211 function cf_line_data (l) { return l.substring(4) || '' };
212 function df_line_data (l) { return l.substring(6) || '' };
213 function line_tag (l) { return l.substring(0,3) };
214 function df_ind1 (l) { return l.substring(4,5).replace('\\',' ') };
215 function df_ind2 (l) { return l.substring(5,6).replace('\\',' ') };
216 function isControlField (l) {
218 return (x == 'LDR' || x < '010') ? true : false;
221 var lines = marctxt.replace(/^=/gm,'').split('\n');
222 lines.forEach(function (current_line, ind) {
224 if (current_line.match(/^#/)) {
225 // skip comment lines
226 } else if (isControlField(current_line)) {
227 if (line_tag(current_line) == 'LDR') {
228 me.leader = cf_line_data(current_line) || '00000cam a2200205Ka 4500';
233 tag : line_tag(current_line),
234 data : cf_line_data(current_line).replace('\\',' ','g'),
240 if (current_line.substring(4,5) == me.delimiter) // add delimiters if they were left out
241 current_line = current_line.substring(0,3) + ' \\\\' + current_line.substring(4);
243 var data = df_line_data(current_line);
244 if (!(data.substring(0,1) == me.delimiter)) data = me.delimiter + 'a' + data;
246 var sf_list = data.split(me.delimiter);
252 tag : line_tag(current_line),
253 ind1 : df_ind1(current_line),
254 ind2 : df_ind2(current_line),
256 subfields : sf_list.map( function (sf, i) {
257 var sf_data = sf.substring(1);
258 if (me.delimiter == '$') sf_data = sf_data.replace(/\{dollar\}/g, '$');
259 return [ sf.substring(0,1), sf_data, i ];
270 this.toBreaker = function () {
273 var mtxt = '=LDR ' + this.leader + '\n';
275 mtxt += this.fields.map( function (f) {
276 if (f.isControlfield()) {
277 if (f.data) return '=' + f.tag + ' ' + f.data.replace(' ','\\','g');
280 return '=' + f.tag + ' ' +
281 f.indicator(1).replace(' ','\\') +
282 f.indicator(2).replace(' ','\\') +
283 f.subfields.map( function (sf) {
285 if (me.delimiter == '$') sf_data = sf_data.replace(/\$/g, '{dollar}');
286 return me.delimiter + sf[0] + sf_data;
294 this.recordType = function () {
296 var _t = this.leader.substr(MARC.Record._ff_pos.Type.ldr.BKS.start, MARC.Record._ff_pos.Type.ldr.BKS.len);
297 var _b = this.leader.substr(MARC.Record._ff_pos.BLvl.ldr.BKS.start, MARC.Record._ff_pos.BLvl.ldr.BKS.len);
299 for (var t in MARC.Record._recType) {
300 if (_t.match(MARC.Record._recType[t].Type) && _b.match(MARC.Record._recType[t].BLvl)) {
304 return 'BKS'; // default
307 this.videorecordingFormatName = function () {
308 var _7 = this.field('007').data;
310 if (_7 && _7.match(/^v/)) {
311 var _v_e = _7.substr(
312 MARC.Record._physical_characteristics.v.subfields.e.start,
313 MARC.Record._physical_characteristics.v.subfields.e.len
316 return MARC.Record._physical_characteristics.v.subfields.e.values[ _v_e ];
322 this.videorecordingFormatCode = function () {
323 var _7 = this.field('007').data;
325 if (_7 && _7.match(/^v/)) {
327 MARC.Record._physical_characteristics.v.subfields.e.start,
328 MARC.Record._physical_characteristics.v.subfields.e.len
335 this.extractFixedField = function (field, dflt) {
336 if (!MARC.Record._ff_pos[field]) return null;
338 var _l = this.leader;
339 var _8 = this.field('008').data;
340 var _6 = this.field('006').data;
342 var rtype = this.recordType();
346 if (MARC.Record._ff_pos[field].ldr && _l) {
347 if (MARC.Record._ff_pos[field].ldr[rtype]) {
349 MARC.Record._ff_pos[field].ldr[rtype].start,
350 MARC.Record._ff_pos[field].ldr[rtype].len
353 } else if (MARC.Record._ff_pos[field]._8 && _8) {
354 if (MARC.Record._ff_pos[field]._8[rtype]) {
356 MARC.Record._ff_pos[field]._8[rtype].start,
357 MARC.Record._ff_pos[field]._8[rtype].len
362 if (!val && MARC.Record._ff_pos[field]._6 && _6) {
363 if (MARC.Record._ff_pos[field]._6[rtype]) {
365 MARC.Record._ff_pos[field]._6[rtype].start,
366 MARC.Record._ff_pos[field]._6[rtype].len
375 if (MARC.Record._ff_pos[field].ldr && MARC.Record._ff_pos[field].ldr[rtype]) {
376 d = MARC.Record._ff_pos[field].ldr[rtype].def;
380 if (MARC.Record._ff_pos[field]._8 && MARC.Record._ff_pos[field]._8[rtype]) {
381 d = MARC.Record._ff_pos[field]._8[rtype].def;
385 if (!val && MARC.Record._ff_pos[field]._6 && MARC.Record._ff_pos[field]._6[rtype]) {
386 d = MARC.Record._ff_pos[field]._6[rtype].def;
391 for (var j = 0; j < MARC.Record._ff_pos[field][p][rtype].len; j++) {
402 this.setFixedField = function (field, value) {
403 if (!MARC.Record._ff_pos[field]) return null;
405 var _l = this.leader;
406 var _8 = this.field('008').data;
407 var _6 = this.field('006').data;
409 var rtype = this.recordType();
413 if (MARC.Record._ff_pos[field].ldr && _l) {
414 if (MARC.Record._ff_pos[field].ldr[rtype]) { // It's in the leader
415 val = value.substr(0, MARC.Record._ff_pos[field].ldr[rtype].len);
417 _l.substring(0, MARC.Record._ff_pos[field].ldr[rtype].start) +
420 MARC.Record._ff_pos[field].ldr[rtype].start
421 + MARC.Record._ff_pos[field].ldr[rtype].len
424 } else if (MARC.Record._ff_pos[field]._8 && _8) {
425 if (MARC.Record._ff_pos[field]._8[rtype]) { // Nope, it's in the 008
426 val = value.substr(0, MARC.Record._ff_pos[field]._8[rtype].len);
427 this.field('008').update(
428 _8.substring(0, MARC.Record._ff_pos[field]._8[rtype].start) +
431 MARC.Record._ff_pos[field]._8[rtype].start
432 + MARC.Record._ff_pos[field]._8[rtype].len
438 if (!val && MARC.Record._ff_pos[field]._6 && _6) {
439 if (MARC.Record._ff_pos[field]._6[rtype]) { // ok, maybe the 006?
440 val = value.substr(0, MARC.Record._ff_pos[field]._6[rtype].len);
441 this.field('006').update(
442 _6.substring(0, MARC.Record._ff_pos[field]._6[rtype].start) +
445 MARC.Record._ff_pos[field]._6[rtype].start
446 + MARC.Record._ff_pos[field]._6[rtype].len
457 this.delimiter = '\u2021';
458 this.leader = '00000cam a2200205Ka 4500';
460 if (kwargs.delimiter) this.delimiter = kwargs.delimiter;
461 if (kwargs.onLoad) this.onLoad = kwargs.onLoad;
464 this.fromXmlURL(kwargs.url);
465 } else if (kwargs.marcxml) {
466 this.fromXmlString(kwargs.marcxml);
467 if (this.onLoad) this.onLoad();
468 } else if (kwargs.xml) {
469 this.fromXmlDocument(kwargs.xml);
470 if (this.onLoad) this.onLoad();
471 } else if (kwargs.marcbreaker) {
472 this.fromBreaker(kwargs.marcbreaker);
473 if (this.onLoad) this.onLoad();
476 if (kwargs.rtype == 'AUT') {
477 this.setFixedField('Type','z');
482 Field : function (kwargs) {
483 if (!kwargs) kwargs = {};
485 this.subfield = function (code) {
486 var list = this.subfields.filter( function (s) {
487 if (s[0] == code) return true; return false;
489 if (list.length == 1) return list[0];
493 this.addSubfields = function () {
494 for (var i = 0; i < arguments.length; i++) {
495 var code = arguments[i];
496 var value = arguments[++i];
497 this.subfields.push( [ code, value ] );
501 this.deleteSubfields = function (c) {
502 return this.deleteSubfield( { code : c } );
505 this.deleteSubfield = function (args) {
507 if (!Array.isArray( args.code )) {
508 args.code = [ args.code ];
511 if (args.pos && !Array.isArray( args.pos )) {
512 args.pos = [ args.pos ];
515 for (var i = 0; i < args.code.length; i++) {
517 for (var j = 0; j < me.subfields; j++) {
518 if (me.subfields[j][0] == args.code[i]) {
520 if (!sub_pos[args.code[i]]) sub_pos[args.code[j]] = 0;
521 else sub_pos[args.code[i]]++;
524 for (var k = 0; k < args.pos.length; k++) {
525 if (sub_pos[args.code[i]] == args.pos[k]) me.subfields.splice(j,1);
527 } else if (args.match && me.subfields[j][1].match( args.match )) {
528 me.subfields.splice(j,1);
530 me.subfields.splice(j,1);
537 this.update = function ( args ) {
538 if (this.isControlfield()) {
541 if (args.ind1) this.ind1 = args.ind1;
542 if (args.ind2) this.ind2 = args.ind2;
543 if (args.tag) this.tag = args.tag;
545 for (var i in args) {
546 if (i == 'tag' || i == 'ind1' || i == 'ind2') continue;
548 this.subfields.forEach( function (f) {
549 if (!done && f[0] == i) {
558 this.isControlfield = function () {
559 return this.tag < '010' ? true : false;
562 this.indicator = function (num, value) {
563 if (value !== undefined) {
564 if (num == 1) this.ind1 = value;
565 else if (num == 2) this.ind2 = value;
566 else { this.error = true; return null; }
568 if (num == 1) return this.ind1;
569 else if (num == 2) return this.ind2;
570 else { this.error = true; return null; }
574 this.record = null; // MARC record pointer
575 this.tag = ''; // MARC tag
576 this.ind1 = ' '; // MARC indicator 1
577 this.ind2 = ' '; // MARC indicator 2
578 this.data = ''; // MARC data for a controlfield element
579 this.subfields = []; // list of MARC subfields for a datafield element
581 this.position = kwargs.position;
582 this.record = kwargs.record;
583 this.tag = kwargs.tag;
584 this.ind1 = kwargs.ind1 || ' ';
585 this.ind2 = kwargs.ind2 || ' ';
586 this.data = kwargs.data;
588 if (kwargs.subfields) this.subfields = kwargs.subfields;
589 else this.subfields = [];
593 Batch : function(kwargs) {
595 this.parse = function () {
596 if (this.source instanceof Object ) { // assume an xml collection document
597 this.source = $('record', this.source);
599 } else if (this.source.match(/^\s*</)) { // this is xml text
600 this.source = $.parseXML( mxml ).find('record');
602 } else { // must be a marcbreaker doc. split on blank lines
603 this.source = this.source.split(/^$/);
604 this.type = 'marcbreaker';
608 this.fetchURL = function (u) {
610 $.get( u, function (mrc) {
616 this.next = function () {
617 var chunk = this.source[this.current_record++];
621 args[this.type] = chunk;
622 if (this.delimiter) args.delimiter = this.delimiter;
623 return new MARC.Record(args);
631 this.source = kwargs.source;
632 this.delimiter = kwargs.delimiter
633 this.current_record = 0;
635 if (this.source) this.ready = true;
636 if (!this.ready && kwargs.url) this.fetchURL( kwargs.url );
638 if (this.ready) this.parse();
643 MARC.Record._recType = {
644 BKS : { Type : /[at]{1}/, BLvl : /[acdm]{1}/ },
645 SER : { Type : /[a]{1}/, BLvl : /[bsi]{1}/ },
646 VIS : { Type : /[gkro]{1}/, BLvl : /[abcdmsi]{1}/ },
647 MIX : { Type : /[p]{1}/, BLvl : /[cdi]{1}/ },
648 MAP : { Type : /[ef]{1}/, BLvl : /[abcdmsi]{1}/ },
649 SCO : { Type : /[cd]{1}/, BLvl : /[abcdmsi]{1}/ },
650 REC : { Type : /[ij]{1}/, BLvl : /[abcdmsi]{1}/ },
651 COM : { Type : /[m]{1}/, BLvl : /[abcdmsi]{1}/ },
652 AUT : { Type : /[z]{1}/, BLvl : /.{1}/ },
653 MFHD : { Type : /[uvxy]{1}/, BLvl : /.{1}/ }
656 MARC.Record._ff_pos = {
659 SCO : {start: 24, len : 6, def : ' ' },
660 REC : {start: 24, len : 6, def : ' ' }
663 SCO : {start: 7, len : 6, def : ' ' },
664 REC : {start: 7, len : 6, def : ' ' }
669 SER : {start : 33, len : 1, def : ' ' }
672 SER : {start : 16, len : 1, def : ' ' }
677 BKS : {start : 22, len : 1, def : ' ' },
678 SER : {start : 22, len : 1, def : ' ' },
679 VIS : {start : 22, len : 1, def : ' ' },
680 SCO : {start : 22, len : 1, def : ' ' },
681 REC : {start : 22, len : 1, def : ' ' },
682 COM : {start : 22, len : 1, def : ' ' }
685 BKS : {start : 5, len : 1, def : ' ' },
686 SER : {start : 5, len : 1, def : ' ' },
687 VIS : {start : 5, len : 1, def : ' ' },
688 SCO : {start : 5, len : 1, def : ' ' },
689 REC : {start : 5, len : 1, def : ' ' },
690 COM : {start : 5, len : 1, def : ' ' }
695 BKS : {start : 34, len : 1, def : ' ' }
698 BKS : {start : 17, len : 1, def : ' ' }
703 BKS : {start : 7, len : 1, def : 'm' },
704 SER : {start : 7, len : 1, def : 's' },
705 VIS : {start : 7, len : 1, def : 'm' },
706 MIX : {start : 7, len : 1, def : 'c' },
707 MAP : {start : 7, len : 1, def : 'm' },
708 SCO : {start : 7, len : 1, def : 'm' },
709 REC : {start : 7, len : 1, def : 'm' },
710 COM : {start : 7, len : 1, def : 'm' }
715 SCO : {start : 18, len : 2, def : 'uu'},
716 REC : {start : 18, len : 2, def : 'uu'}
719 SCO : {start : 1, len : 2, def : 'uu'},
720 REC : {start : 1, len : 2, def : 'uu'}
725 BKS : {start : 29, len : 1, def : '0' },
726 SER : {start : 29, len : 1, def : '0' }
729 BKS : {start : 11, len : 1, def : '0' },
730 SER : {start : 11, len : 1, def : '0' }
735 BKS : {start : 24, len : 4, def : ' ' },
736 SER : {start : 25, len : 3, def : ' ' }
739 BKS : {start : 7, len : 4, def : ' ' },
740 SER : {start : 8, len : 3, def : ' ' }
745 MAP : {start: 25, len : 1, def : 'a' }
748 MAP : {start : 8, len : 1, def : 'a' }
753 BKS : {start : 8, len : 1, def : ' ' },
754 SER : {start : 8, len : 1, def : ' ' },
755 VIS : {start : 8, len : 1, def : ' ' },
756 MIX : {start : 8, len : 1, def : ' ' },
757 MAP : {start : 8, len : 1, def : ' ' },
758 SCO : {start : 8, len : 1, def : ' ' },
759 REC : {start : 8, len : 1, def : ' ' },
760 COM : {start : 8, len : 1, def : ' ' }
765 BKS : {start : 15, len : 3, def : ' ' },
766 SER : {start : 15, len : 3, def : ' ' },
767 VIS : {start : 15, len : 3, def : ' ' },
768 MIX : {start : 15, len : 3, def : ' ' },
769 MAP : {start : 15, len : 3, def : ' ' },
770 SCO : {start : 15, len : 3, def : ' ' },
771 REC : {start : 15, len : 3, def : ' ' },
772 COM : {start : 15, len : 3, def : ' ' }
777 BKS : {start : 7, len : 4, def : ' ' },
778 SER : {start : 7, len : 4, def : ' ' },
779 VIS : {start : 7, len : 4, def : ' ' },
780 MIX : {start : 7, len : 4, def : ' ' },
781 MAP : {start : 7, len : 4, def : ' ' },
782 SCO : {start : 7, len : 4, def : ' ' },
783 REC : {start : 7, len : 4, def : ' ' },
784 COM : {start : 7, len : 4, def : ' ' }
789 BKS : {start : 11, len : 4, def : ' ' },
790 SER : {start : 11, len : 4, def : '9' },
791 VIS : {start : 11, len : 4, def : ' ' },
792 MIX : {start : 11, len : 4, def : ' ' },
793 MAP : {start : 11, len : 4, def : ' ' },
794 SCO : {start : 11, len : 4, def : ' ' },
795 REC : {start : 11, len : 4, def : ' ' },
796 COM : {start : 11, len : 4, def : ' ' }
801 BKS : {start : 18, len : 1, def : ' ' },
802 SER : {start : 18, len : 1, def : ' ' },
803 VIS : {start : 18, len : 1, def : ' ' },
804 MIX : {start : 18, len : 1, def : ' ' },
805 MAP : {start : 18, len : 1, def : ' ' },
806 SCO : {start : 18, len : 1, def : ' ' },
807 REC : {start : 18, len : 1, def : ' ' },
808 COM : {start : 18, len : 1, def : ' ' }
813 BKS : {start : 6, len : 1, def : ' ' },
814 SER : {start : 6, len : 1, def : 'c' },
815 VIS : {start : 6, len : 1, def : ' ' },
816 MIX : {start : 6, len : 1, def : ' ' },
817 MAP : {start : 6, len : 1, def : ' ' },
818 SCO : {start : 6, len : 1, def : ' ' },
819 REC : {start : 6, len : 1, def : ' ' },
820 COM : {start : 6, len : 1, def : ' ' }
825 BKS : {start : 17, len : 1, def : ' ' },
826 SER : {start : 17, len : 1, def : ' ' },
827 VIS : {start : 17, len : 1, def : ' ' },
828 MIX : {start : 17, len : 1, def : ' ' },
829 MAP : {start : 17, len : 1, def : ' ' },
830 SCO : {start : 17, len : 1, def : ' ' },
831 REC : {start : 17, len : 1, def : ' ' },
832 COM : {start : 17, len : 1, def : ' ' },
833 AUT : {start : 17, len : 1, def : 'n' },
834 MFHD : {start : 17, len : 1, def : 'u' }
839 SER : {start : 24, len : 1, def : ' '}
842 SER : {start : 7, len : 1, def : ' '}
847 BKS : {start : 30, len : 1, def : '0' }
850 BKS : {start : 13, len : 1, def : '0' }
855 COM : {start: 26, len : 1, def : 'u' }
858 COM : {start: 9, len : 1, def : 'u' }
863 SCO : {start : 20, len : 1, def : 'u'},
864 REC : {start : 20, len : 1, def : 'n'}
867 SCO : {start : 3, len : 1, def : 'u'},
868 REC : {start : 3, len : 1, def : 'n'}
873 BKS : {start : 23, len : 1, def : ' ' },
874 SER : {start : 23, len : 1, def : ' ' },
875 VIS : {start : 29, len : 1, def : ' ' },
876 MIX : {start : 23, len : 1, def : ' ' },
877 MAP : {start : 29, len : 1, def : ' ' },
878 SCO : {start : 23, len : 1, def : ' ' },
879 REC : {start : 23, len : 1, def : ' ' }
882 BKS : {start : 6, len : 1, def : ' ' },
883 SER : {start : 6, len : 1, def : ' ' },
884 VIS : {start : 12, len : 1, def : ' ' },
885 MIX : {start : 6, len : 1, def : ' ' },
886 MAP : {start : 12, len : 1, def : ' ' },
887 SCO : {start : 6, len : 1, def : ' ' },
888 REC : {start : 6, len : 1, def : ' ' }
893 SER : {start : 18, len : 1, def : ' '}
896 SER : {start : 1, len : 1, def : ' '}
901 BKS : {start : 28, len : 1, def : ' ' },
902 SER : {start : 28, len : 1, def : ' ' },
903 VIS : {start : 28, len : 1, def : ' ' },
904 MAP : {start : 28, len : 1, def : ' ' },
905 COM : {start : 28, len : 1, def : ' ' }
908 BKS : {start : 11, len : 1, def : ' ' },
909 SER : {start : 11, len : 1, def : ' ' },
910 VIS : {start : 11, len : 1, def : ' ' },
911 MAP : {start : 11, len : 1, def : ' ' },
912 COM : {start : 11, len : 1, def : ' ' }
917 BKS : {start : 18, len : 4, def : ' ' }
920 BKS : {start : 1, len : 4, def : ' ' }
925 BKS : {start : 31, len : 1, def : '0' },
926 MAP : {start : 31, len : 1, def : '0' }
929 BKS : {start : 14, len : 1, def : '0' },
930 MAP : {start : 14, len : 1, def : '0' }
935 MFHD : {start : 18, len : 1, def : 'i' }
940 BKS : {start : 35, len : 3, def : ' ' },
941 SER : {start : 35, len : 3, def : ' ' },
942 VIS : {start : 35, len : 3, def : ' ' },
943 MIX : {start : 35, len : 3, def : ' ' },
944 MAP : {start : 35, len : 3, def : ' ' },
945 SCO : {start : 35, len : 3, def : ' ' },
946 REC : {start : 35, len : 3, def : ' ' },
947 COM : {start : 35, len : 3, def : ' ' }
952 BKS : {start : 33, len : 1, def : '0' }
955 BKS : {start : 16, len : 1, def : '0' }
960 SCO : {start : 30, len : 2, def : 'n'},
961 REC : {start : 30, len : 2, def : ' '}
964 SCO : {start : 13, len : 2, def : 'n'},
965 REC : {start : 13, len : 2, def : ' '}
970 BKS : {start : 38, len : 1, def : ' ' },
971 SER : {start : 38, len : 1, def : ' ' },
972 VIS : {start : 38, len : 1, def : ' ' },
973 MIX : {start : 38, len : 1, def : ' ' },
974 MAP : {start : 38, len : 1, def : ' ' },
975 SCO : {start : 38, len : 1, def : ' ' },
976 REC : {start : 38, len : 1, def : ' ' },
977 COM : {start : 38, len : 1, def : ' ' }
982 SER : {start : 22, len : 1, def : ' '}
985 SER : {start: 5, len : 1, def: ' '}
990 SCO : {start : 21, len : 1, def : ' '},
991 REC : {start : 21, len : 1, def : 'n'}
994 SCO : {start : 4, len : 1, def : ' '},
995 REC : {start : 4, len : 1, def : 'n'}
1000 MAP : {start : 22, len : 2, def : ' ' }
1003 MAP: {start : 5, len : 2, def : ' ' }
1008 BKS : {start : 5, len : 1, def : 'n' },
1009 SER : {start : 5, len : 1, def : 'n' },
1010 VIS : {start : 5, len : 1, def : 'n' },
1011 MIX : {start : 5, len : 1, def : 'n' },
1012 MAP : {start : 5, len : 1, def : 'n' },
1013 SCO : {start : 5, len : 1, def : 'n' },
1014 REC : {start : 5, len : 1, def : 'n' },
1015 COM : {start : 5, len : 1, def : 'n' },
1016 MFHD: {start : 5, len : 1, def : 'n' },
1017 AUT : {start : 5, len : 1, def : 'n' }
1022 SER : {start : 19, len : 1, def : ' '}
1025 SER : {start : 2, len : 1, def : ' '}
1030 MAP : {start: 18, len : 4, def : ' '}
1033 MAP : {start: 1, len : 4, def : ' '}
1038 SER : {start : 34, len : 1, def : '0' }
1041 SER : {start : 17, len : 1, def : '0' }
1046 MAP : {start: 33, len : 2, def : ' ' }
1049 MAP : {start: 16, len : 2, def : ' '}
1054 BKS : {start : 39, len : 1, def : 'd' },
1055 SER : {start : 39, len : 1, def : 'd' },
1056 VIS : {start : 39, len : 1, def : 'd' },
1057 SCO : {start : 39, len : 1, def : 'd' },
1058 REC : {start : 39, len : 1, def : 'd' },
1059 COM : {start : 39, len : 1, def : 'd' },
1060 MFHD : {start : 39, len : 1, def : 'd' },
1061 "AUT" : {"start" : 39, "len" : 1, "def" : 'd' }
1066 SER : {start : 21, len : 1, def : ' '}
1069 SER : {start : 4, len : 1, def : ' '}
1074 VIS : {start : 34, len : 1, def : ' '}
1077 VIS : {start : 17, len : 1, def : ' '}
1082 VIS : {start : 18, len : 3, def : ' '}
1085 VIS : {start : 1, len : 3, def : ' '}
1090 VIS : {start : 33, len : 1, def : ' ' }
1093 VIS : {start : 16, len : 1, def : ' ' }
1098 SCO : {start : 33, len : 1, def : ' ' },
1099 REC : {start : 33, len : 1, def : 'n' }
1102 SCO : {start : 16, len : 1, def : ' ' },
1103 REC : {start : 16, len : 1, def : 'n' }
1108 BKS : {start : 6, len : 1, def : 'a' },
1109 SER : {start : 6, len : 1, def : 'a' },
1110 VIS : {start : 6, len : 1, def : 'g' },
1111 MIX : {start : 6, len : 1, def : 'p' },
1112 MAP : {start : 6, len : 1, def : 'e' },
1113 SCO : {start : 6, len : 1, def : 'c' },
1114 REC : {start : 6, len : 1, def : 'i' },
1115 COM : {start : 6, len : 1, def : 'm' },
1116 AUT : {start : 6, len : 1, def : 'z' },
1117 MFHD : {start : 6, len : 1, def : 'y' }
1122 "AUT" : {"start" : 6, "len" : 1, "def" : ' ' }
1127 "AUT" : {"start" : 7, "len" : 1, "def" : ' ' }
1132 "AUT" : {"start" : 8, "len" : 1, "def" : ' ' }
1137 "AUT" : {"start" : 9, "len" : 1, "def" : ' ' }
1142 "AUT" : {"start" : 10, "len" : 1, "def" : ' ' }
1147 "AUT" : {"start" : 11, "len" : 1, "def" : ' ' }
1152 "AUT" : {"start" : 12, "len" : 1, "def" : ' ' }
1157 "AUT" : {"start" : 13, "len" : 1, "def" : ' ' }
1162 "AUT" : {"start" : 14, "len" : 1, "def" : ' ' }
1167 "AUT" : {"start" : 15, "len" : 1, "def" : ' ' }
1172 "AUT" : {"start" : 16, "len" : 1, "def" : ' ' }
1177 "AUT" : {"start" : 17, "len" : 1, "def" : ' ' }
1182 "AUT" : {"start" : 28, "len" : 1, "def" : ' ' }
1187 "AUT" : {"start" : 29, "len" : 1, "def" : ' ' }
1192 "AUT" : {"start" : 31, "len" : 1, "def" : ' ' }
1197 "AUT" : {"start" : 32, "len" : 1, "def" : ' ' }
1202 "AUT" : {"start" : 33, "len" : 1, "def" : ' ' }
1207 "AUT" : {"start" : 38, "len" : 1, "def" : ' ' }
1212 "AUT" : {"start" : 39, "len" : 1, "def" : ' ' }
1217 MARC.Record._physical_characteristics = {
1219 label : "Electronic Resource",
1224 values: { a : "Tape Cartridge",
1225 b : "Chip cartridge",
1226 c : "Computer optical disk cartridge",
1227 f : "Tape cassette",
1229 j : "Magnetic disk",
1230 m : "Magneto-optical disk",
1240 values: { a : "One color",
1241 b : "Black-and-white",
1245 n : "Not applicable",
1252 label : "Dimensions",
1253 values: { a : "3 1/2 in.",
1255 g : "4 3/4 in. or 12 cm.",
1256 i : "1 1/8 x 2 3/8 in.",
1257 j : "3 7/8 x 2 1/2 in.",
1258 n : "Not applicable",
1268 values: { ' ' : "No sound (Silent)",
1275 label : "Image bit depth",
1276 values: { mmm : "Multiple",
1277 nnn : "Not applicable",
1283 label : "File formats",
1284 values: { a : "One file format",
1285 m : "Multiple file formats",
1291 label : "Quality assurance target(s)",
1292 values: { a : "Absent",
1293 n : "Not applicable",
1300 label : "Antecedent/Source",
1301 values: { a : "File reproduced from original",
1302 b : "File reproduced from microform",
1303 c : "File reproduced from electronic resource",
1304 d : "File reproduced from an intermediate (not microform)",
1306 n : "Not applicable",
1312 label : "Level of compression",
1313 values: { a : "Uncompressed",
1322 label : "Reformatting quality",
1323 values: { a : "Access",
1324 n : "Not applicable",
1338 values: { a : "Celestial globe",
1339 b : "Planetary or lunar globe",
1340 c : "Terrestrial globe",
1341 e : "Earth moon globe",
1349 values: { a : "One color",
1355 label : "Physical medium",
1356 values: { a : "Paper",
1370 label : "Type of reproduction",
1371 values: { f : "Facsimile",
1372 n : "Not applicable",
1385 values: { d : "Atlas",
1390 r : "Remote-sensing image",
1400 values: { a : "One color",
1406 label : "Physical medium",
1407 values: { a : "Paper",
1415 q : "Flexible base photographic medium, positive",
1416 r : "Flexible base photographic medium, negative",
1417 s : "Non-flexible base photographic medium, positive",
1418 t : "Non-flexible base photographic medium, negative",
1420 y : "Other photographic medium",
1426 label : "Type of reproduction",
1427 values: { f : "Facsimile",
1428 n : "Not applicable",
1435 label : "Production/reproduction details",
1436 values: { a : "Photocopy, blueline print",
1438 c : "Pre-production",
1446 label : "Positive/negative",
1447 values: { a : "Positive",
1450 n : "Not applicable"
1456 label : "Microform",
1461 values: { a : "Aperture card",
1462 b : "Microfilm cartridge",
1463 c : "Microfilm cassette",
1464 d : "Microfilm reel",
1466 f : "Microfiche cassette",
1474 label : "Positive/negative",
1475 values: { a : "Positive",
1483 label : "Dimensions",
1484 values: { a : "8 mm.",
1489 l : "3 x 5 in. (8 x 13 cm.)",
1490 m : "4 x 6 in. (11 x 15 cm.)",
1491 o : "6 x 9 in. (16 x 23 cm.)",
1492 p : "3 1/4 x 7 3/8 in. (9 x 19 cm.)",
1499 label : "Reduction ratio range/Reduction ratio",
1500 values: { a : "Low (1-16x)",
1501 b : "Normal (16-30x)",
1502 c : "High (31-60x)",
1503 d : "Very high (61-90x)",
1506 v : "Reduction ratio varies"
1512 values: { b : "Black-and-white",
1521 label : "Emulsion on film",
1522 values: { a : "Silver halide",
1526 n : "Not applicable",
1533 label : "Quality assurance target(s)",
1534 values: { a : "1st gen. master",
1535 b : "Printing master",
1537 m : "Mixed generation",
1543 label : "Base of film",
1544 values: { a : "Safety base, undetermined",
1545 c : "Safety base, acetate undetermined",
1546 d : "Safety base, diacetate",
1549 n : "Not applicable",
1550 p : "Safety base, polyester",
1551 r : "Safety base, mixed",
1552 t : "Safety base, triacetate",
1560 label : "Motion Picture",
1565 values: { a : "Film cartridge",
1566 f : "Film cassette",
1575 values: { b : "Black-and-white",
1585 label : "Motion picture presentation format",
1586 values: { a : "Standard sound aperture, reduced frame",
1587 b : "Nonanamorphic (wide-screen)",
1589 d : "Anamorphic (wide-screen)",
1590 e : "Other-wide screen format",
1591 f : "Standard. silent aperture, full frame",
1598 label : "Sound on medium or separate",
1599 values: { a : "Sound on medium",
1600 b : "Sound separate from medium",
1606 label : "Medium for sound",
1607 values: { a : "Optical sound track on motion picture film",
1608 b : "Magnetic sound track on motion picture film",
1609 c : "Magnetic audio tape in cartridge",
1611 e : "Magnetic audio tape on reel",
1612 f : "Magnetic audio tape in cassette",
1613 g : "Optical and magnetic sound track on film",
1622 label : "Dimensions",
1623 values: { a : "Standard 8 mm.",
1624 b : "Super 8 mm./single 8 mm.",
1636 label : "Configuration of playback channels",
1637 values: { k : "Mixed",
1639 n : "Not applicable",
1640 q : "Multichannel, surround or quadraphonic",
1648 label : "Production elements",
1649 values: { a : "Work print",
1653 e : "Mixing tracks",
1654 f : "Title bands/inter-title rolls",
1655 g : "Production rolls",
1656 n : "Not applicable",
1663 label : "Non-projected Graphic",
1668 values: { c : "Collage",
1671 f : "Photo-mechanical print",
1672 g : "Photonegative",
1676 l : "Technical drawing",
1678 o : "Flash/activity card",
1686 values: { a : "One color",
1687 b : "Black-and-white",
1697 label : "Primary support material",
1698 values: { a : "Canvas",
1699 b : "Bristol board",
1700 c : "Cardboard/illustration board",
1706 m : "Mixed collection",
1719 label : "Secondary support material",
1720 values: { a : "Canvas",
1721 b : "Bristol board",
1722 c : "Cardboard/illustration board",
1728 m : "Mixed collection",
1742 label : "Projected Graphic",
1747 values: { c : "Film cartridge",
1749 f : "Film filmstrip type",
1750 o : "Filmstrip roll",
1759 values: { b : "Black-and-white",
1763 n : "Not applicable",
1770 label : "Base of emulsion",
1771 values: { d : "Glass",
1774 k : "Film base, other than safety film",
1775 m : "Mixed collection",
1783 label : "Sound on medium or separate",
1784 values: { a : "Sound on medium",
1785 b : "Sound separate from medium",
1791 label : "Medium for sound",
1792 values: { a : "Optical sound track on motion picture film",
1793 b : "Magnetic sound track on motion picture film",
1794 c : "Magnetic audio tape in cartridge",
1796 e : "Magnetic audio tape on reel",
1797 f : "Magnetic audio tape in cassette",
1798 g : "Optical and magnetic sound track on film",
1807 label : "Dimensions",
1808 values: { a : "Standard 8 mm.",
1809 b : "Super 8 mm./single 8 mm.",
1815 j : "2 x 2 in. (5 x 5 cm.)",
1816 k : "2 1/4 x 2 1/4 in. (6 x 6 cm.)",
1817 s : "4 x 5 in. (10 x 13 cm.)",
1818 t : "5 x 7 in. (13 x 18 cm.)",
1819 v : "8 x 10 in. (21 x 26 cm.)",
1820 w : "9 x 9 in. (23 x 23 cm.)",
1821 x : "10 x 10 in. (26 x 26 cm.)",
1822 y : "7 x 7 in. (18 x 18 cm.)",
1829 label : "Secondary support material",
1830 values: { c : "Cardboard",
1834 j : "Metal and glass",
1835 k : "Synthetics and glass",
1836 m : "Mixed collection",
1844 label : "Remote-sensing Image",
1849 values: { u : "Unspecified" }
1853 label : "Altitude of sensor",
1854 values: { a : "Surface",
1857 n : "Not applicable",
1864 label : "Attitude of sensor",
1865 values: { a : "Low oblique",
1868 n : "Not applicable",
1874 label : "Cloud cover",
1875 values: { 0 : "0-09%",
1885 n : "Not applicable",
1891 label : "Platform construction type",
1892 values: { a : "Balloon",
1893 b : "Aircraft-low altitude",
1894 c : "Aircraft-medium altitude",
1895 d : "Aircraft-high altitude",
1896 e : "Manned spacecraft",
1897 f : "Unmanned spacecraft",
1898 g : "Land-based remote-sensing device",
1899 h : "Water surface-based remote-sensing device",
1900 i : "Submersible remote-sensing device",
1901 n : "Not applicable",
1908 label : "Platform use category",
1909 values: { a : "Meteorological",
1910 b : "Surface observing",
1911 c : "Space observing",
1913 n : "Not applicable",
1920 label : "Sensor type",
1921 values: { a : "Active",
1929 label : "Data type",
1930 values: { nn : "Not applicable",
1933 aa : "Visible light",
1934 da : "Near infrared",
1935 db : "Middle infrared",
1936 dc : "Far infrared",
1937 dd : "Thermal infrared",
1938 de : "Shortwave infrared (SWIR)",
1939 df : "Reflective infrared",
1940 dv : "Combinations",
1941 dz : "Other infrared data",
1942 ga : "Sidelooking airborne radar (SLAR)",
1943 gb : "Synthetic aperture radar (SAR-single frequency)",
1944 gc : "SAR-multi-frequency (multichannel)",
1945 gd : "SAR-like polarization",
1946 ge : "SAR-cross polarization",
1947 gf : "Infometric SAR",
1948 gg : "Polarmetric SAR",
1949 gu : "Passive microwave mapping",
1950 gz : "Other microwave data",
1951 ja : "Far ultraviolet",
1952 jb : "Middle ultraviolet",
1953 jc : "Near ultraviolet",
1954 jv : "Ultraviolet combinations",
1955 jz : "Other ultraviolet data",
1956 ma : "Multi-spectral, multidata",
1957 mb : "Multi-temporal",
1958 mm : "Combination of various data types",
1959 pa : "Sonar-water depth",
1960 pb : "Sonar-bottom topography images, sidescan",
1961 pc : "Sonar-bottom topography, near-surface",
1962 pd : "Sonar-bottom topography, near-bottom",
1963 pe : "Seismic surveys",
1964 pz : "Other acoustical data",
1965 ra : "Gravity anomales (general)",
1969 sa : "Magnetic field",
1970 ta : "Radiometric surveys"
1976 label : "Sound Recording",
1981 values: { d : "Sound disc",
1983 g : "Sound cartridge",
1984 i : "Sound-track film",
1986 s : "Sound cassette",
1987 t : "Sound-tape reel",
1989 w : "Wire recording",
1996 values: { a : "16 rpm",
2016 label : "Configuration of playback channels",
2017 values: { m : "Monaural",
2026 label : "Groove width or pitch",
2027 values: { m : "Microgroove/fine",
2028 n : "Not applicable",
2029 s : "Coarse/standard",
2036 label : "Dimensions",
2037 values: { a : "3 in.",
2043 g : "4 3/4 in. (12 cm.)",
2044 j : "3 7/8 x 2 1/2 in.",
2045 o : "5 1/4 x 3 7/8 in.",
2046 s : "2 3/4 x 4 in.",
2047 n : "Not applicable",
2054 label : "Tape width",
2055 values: { l : "1/8 in.",
2057 n : "Not applicable",
2066 label : "Tape configuration ",
2067 values: { a : "Full (1) track",
2068 b : "Half (2) track",
2069 c : "Quarter (4) track",
2073 n : "Not applicable",
2080 label : "Special playback",
2081 values: { a : "NAB standard",
2082 b : "CCIR standard",
2083 c : "Dolby-B encoded, standard Dolby",
2085 e : "Digital recording",
2086 f : "Dolby-A encoded",
2087 g : "Dolby-C encoded",
2089 n : "Not applicable",
2096 label : "Capture and storage",
2097 values: { a : "Acoustical capture, direct storage",
2098 b : "Direct storage, not acoustical",
2099 d : "Digital storage",
2100 e : "Analog electrical storage",
2108 label : "Tactile Material",
2113 values: { a : "Moon",
2116 d : "Tactile, with no writing system",
2123 label : "Class of braille writing",
2124 values: { a : "Literary braille",
2125 b : "Format code braille",
2126 c : "Mathematics and scientific braille",
2127 d : "Computer braille",
2128 e : "Music braille",
2129 m : "Multiple braille types",
2130 n : "Not applicable",
2137 label : "Level of contraction",
2138 values: { a : "Uncontracted",
2141 n : "Not applicable",
2148 label : "Braille music format",
2149 values: { a : "Bar over bar",
2151 c : "Line over line",
2154 f : "Section by section",
2157 i : "Spanner short form scoring",
2158 j : "Short form scoring",
2160 l : "Vertical score",
2161 n : "Not applicable",
2168 label : "Special physical characteristics",
2169 values: { a : "Print/braille",
2170 b : "Jumbo or enlarged braille",
2171 n : "Not applicable",
2179 label : "Videorecording",
2184 values: { c : "Videocartridge",
2186 f : "Videocassette",
2195 values: { b : "Black-and-white",
2198 n : "Not applicable",
2205 label : "Videorecording format",
2206 values: { a : "Beta",
2228 label : "Sound on medium or separate",
2229 values: { a : "Sound on medium",
2230 b : "Sound separate from medium",
2236 label : "Medium for sound",
2237 values: { a : "Optical sound track on motion picture film",
2238 b : "Magnetic sound track on motion picture film",
2239 c : "Magnetic audio tape in cartridge",
2241 e : "Magnetic audio tape on reel",
2242 f : "Magnetic audio tape in cassette",
2243 g : "Optical and magnetic sound track on motion picture film",
2252 label : "Dimensions",
2253 values: { a : "8 mm.",
2265 label : "Configuration of playback channel",
2266 values: { k : "Mixed",
2268 n : "Not applicable",
2269 q : "Multichannel, surround or quadraphonic",