[open-ils-commits] [GIT] Evergreen ILS branch rel_2_10 updated. 0743d8fbd68089780d59b9725a8ebd9a75e14a57

Evergreen Git git at git.evergreen-ils.org
Thu Mar 17 18:53:52 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, rel_2_10 has been updated
       via  0743d8fbd68089780d59b9725a8ebd9a75e14a57 (commit)
       via  39b1b170039353aa9f9aca472114bc3c7f51139e (commit)
      from  bba23ded2dc14050f33e1719de7ebf8b9544cfc6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 0743d8fbd68089780d59b9725a8ebd9a75e14a57
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Mar 17 18:46:02 2016 -0400

    forward-port 2.9.3-2.10.0 monolithic DB update script
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>

diff --git a/Open-ILS/src/sql/Pg/version-upgrade/2.9.3-2.10.0-upgrade-db.sql b/Open-ILS/src/sql/Pg/version-upgrade/2.9.3-2.10.0-upgrade-db.sql
new file mode 100644
index 0000000..0856094
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/version-upgrade/2.9.3-2.10.0-upgrade-db.sql
@@ -0,0 +1,4645 @@
+--Upgrade Script for 2.9.3 to 2.10.0
+\set eg_version '''2.10.0'''
+BEGIN;
+
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('2.10.0', :eg_version);
+
+SELECT evergreen.upgrade_deps_block_check('0945', :eg_version);
+
+-- run the entire update inside a DO block for managing the logic
+-- of whether to recreate the optional reporter views
+DO $$
+DECLARE
+    has_current_circ BOOLEAN;
+    has_billing_summary BOOLEAN;
+BEGIN
+
+SELECT INTO has_current_circ TRUE FROM pg_views 
+    WHERE schemaname = 'reporter' AND viewname = 'classic_current_circ';
+
+SELECT INTO has_billing_summary TRUE FROM pg_views 
+    WHERE schemaname = 'reporter' AND 
+    viewname = 'classic_current_billing_summary';
+
+DROP VIEW action.all_circulation;
+DROP VIEW IF EXISTS reporter.classic_current_circ;
+DROP VIEW IF EXISTS reporter.classic_current_billing_summary;
+DROP VIEW reporter.demographic;
+DROP VIEW auditor.actor_usr_lifecycle;
+DROP VIEW action.all_hold_request;
+
+ALTER TABLE actor.usr 
+    ALTER dob TYPE DATE USING (dob + '3 hours'::INTERVAL)::DATE;
+
+-- alter the auditor table manually to apply the same
+-- dob mangling logic as above.
+ALTER TABLE auditor.actor_usr_history 
+    ALTER dob TYPE DATE USING (dob + '3 hours'::INTERVAL)::DATE;
+
+-- this recreates auditor.actor_usr_lifecycle
+PERFORM auditor.update_auditors();
+
+CREATE VIEW reporter.demographic AS
+    SELECT u.id, u.dob,
+        CASE
+            WHEN u.dob IS NULL THEN 'Adult'::text
+            WHEN age(u.dob) > '18 years'::interval THEN 'Adult'::text
+            ELSE 'Juvenile'::text
+        END AS general_division
+    FROM actor.usr u;
+
+CREATE VIEW action.all_circulation AS
+         SELECT aged_circulation.id, aged_circulation.usr_post_code,
+            aged_circulation.usr_home_ou, aged_circulation.usr_profile,
+            aged_circulation.usr_birth_year, aged_circulation.copy_call_number,
+            aged_circulation.copy_location, aged_circulation.copy_owning_lib,
+            aged_circulation.copy_circ_lib, aged_circulation.copy_bib_record,
+            aged_circulation.xact_start, aged_circulation.xact_finish,
+            aged_circulation.target_copy, aged_circulation.circ_lib,
+            aged_circulation.circ_staff, aged_circulation.checkin_staff,
+            aged_circulation.checkin_lib, aged_circulation.renewal_remaining,
+            aged_circulation.grace_period, aged_circulation.due_date,
+            aged_circulation.stop_fines_time, aged_circulation.checkin_time,
+            aged_circulation.create_time, aged_circulation.duration,
+            aged_circulation.fine_interval, aged_circulation.recurring_fine,
+            aged_circulation.max_fine, aged_circulation.phone_renewal,
+            aged_circulation.desk_renewal, aged_circulation.opac_renewal,
+            aged_circulation.duration_rule,
+            aged_circulation.recurring_fine_rule,
+            aged_circulation.max_fine_rule, aged_circulation.stop_fines,
+            aged_circulation.workstation, aged_circulation.checkin_workstation,
+            aged_circulation.checkin_scan_time, aged_circulation.parent_circ
+           FROM action.aged_circulation
+UNION ALL
+         SELECT DISTINCT circ.id,
+            COALESCE(a.post_code, b.post_code) AS usr_post_code,
+            p.home_ou AS usr_home_ou, p.profile AS usr_profile,
+            date_part('year'::text, p.dob)::integer AS usr_birth_year,
+            cp.call_number AS copy_call_number, circ.copy_location,
+            cn.owning_lib AS copy_owning_lib, cp.circ_lib AS copy_circ_lib,
+            cn.record AS copy_bib_record, circ.xact_start, circ.xact_finish,
+            circ.target_copy, circ.circ_lib, circ.circ_staff,
+            circ.checkin_staff, circ.checkin_lib, circ.renewal_remaining,
+            circ.grace_period, circ.due_date, circ.stop_fines_time,
+            circ.checkin_time, circ.create_time, circ.duration,
+            circ.fine_interval, circ.recurring_fine, circ.max_fine,
+            circ.phone_renewal, circ.desk_renewal, circ.opac_renewal,
+            circ.duration_rule, circ.recurring_fine_rule, circ.max_fine_rule,
+            circ.stop_fines, circ.workstation, circ.checkin_workstation,
+            circ.checkin_scan_time, circ.parent_circ
+           FROM action.circulation circ
+      JOIN asset.copy cp ON circ.target_copy = cp.id
+   JOIN asset.call_number cn ON cp.call_number = cn.id
+   JOIN actor.usr p ON circ.usr = p.id
+   LEFT JOIN actor.usr_address a ON p.mailing_address = a.id
+   LEFT JOIN actor.usr_address b ON p.billing_address = b.id;
+
+CREATE OR REPLACE VIEW action.all_hold_request AS
+         SELECT DISTINCT COALESCE(a.post_code, b.post_code) AS usr_post_code,
+            p.home_ou AS usr_home_ou, p.profile AS usr_profile,
+            date_part('year'::text, p.dob)::integer AS usr_birth_year,
+            ahr.requestor <> ahr.usr AS staff_placed, ahr.id, ahr.request_time,
+            ahr.capture_time, ahr.fulfillment_time, ahr.checkin_time,
+            ahr.return_time, ahr.prev_check_time, ahr.expire_time,
+            ahr.cancel_time, ahr.cancel_cause, ahr.cancel_note, ahr.target,
+            ahr.current_copy, ahr.fulfillment_staff, ahr.fulfillment_lib,
+            ahr.request_lib, ahr.selection_ou, ahr.selection_depth,
+            ahr.pickup_lib, ahr.hold_type, ahr.holdable_formats,
+                CASE
+                    WHEN ahr.phone_notify IS NULL THEN false
+                    WHEN ahr.phone_notify = ''::text THEN false
+                    ELSE true
+                END AS phone_notify,
+            ahr.email_notify,
+                CASE
+                    WHEN ahr.sms_notify IS NULL THEN false
+                    WHEN ahr.sms_notify = ''::text THEN false
+                    ELSE true
+                END AS sms_notify,
+            ahr.frozen, ahr.thaw_date, ahr.shelf_time, ahr.cut_in_line,
+            ahr.mint_condition, ahr.shelf_expire_time, ahr.current_shelf_lib,
+            ahr.behind_desk
+           FROM action.hold_request ahr
+      JOIN actor.usr p ON ahr.usr = p.id
+   LEFT JOIN actor.usr_address a ON p.mailing_address = a.id
+   LEFT JOIN actor.usr_address b ON p.billing_address = b.id
+UNION ALL
+         SELECT aged_hold_request.usr_post_code, aged_hold_request.usr_home_ou,
+            aged_hold_request.usr_profile, aged_hold_request.usr_birth_year,
+            aged_hold_request.staff_placed, aged_hold_request.id,
+            aged_hold_request.request_time, aged_hold_request.capture_time,
+            aged_hold_request.fulfillment_time, aged_hold_request.checkin_time,
+            aged_hold_request.return_time, aged_hold_request.prev_check_time,
+            aged_hold_request.expire_time, aged_hold_request.cancel_time,
+            aged_hold_request.cancel_cause, aged_hold_request.cancel_note,
+            aged_hold_request.target, aged_hold_request.current_copy,
+            aged_hold_request.fulfillment_staff,
+            aged_hold_request.fulfillment_lib, aged_hold_request.request_lib,
+            aged_hold_request.selection_ou, aged_hold_request.selection_depth,
+            aged_hold_request.pickup_lib, aged_hold_request.hold_type,
+            aged_hold_request.holdable_formats, aged_hold_request.phone_notify,
+            aged_hold_request.email_notify, aged_hold_request.sms_notify,
+            aged_hold_request.frozen, aged_hold_request.thaw_date,
+            aged_hold_request.shelf_time, aged_hold_request.cut_in_line,
+            aged_hold_request.mint_condition,
+            aged_hold_request.shelf_expire_time,
+            aged_hold_request.current_shelf_lib, aged_hold_request.behind_desk
+           FROM action.aged_hold_request;
+
+IF has_current_circ THEN
+RAISE NOTICE 'Recreating optional view reporter.classic_current_circ';
+
+CREATE OR REPLACE VIEW reporter.classic_current_circ AS
+SELECT	cl.shortname AS circ_lib,
+	cl.id AS circ_lib_id,
+	circ.xact_start AS xact_start,
+	circ_type.type AS circ_type,
+	cp.id AS copy_id,
+	cp.circ_modifier,
+	ol.shortname AS owning_lib_name,
+	lm.value AS language,
+	lfm.value AS lit_form,
+	ifm.value AS item_form,
+	itm.value AS item_type,
+	sl.name AS shelving_location,
+	p.id AS patron_id,
+	g.name AS profile_group,
+	dem.general_division AS demographic_general_division,
+	circ.id AS id,
+	cn.id AS call_number,
+	cn.label AS call_number_label,
+	call_number_dewey(cn.label) AS dewey,
+	CASE
+		WHEN call_number_dewey(cn.label) ~  E'^[0-9.]+$'
+			THEN
+				btrim(
+					to_char(
+						10 * floor((call_number_dewey(cn.label)::float) / 10), '000'
+					)
+				)
+		ELSE NULL
+	END AS dewey_block_tens,
+	CASE
+		WHEN call_number_dewey(cn.label) ~  E'^[0-9.]+$'
+			THEN
+				btrim(
+					to_char(
+						100 * floor((call_number_dewey(cn.label)::float) / 100), '000'
+					)
+				)
+		ELSE NULL
+	END AS dewey_block_hundreds,
+	CASE
+		WHEN call_number_dewey(cn.label) ~  E'^[0-9.]+$'
+			THEN
+				btrim(
+					to_char(
+						10 * floor((call_number_dewey(cn.label)::float) / 10), '000'
+					)
+				)
+				|| '-' ||
+				btrim(
+					to_char(
+						10 * floor((call_number_dewey(cn.label)::float) / 10) + 9, '000'
+					)
+				)
+		ELSE NULL
+	END AS dewey_range_tens,
+	CASE
+		WHEN call_number_dewey(cn.label) ~  E'^[0-9.]+$'
+			THEN
+				btrim(
+					to_char(
+						100 * floor((call_number_dewey(cn.label)::float) / 100), '000'
+					)
+				)
+				|| '-' ||
+				btrim(
+					to_char(
+						100 * floor((call_number_dewey(cn.label)::float) / 100) + 99, '000'
+					)
+				)
+		ELSE NULL
+	END AS dewey_range_hundreds,
+	hl.id AS patron_home_lib,
+	hl.shortname AS patron_home_lib_shortname,
+	paddr.county AS patron_county,
+	paddr.city AS patron_city,
+	paddr.post_code AS patron_zip,
+	sc1.stat_cat_entry AS stat_cat_1,
+	sc2.stat_cat_entry AS stat_cat_2,
+	sce1.value AS stat_cat_1_value,
+	sce2.value AS stat_cat_2_value
+  FROM	action.circulation circ
+	JOIN reporter.circ_type circ_type ON (circ.id = circ_type.id)
+	JOIN asset.copy cp ON (cp.id = circ.target_copy)
+	JOIN asset.copy_location sl ON (cp.location = sl.id)
+	JOIN asset.call_number cn ON (cp.call_number = cn.id)
+	JOIN actor.org_unit ol ON (cn.owning_lib = ol.id)
+	JOIN metabib.rec_descriptor rd ON (rd.record = cn.record)
+	JOIN actor.org_unit cl ON (circ.circ_lib = cl.id)
+	JOIN actor.usr p ON (p.id = circ.usr)
+	JOIN actor.org_unit hl ON (p.home_ou = hl.id)
+	JOIN permission.grp_tree g ON (p.profile = g.id)
+	JOIN reporter.demographic dem ON (dem.id = p.id)
+	JOIN actor.usr_address paddr ON (paddr.id = p.billing_address)
+	LEFT JOIN config.language_map lm ON (rd.item_lang = lm.code)
+	LEFT JOIN config.lit_form_map lfm ON (rd.lit_form = lfm.code)
+	LEFT JOIN config.item_form_map ifm ON (rd.item_form = ifm.code)
+	LEFT JOIN config.item_type_map itm ON (rd.item_type = itm.code)
+	LEFT JOIN asset.stat_cat_entry_copy_map sc1 ON (sc1.owning_copy = cp.id AND sc1.stat_cat = 1)
+	LEFT JOIN asset.stat_cat_entry sce1 ON (sce1.id = sc1.stat_cat_entry)
+	LEFT JOIN asset.stat_cat_entry_copy_map sc2 ON (sc2.owning_copy = cp.id AND sc2.stat_cat = 2)
+	LEFT JOIN asset.stat_cat_entry sce2 ON (sce2.id = sc2.stat_cat_entry);
+END IF;
+
+IF has_billing_summary THEN
+RAISE NOTICE 'Recreating optional view reporter.classic_current_billing_summary';
+
+CREATE OR REPLACE VIEW reporter.classic_current_billing_summary AS
+SELECT	x.id AS id,
+	x.usr AS usr,
+	bl.shortname AS billing_location_shortname,
+	bl.name AS billing_location_name,
+	x.billing_location AS billing_location,
+	c.barcode AS barcode,
+	u.home_ou AS usr_home_ou,
+	ul.shortname AS usr_home_ou_shortname,
+	ul.name AS usr_home_ou_name,
+	x.xact_start AS xact_start,
+	x.xact_finish AS xact_finish,
+	x.xact_type AS xact_type,
+	x.total_paid AS total_paid,
+	x.total_owed AS total_owed,
+	x.balance_owed AS balance_owed,
+	x.last_payment_ts AS last_payment_ts,
+	x.last_payment_note AS last_payment_note,
+	x.last_payment_type AS last_payment_type,
+	x.last_billing_ts AS last_billing_ts,
+	x.last_billing_note AS last_billing_note,
+	x.last_billing_type AS last_billing_type,
+	paddr.county AS patron_county,
+	paddr.city AS patron_city,
+	paddr.post_code AS patron_zip,
+	g.name AS profile_group,
+	dem.general_division AS demographic_general_division
+  FROM	money.open_billable_xact_summary x
+	JOIN actor.org_unit bl ON (x.billing_location = bl.id)
+	JOIN actor.usr u ON (u.id = x.usr)
+	JOIN actor.org_unit ul ON (u.home_ou = ul.id)
+	JOIN actor.card c ON (u.card = c.id)
+	JOIN permission.grp_tree g ON (u.profile = g.id)
+	JOIN reporter.demographic dem ON (dem.id = u.id)
+	JOIN actor.usr_address paddr ON (paddr.id = u.billing_address);
+END IF;
+
+END $$;
+
+SELECT evergreen.upgrade_deps_block_check('0946', :eg_version);
+
+CREATE OR REPLACE FUNCTION actor.org_unit_ancestor_setting_batch( org_id INT, VARIADIC setting_names TEXT[] ) RETURNS SETOF actor.org_unit_setting AS $$
+DECLARE
+    setting RECORD;
+    setting_name TEXT;
+    cur_org INT;
+BEGIN
+    FOREACH setting_name IN ARRAY setting_names
+    LOOP
+        cur_org := org_id;
+        LOOP
+            SELECT INTO setting * FROM actor.org_unit_setting WHERE org_unit = cur_org AND name = setting_name;
+            IF FOUND THEN
+                RETURN NEXT setting;
+                EXIT;
+            END IF;
+            SELECT INTO cur_org parent_ou FROM actor.org_unit WHERE id = cur_org;
+            EXIT WHEN cur_org IS NULL;
+        END LOOP;
+    END LOOP;
+    RETURN;
+END;
+$$ LANGUAGE plpgsql STABLE;
+
+COMMENT ON FUNCTION actor.org_unit_ancestor_setting_batch( INT, VARIADIC TEXT[] ) IS $$
+For each setting name passed, search "up" the org_unit tree until
+we find the first occurrence of an org_unit_setting with the given name.
+$$;
+
+SELECT evergreen.upgrade_deps_block_check('0947', :eg_version);
+
+CREATE OR REPLACE FUNCTION evergreen.lpad_number_substrings( TEXT, TEXT, INT ) RETURNS TEXT AS $$
+    my $string = shift;            # Source string
+    my $pad = shift;               # string to fill. Typically '0'. This should be a single character.
+    my $len = shift;               # length of resultant padded field
+
+    $string =~ s/([0-9]+)/$pad x ($len - length($1)) . $1/eg;
+
+    return $string;
+$$ LANGUAGE PLPERLU;
+
+SELECT evergreen.upgrade_deps_block_check('0951', :eg_version);
+
+ALTER TABLE config.standing_penalty
+      ADD COLUMN ignore_proximity INTEGER;
+
+CREATE OR REPLACE FUNCTION action.hold_request_permit_test( pickup_ou INT, request_ou INT, match_item BIGINT, match_user INT, match_requestor INT, retargetting BOOL ) RETURNS SETOF action.matrix_test_result AS $func$
+DECLARE
+    matchpoint_id        INT;
+    user_object        actor.usr%ROWTYPE;
+    age_protect_object    config.rule_age_hold_protect%ROWTYPE;
+    standing_penalty    config.standing_penalty%ROWTYPE;
+    transit_range_ou_type    actor.org_unit_type%ROWTYPE;
+    transit_source        actor.org_unit%ROWTYPE;
+    item_object        asset.copy%ROWTYPE;
+    item_cn_object     asset.call_number%ROWTYPE;
+    item_status_object  config.copy_status%ROWTYPE;
+    item_location_object    asset.copy_location%ROWTYPE;
+    ou_skip              actor.org_unit_setting%ROWTYPE;
+    result            action.matrix_test_result;
+    hold_test        config.hold_matrix_matchpoint%ROWTYPE;
+    use_active_date   TEXT;
+    age_protect_date  TIMESTAMP WITH TIME ZONE;
+    hold_count        INT;
+    hold_transit_prox    INT;
+    frozen_hold_count    INT;
+    context_org_list    INT[];
+    done            BOOL := FALSE;
+    hold_penalty TEXT;
+    v_pickup_ou ALIAS FOR pickup_ou;
+    v_request_ou ALIAS FOR request_ou;
+    item_prox INT;
+    pickup_prox INT;
+BEGIN
+    SELECT INTO user_object * FROM actor.usr WHERE id = match_user;
+    SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( v_pickup_ou );
+
+    result.success := TRUE;
+
+    -- The HOLD penalty block only applies to new holds.
+    -- The CAPTURE penalty block applies to existing holds.
+    hold_penalty := 'HOLD';
+    IF retargetting THEN
+        hold_penalty := 'CAPTURE';
+    END IF;
+
+    -- Fail if we couldn't find a user
+    IF user_object.id IS NULL THEN
+        result.fail_part := 'no_user';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    SELECT INTO item_object * FROM asset.copy WHERE id = match_item;
+
+    -- Fail if we couldn't find a copy
+    IF item_object.id IS NULL THEN
+        result.fail_part := 'no_item';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    SELECT INTO matchpoint_id action.find_hold_matrix_matchpoint(v_pickup_ou, v_request_ou, match_item, match_user, match_requestor);
+    result.matchpoint := matchpoint_id;
+
+    SELECT INTO ou_skip * FROM actor.org_unit_setting WHERE name = 'circ.holds.target_skip_me' AND org_unit = item_object.circ_lib;
+
+    -- Fail if the circ_lib for the item has circ.holds.target_skip_me set to true
+    IF ou_skip.id IS NOT NULL AND ou_skip.value = 'true' THEN
+        result.fail_part := 'circ.holds.target_skip_me';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    -- Fail if user is barred
+    IF user_object.barred IS TRUE THEN
+        result.fail_part := 'actor.usr.barred';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
+    SELECT INTO item_status_object * FROM config.copy_status WHERE id = item_object.status;
+    SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location;
+
+    -- Fail if we couldn't find any matchpoint (requires a default)
+    IF matchpoint_id IS NULL THEN
+        result.fail_part := 'no_matchpoint';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    SELECT INTO hold_test * FROM config.hold_matrix_matchpoint WHERE id = matchpoint_id;
+
+    IF hold_test.holdable IS FALSE THEN
+        result.fail_part := 'config.hold_matrix_test.holdable';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    IF item_object.holdable IS FALSE THEN
+        result.fail_part := 'item.holdable';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    IF item_status_object.holdable IS FALSE THEN
+        result.fail_part := 'status.holdable';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    IF item_location_object.holdable IS FALSE THEN
+        result.fail_part := 'location.holdable';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    IF hold_test.transit_range IS NOT NULL THEN
+        SELECT INTO transit_range_ou_type * FROM actor.org_unit_type WHERE id = hold_test.transit_range;
+        IF hold_test.distance_is_from_owner THEN
+            SELECT INTO transit_source ou.* FROM actor.org_unit ou JOIN asset.call_number cn ON (cn.owning_lib = ou.id) WHERE cn.id = item_object.call_number;
+        ELSE
+            SELECT INTO transit_source * FROM actor.org_unit WHERE id = item_object.circ_lib;
+        END IF;
+
+        PERFORM * FROM actor.org_unit_descendants( transit_source.id, transit_range_ou_type.depth ) WHERE id = v_pickup_ou;
+
+        IF NOT FOUND THEN
+            result.fail_part := 'transit_range';
+            result.success := FALSE;
+            done := TRUE;
+            RETURN NEXT result;
+        END IF;
+    END IF;
+ 
+    -- Proximity of user's home_ou to the pickup_lib to see if penalty should be ignored.
+    SELECT INTO pickup_prox prox FROM actor.org_unit_proximity WHERE from_org = user_object.home_ou AND to_org = v_pickup_ou;
+    -- Proximity of user's home_ou to the items' lib to see if penalty should be ignored.
+    IF hold_test.distance_is_from_owner THEN
+        SELECT INTO item_prox prox FROM actor.org_unit_proximity WHERE from_org = user_object.home_ou AND to_org = item_cn_object.owning_lib;
+    ELSE
+        SELECT INTO item_prox prox FROM actor.org_unit_proximity WHERE from_org = user_object.home_ou AND to_org = item_object.circ_lib;
+    END IF;
+
+    FOR standing_penalty IN
+        SELECT  DISTINCT csp.*
+          FROM  actor.usr_standing_penalty usp
+                JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
+          WHERE usr = match_user
+                AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
+                AND (usp.stop_date IS NULL or usp.stop_date > NOW())
+                AND (csp.ignore_proximity IS NULL OR csp.ignore_proximity < item_prox
+                     OR csp.ignore_proximity < pickup_prox)
+                AND csp.block_list LIKE '%' || hold_penalty || '%' LOOP
+
+        result.fail_part := standing_penalty.name;
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END LOOP;
+
+    IF hold_test.stop_blocked_user IS TRUE THEN
+        FOR standing_penalty IN
+            SELECT  DISTINCT csp.*
+              FROM  actor.usr_standing_penalty usp
+                    JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
+              WHERE usr = match_user
+                    AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
+                    AND (usp.stop_date IS NULL or usp.stop_date > NOW())
+                    AND csp.block_list LIKE '%CIRC%' LOOP
+    
+            result.fail_part := standing_penalty.name;
+            result.success := FALSE;
+            done := TRUE;
+            RETURN NEXT result;
+        END LOOP;
+    END IF;
+
+    IF hold_test.max_holds IS NOT NULL AND NOT retargetting THEN
+        SELECT    INTO hold_count COUNT(*)
+          FROM    action.hold_request
+          WHERE    usr = match_user
+            AND fulfillment_time IS NULL
+            AND cancel_time IS NULL
+            AND CASE WHEN hold_test.include_frozen_holds THEN TRUE ELSE frozen IS FALSE END;
+
+        IF hold_count >= hold_test.max_holds THEN
+            result.fail_part := 'config.hold_matrix_test.max_holds';
+            result.success := FALSE;
+            done := TRUE;
+            RETURN NEXT result;
+        END IF;
+    END IF;
+
+    IF item_object.age_protect IS NOT NULL THEN
+        SELECT INTO age_protect_object * FROM config.rule_age_hold_protect WHERE id = item_object.age_protect;
+        IF hold_test.distance_is_from_owner THEN
+            SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_cn_object.owning_lib);
+        ELSE
+            SELECT INTO use_active_date value FROM actor.org_unit_ancestor_setting('circ.holds.age_protect.active_date', item_object.circ_lib);
+        END IF;
+        IF use_active_date = 'true' THEN
+            age_protect_date := COALESCE(item_object.active_date, NOW());
+        ELSE
+            age_protect_date := item_object.create_date;
+        END IF;
+        IF age_protect_date + age_protect_object.age > NOW() THEN
+            IF hold_test.distance_is_from_owner THEN
+                SELECT INTO item_cn_object * FROM asset.call_number WHERE id = item_object.call_number;
+                SELECT INTO hold_transit_prox prox FROM actor.org_unit_proximity WHERE from_org = item_cn_object.owning_lib AND to_org = v_pickup_ou;
+            ELSE
+                SELECT INTO hold_transit_prox prox FROM actor.org_unit_proximity WHERE from_org = item_object.circ_lib AND to_org = v_pickup_ou;
+            END IF;
+
+            IF hold_transit_prox > age_protect_object.prox THEN
+                result.fail_part := 'config.rule_age_hold_protect.prox';
+                result.success := FALSE;
+                done := TRUE;
+                RETURN NEXT result;
+            END IF;
+        END IF;
+    END IF;
+
+    IF NOT done THEN
+        RETURN NEXT result;
+    END IF;
+
+    RETURN;
+END;
+$func$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION action.item_user_circ_test( circ_ou INT, match_item BIGINT, match_user INT, renewal BOOL ) RETURNS SETOF action.circ_matrix_test_result AS $func$
+DECLARE
+    user_object             actor.usr%ROWTYPE;
+    standing_penalty        config.standing_penalty%ROWTYPE;
+    item_object             asset.copy%ROWTYPE;
+    item_status_object      config.copy_status%ROWTYPE;
+    item_location_object    asset.copy_location%ROWTYPE;
+    result                  action.circ_matrix_test_result;
+    circ_test               action.found_circ_matrix_matchpoint;
+    circ_matchpoint         config.circ_matrix_matchpoint%ROWTYPE;
+    circ_limit_set          config.circ_limit_set%ROWTYPE;
+    hold_ratio              action.hold_stats%ROWTYPE;
+    penalty_type            TEXT;
+    items_out               INT;
+    context_org_list        INT[];
+    done                    BOOL := FALSE;
+    item_prox               INT;
+    home_prox               INT;
+BEGIN
+    -- Assume success unless we hit a failure condition
+    result.success := TRUE;
+
+    -- Need user info to look up matchpoints
+    SELECT INTO user_object * FROM actor.usr WHERE id = match_user AND NOT deleted;
+
+    -- (Insta)Fail if we couldn't find the user
+    IF user_object.id IS NULL THEN
+        result.fail_part := 'no_user';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    -- Need item info to look up matchpoints
+    SELECT INTO item_object * FROM asset.copy WHERE id = match_item AND NOT deleted;
+
+    -- (Insta)Fail if we couldn't find the item 
+    IF item_object.id IS NULL THEN
+        result.fail_part := 'no_item';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    SELECT INTO circ_test * FROM action.find_circ_matrix_matchpoint(circ_ou, item_object, user_object, renewal);
+
+    circ_matchpoint             := circ_test.matchpoint;
+    result.matchpoint           := circ_matchpoint.id;
+    result.circulate            := circ_matchpoint.circulate;
+    result.duration_rule        := circ_matchpoint.duration_rule;
+    result.recurring_fine_rule  := circ_matchpoint.recurring_fine_rule;
+    result.max_fine_rule        := circ_matchpoint.max_fine_rule;
+    result.hard_due_date        := circ_matchpoint.hard_due_date;
+    result.renewals             := circ_matchpoint.renewals;
+    result.grace_period         := circ_matchpoint.grace_period;
+    result.buildrows            := circ_test.buildrows;
+
+    -- (Insta)Fail if we couldn't find a matchpoint
+    IF circ_test.success = false THEN
+        result.fail_part := 'no_matchpoint';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+        RETURN;
+    END IF;
+
+    -- All failures before this point are non-recoverable
+    -- Below this point are possibly overridable failures
+
+    -- Fail if the user is barred
+    IF user_object.barred IS TRUE THEN
+        result.fail_part := 'actor.usr.barred';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the item can't circulate
+    IF item_object.circulate IS FALSE THEN
+        result.fail_part := 'asset.copy.circulate';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the item isn't in a circulateable status on a non-renewal
+    IF NOT renewal AND item_object.status NOT IN ( 0, 7, 8 ) THEN 
+        result.fail_part := 'asset.copy.status';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    -- Alternately, fail if the item isn't checked out on a renewal
+    ELSIF renewal AND item_object.status <> 1 THEN
+        result.fail_part := 'asset.copy.status';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the item can't circulate because of the shelving location
+    SELECT INTO item_location_object * FROM asset.copy_location WHERE id = item_object.location;
+    IF item_location_object.circulate IS FALSE THEN
+        result.fail_part := 'asset.copy_location.circulate';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Use Circ OU for penalties and such
+    SELECT INTO context_org_list ARRAY_AGG(id) FROM actor.org_unit_full_path( circ_ou );
+
+    -- Proximity of user's home_ou to circ_ou to see if penalties should be ignored.
+    SELECT INTO home_prox prox FROM actor.org_unit_proximity WHERE from_org = user_object.home_ou AND to_org = circ_ou;
+
+    -- Proximity of user's home_ou to item circ_lib to see if penalties should be ignored.
+    SELECT INTO item_prox prox FROM actor.org_unit_proximity WHERE from_org = user_object.home_ou AND to_org = item_object.circ_lib;
+
+    IF renewal THEN
+        penalty_type = '%RENEW%';
+    ELSE
+        penalty_type = '%CIRC%';
+    END IF;
+
+    FOR standing_penalty IN
+        SELECT  DISTINCT csp.*
+          FROM  actor.usr_standing_penalty usp
+                JOIN config.standing_penalty csp ON (csp.id = usp.standing_penalty)
+          WHERE usr = match_user
+                AND usp.org_unit IN ( SELECT * FROM unnest(context_org_list) )
+                AND (usp.stop_date IS NULL or usp.stop_date > NOW())
+                AND (csp.ignore_proximity IS NULL
+                     OR csp.ignore_proximity < home_prox
+                     OR csp.ignore_proximity < item_prox)
+                AND csp.block_list LIKE penalty_type LOOP
+
+        result.fail_part := standing_penalty.name;
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END LOOP;
+
+    -- Fail if the test is set to hard non-circulating
+    IF circ_matchpoint.circulate IS FALSE THEN
+        result.fail_part := 'config.circ_matrix_test.circulate';
+        result.success := FALSE;
+        done := TRUE;
+        RETURN NEXT result;
+    END IF;
+
+    -- Fail if the total copy-hold ratio is too low
+    IF circ_matchpoint.total_copy_hold_ratio IS NOT NULL THEN
+        SELECT INTO hold_ratio * FROM action.copy_related_hold_stats(match_item);
+        IF hold_ratio.total_copy_ratio IS NOT NULL AND hold_ratio.total_copy_ratio < circ_matchpoint.total_copy_hold_ratio THEN
+            result.fail_part := 'config.circ_matrix_test.total_copy_hold_ratio';
+            result.success := FALSE;
+            done := TRUE;
+            RETURN NEXT result;
+        END IF;
+    END IF;
+
+    -- Fail if the available copy-hold ratio is too low
+    IF circ_matchpoint.available_copy_hold_ratio IS NOT NULL THEN
+        IF hold_ratio.hold_count IS NULL THEN
+            SELECT INTO hold_ratio * FROM action.copy_related_hold_stats(match_item);
+        END IF;
+        IF hold_ratio.available_copy_ratio IS NOT NULL AND hold_ratio.available_copy_ratio < circ_matchpoint.available_copy_hold_ratio THEN
+            result.fail_part := 'config.circ_matrix_test.available_copy_hold_ratio';
+            result.success := FALSE;
+            done := TRUE;
+            RETURN NEXT result;
+        END IF;
+    END IF;
+
+    -- Fail if the user has too many items out by defined limit sets
+    FOR circ_limit_set IN SELECT ccls.* FROM config.circ_limit_set ccls
+      JOIN config.circ_matrix_limit_set_map ccmlsm ON ccmlsm.limit_set = ccls.id
+      WHERE ccmlsm.active AND ( ccmlsm.matchpoint = circ_matchpoint.id OR
+        ( ccmlsm.matchpoint IN (SELECT * FROM unnest(result.buildrows)) AND ccmlsm.fallthrough )
+        ) LOOP
+            IF circ_limit_set.items_out > 0 AND NOT renewal THEN
+                SELECT INTO context_org_list ARRAY_AGG(aou.id)
+                  FROM actor.org_unit_full_path( circ_ou ) aou
+                    JOIN actor.org_unit_type aout ON aou.ou_type = aout.id
+                  WHERE aout.depth >= circ_limit_set.depth;
+                IF circ_limit_set.global THEN
+                    WITH RECURSIVE descendant_depth AS (
+                        SELECT  ou.id,
+                            ou.parent_ou
+                        FROM  actor.org_unit ou
+                        WHERE ou.id IN (SELECT * FROM unnest(context_org_list))
+                            UNION
+                        SELECT  ou.id,
+                            ou.parent_ou
+                        FROM  actor.org_unit ou
+                            JOIN descendant_depth ot ON (ot.id = ou.parent_ou)
+                    ) SELECT INTO context_org_list ARRAY_AGG(ou.id) FROM actor.org_unit ou JOIN descendant_depth USING (id);
+                END IF;
+                SELECT INTO items_out COUNT(DISTINCT circ.id)
+                  FROM action.circulation circ
+                    JOIN asset.copy copy ON (copy.id = circ.target_copy)
+                    LEFT JOIN action.circulation_limit_group_map aclgm ON (circ.id = aclgm.circ)
+                  WHERE circ.usr = match_user
+                    AND circ.circ_lib IN (SELECT * FROM unnest(context_org_list))
+                    AND circ.checkin_time IS NULL
+                    AND (circ.stop_fines IN ('MAXFINES','LONGOVERDUE') OR circ.stop_fines IS NULL)
+                    AND (copy.circ_modifier IN (SELECT circ_mod FROM config.circ_limit_set_circ_mod_map WHERE limit_set = circ_limit_set.id)
+                        OR copy.location IN (SELECT copy_loc FROM config.circ_limit_set_copy_loc_map WHERE limit_set = circ_limit_set.id)
+                        OR aclgm.limit_group IN (SELECT limit_group FROM config.circ_limit_set_group_map WHERE limit_set = circ_limit_set.id)
+                    );
+                IF items_out >= circ_limit_set.items_out THEN
+                    result.fail_part := 'config.circ_matrix_circ_mod_test';
+                    result.success := FALSE;
+                    done := TRUE;
+                    RETURN NEXT result;
+                END IF;
+            END IF;
+            SELECT INTO result.limit_groups result.limit_groups || ARRAY_AGG(limit_group) FROM config.circ_limit_set_group_map WHERE limit_set = circ_limit_set.id AND NOT check_only;
+    END LOOP;
+
+    -- If we passed everything, return the successful matchpoint
+    IF NOT done THEN
+        RETURN NEXT result;
+    END IF;
+
+    RETURN;
+END;
+$func$ LANGUAGE plpgsql;
+
+SELECT evergreen.upgrade_deps_block_check('0952', :eg_version); --miker/kmlussier/gmcharlt
+
+INSERT INTO config.metabib_field ( id, field_class, name, label, format, xpath, browse_field, facet_field, facet_xpath, joiner ) VALUES
+    (33, 'identifier', 'genre', oils_i18n_gettext(33, 'Genre', 'cmf', 'label'), 'marcxml', $$//marc:datafield[@tag='655']$$, FALSE, TRUE, $$//*[local-name()='subfield' and contains('abvxyz', at code)]$$, ' -- ' ); -- /* to fool vim */;
+
+INSERT INTO config.metabib_field_index_norm_map (field,norm)
+    SELECT  m.id,
+            i.id
+      FROM  config.metabib_field m,
+        config.index_normalizer i
+      WHERE i.func IN ('search_normalize','split_date_range')
+            AND m.id IN (33);
+
+SELECT evergreen.upgrade_deps_block_check('0953', :eg_version);
+
+CREATE OR REPLACE FUNCTION unapi.bre (
+    obj_id BIGINT,
+    format TEXT,
+    ename TEXT,
+    includes TEXT[],
+    org TEXT,
+    depth INT DEFAULT NULL,
+    slimit HSTORE DEFAULT NULL,
+    soffset HSTORE DEFAULT NULL,
+    include_xmlns BOOL DEFAULT TRUE,
+    pref_lib INT DEFAULT NULL
+)
+RETURNS XML AS $F$
+DECLARE
+    me      biblio.record_entry%ROWTYPE;
+    layout  unapi.bre_output_layout%ROWTYPE;
+    xfrm    config.xml_transform%ROWTYPE;
+    ouid    INT;
+    tmp_xml TEXT;
+    top_el  TEXT;
+    output  XML;
+    hxml    XML;
+    axml    XML;
+    source  XML;
+BEGIN
+
+    IF org = '-' OR org IS NULL THEN
+        SELECT shortname INTO org FROM evergreen.org_top();
+    END IF;
+
+    SELECT id INTO ouid FROM actor.org_unit WHERE shortname = org;
+
+    IF ouid IS NULL THEN
+        RETURN NULL::XML;
+    END IF;
+
+    IF format = 'holdings_xml' THEN -- the special case
+        output := unapi.holdings_xml( obj_id, ouid, org, depth, includes, slimit, soffset, include_xmlns);
+        RETURN output;
+    END IF;
+
+    SELECT * INTO layout FROM unapi.bre_output_layout WHERE name = format;
+
+    IF layout.name IS NULL THEN
+        RETURN NULL::XML;
+    END IF;
+
+    SELECT * INTO xfrm FROM config.xml_transform WHERE name = layout.transform;
+
+    SELECT * INTO me FROM biblio.record_entry WHERE id = obj_id;
+
+    -- grab bib_source, if any
+    IF ('cbs' = ANY (includes) AND me.source IS NOT NULL) THEN
+        source := unapi.cbs(me.source,NULL,NULL,NULL,NULL);
+    ELSE
+        source := NULL::XML;
+    END IF;
+
+    -- grab SVF if we need them
+    IF ('mra' = ANY (includes)) THEN 
+        axml := unapi.mra(obj_id,NULL,NULL,NULL,NULL);
+    ELSE
+        axml := NULL::XML;
+    END IF;
+
+    -- grab holdings if we need them
+    IF ('holdings_xml' = ANY (includes)) THEN 
+        hxml := unapi.holdings_xml(obj_id, ouid, org, depth, evergreen.array_remove_item_by_value(includes,'holdings_xml'), slimit, soffset, include_xmlns, pref_lib);
+    ELSE
+        hxml := NULL::XML;
+    END IF;
+
+
+    -- generate our item node
+
+
+    IF format = 'marcxml' THEN
+        tmp_xml := me.marc;
+        IF tmp_xml !~ E'<marc:' THEN -- If we're not using the prefixed namespace in this record, then remove all declarations of it
+           tmp_xml := REGEXP_REPLACE(tmp_xml, ' xmlns:marc="http://www.loc.gov/MARC21/slim"', '', 'g');
+        END IF; 
+    ELSE
+        tmp_xml := oils_xslt_process(me.marc, xfrm.xslt)::XML;
+    END IF;
+
+    top_el := REGEXP_REPLACE(tmp_xml, E'^.*?<((?:\\S+:)?' || layout.holdings_element || ').*$', E'\\1');
+
+    IF source IS NOT NULL THEN
+        tmp_xml := REGEXP_REPLACE(tmp_xml, '</' || top_el || '>(.*?)$', source || '</' || top_el || E'>\\1');
+    END IF;
+
+    IF axml IS NOT NULL THEN 
+        tmp_xml := REGEXP_REPLACE(tmp_xml, '</' || top_el || '>(.*?)$', axml || '</' || top_el || E'>\\1');
+    END IF;
+
+    IF hxml IS NOT NULL THEN -- XXX how do we configure the holdings position?
+        tmp_xml := REGEXP_REPLACE(tmp_xml, '</' || top_el || '>(.*?)$', hxml || '</' || top_el || E'>\\1');
+    END IF;
+
+    IF ('bre.unapi' = ANY (includes)) THEN 
+        output := REGEXP_REPLACE(
+            tmp_xml,
+            '</' || top_el || '>(.*?)',
+            XMLELEMENT(
+                name abbr,
+                XMLATTRIBUTES(
+                    'http://www.w3.org/1999/xhtml' AS xmlns,
+                    'unapi-id' AS class,
+                    'tag:open-ils.org:U2 at bre/' || obj_id || '/' || org AS title
+                )
+            )::TEXT || '</' || top_el || E'>\\1'
+        );
+    ELSE
+        output := tmp_xml;
+    END IF;
+
+    IF ('bre.extern' = ANY (includes)) THEN 
+        output := REGEXP_REPLACE(
+            tmp_xml,
+            '</' || top_el || '>(.*?)',
+            XMLELEMENT(
+                name extern,
+                XMLATTRIBUTES(
+                    'http://open-ils.org/spec/biblio/v1' AS xmlns,
+                    me.creator AS creator,
+                    me.editor AS editor,
+                    me.create_date AS create_date,
+                    me.edit_date AS edit_date,
+                    me.quality AS quality,
+                    me.fingerprint AS fingerprint,
+                    me.tcn_source AS tcn_source,
+                    me.tcn_value AS tcn_value,
+                    me.owner AS owner,
+                    me.share_depth AS share_depth,
+                    me.active AS active,
+                    me.deleted AS deleted
+                )
+            )::TEXT || '</' || top_el || E'>\\1'
+        );
+    ELSE
+        output := tmp_xml;
+    END IF;
+
+    output := REGEXP_REPLACE(output::TEXT,E'>\\s+<','><','gs')::XML;
+    RETURN output;
+END;
+$F$ LANGUAGE PLPGSQL STABLE;
+
+SELECT evergreen.upgrade_deps_block_check('0954', :eg_version);
+
+ALTER TABLE acq.fund_debit 
+    ADD COLUMN invoice_entry INTEGER 
+        REFERENCES acq.invoice_entry (id)
+        ON DELETE SET NULL;
+
+CREATE INDEX fund_debit_invoice_entry_idx ON acq.fund_debit (invoice_entry);
+CREATE INDEX lineitem_detail_fund_debit_idx ON acq.lineitem_detail (fund_debit);
+
+SELECT evergreen.upgrade_deps_block_check('0955', :eg_version);
+
+UPDATE config.org_unit_setting_type
+SET description = 'Regular expression defining the password format.  Note: Be sure to update the update_password_msg.tt2 TPAC template with a user-friendly description of your password strength requirements.'
+WHERE NAME = 'global.password_regex';
+
+SELECT evergreen.upgrade_deps_block_check('0956', :eg_version);
+
+ALTER TABLE money.credit_card_payment 
+    DROP COLUMN cc_type,
+    DROP COLUMN expire_month,
+    DROP COLUMN expire_year,
+    DROP COLUMN cc_first_name,
+    DROP COLUMN cc_last_name;
+
+SELECT evergreen.upgrade_deps_block_check('0957', :eg_version);
+
+-- Remove references to dropped CC payment columns in the print/email 
+-- payment receipt templates, but only if the in-db template matches 
+-- the stock template.
+-- The actual diff here is only about 8 lines.
+
+UPDATE action_trigger.event_definition SET template = 
+$$
+[%- USE date -%]
+[%- SET user = target.0.xact.usr -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- params.sender_email || default_sender %]
+Subject: Payment Receipt
+
+[% date.format -%]
+[%- SET xact_mp_hash = {} -%]
+[%- FOR mp IN target %][%# Template is hooked around payments, but let us make the receipt focused on transactions -%]
+    [%- SET xact_id = mp.xact.id -%]
+    [%- IF ! xact_mp_hash.defined( xact_id ) -%][%- xact_mp_hash.$xact_id = { 'xact' => mp.xact, 'payments' => [] } -%][%- END -%]
+    [%- xact_mp_hash.$xact_id.payments.push(mp) -%]
+[%- END -%]
+[%- FOR xact_id IN xact_mp_hash.keys.sort -%]
+    [%- SET xact = xact_mp_hash.$xact_id.xact %]
+Transaction ID: [% xact_id %]
+    [% IF xact.circulation %][% helpers.get_copy_bib_basics(xact.circulation.target_copy).title %]
+    [% ELSE %]Miscellaneous
+    [% END %]
+    Line item billings:
+        [%- SET mb_type_hash = {} -%]
+        [%- FOR mb IN xact.billings %][%# Group billings by their btype -%]
+            [%- IF mb.voided == 'f' -%]
+                [%- SET mb_type = mb.btype.id -%]
+                [%- IF ! mb_type_hash.defined( mb_type ) -%][%- mb_type_hash.$mb_type = { 'sum' => 0.00, 'billings' => [] } -%][%- END -%]
+                [%- IF ! mb_type_hash.$mb_type.defined( 'first_ts' ) -%][%- mb_type_hash.$mb_type.first_ts = mb.billing_ts -%][%- END -%]
+                [%- mb_type_hash.$mb_type.last_ts = mb.billing_ts -%]
+                [%- mb_type_hash.$mb_type.sum = mb_type_hash.$mb_type.sum + mb.amount -%]
+                [%- mb_type_hash.$mb_type.billings.push( mb ) -%]
+            [%- END -%]
+        [%- END -%]
+        [%- FOR mb_type IN mb_type_hash.keys.sort -%]
+            [%- IF mb_type == 1 %][%-# Consolidated view of overdue billings -%]
+                $[% mb_type_hash.$mb_type.sum %] for [% mb_type_hash.$mb_type.billings.0.btype.name %] 
+                    on [% mb_type_hash.$mb_type.first_ts %] through [% mb_type_hash.$mb_type.last_ts %]
+            [%- ELSE -%][%# all other billings show individually %]
+                [% FOR mb IN mb_type_hash.$mb_type.billings %]
+                    $[% mb.amount %] for [% mb.btype.name %] on [% mb.billing_ts %] [% mb.note %]
+                [% END %]
+            [% END %]
+        [% END %]
+    Line item payments:
+        [% FOR mp IN xact_mp_hash.$xact_id.payments %]
+            Payment ID: [% mp.id %]
+                Paid [% mp.amount %] via [% SWITCH mp.payment_type -%]
+                    [% CASE "cash_payment" %]cash
+                    [% CASE "check_payment" %]check
+                    [% CASE "credit_card_payment" %]credit card
+                    [%- IF mp.credit_card_payment.cc_number %] ([% mp.credit_card_payment.cc_number %])[% END %]
+                    [% CASE "credit_payment" %]credit
+                    [% CASE "forgive_payment" %]forgiveness
+                    [% CASE "goods_payment" %]goods
+                    [% CASE "work_payment" %]work
+                [%- END %] on [% mp.payment_ts %] [% mp.note %]
+        [% END %]
+[% END %]
+$$
+
+WHERE id = 29 AND template =
+
+$$
+[%- USE date -%]
+[%- SET user = target.0.xact.usr -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- params.sender_email || default_sender %]
+Subject: Payment Receipt
+
+[% date.format -%]
+[%- SET xact_mp_hash = {} -%]
+[%- FOR mp IN target %][%# Template is hooked around payments, but let us make the receipt focused on transactions -%]
+    [%- SET xact_id = mp.xact.id -%]
+    [%- IF ! xact_mp_hash.defined( xact_id ) -%][%- xact_mp_hash.$xact_id = { 'xact' => mp.xact, 'payments' => [] } -%][%- END -%]
+    [%- xact_mp_hash.$xact_id.payments.push(mp) -%]
+[%- END -%]
+[%- FOR xact_id IN xact_mp_hash.keys.sort -%]
+    [%- SET xact = xact_mp_hash.$xact_id.xact %]
+Transaction ID: [% xact_id %]
+    [% IF xact.circulation %][% helpers.get_copy_bib_basics(xact.circulation.target_copy).title %]
+    [% ELSE %]Miscellaneous
+    [% END %]
+    Line item billings:
+        [%- SET mb_type_hash = {} -%]
+        [%- FOR mb IN xact.billings %][%# Group billings by their btype -%]
+            [%- IF mb.voided == 'f' -%]
+                [%- SET mb_type = mb.btype.id -%]
+                [%- IF ! mb_type_hash.defined( mb_type ) -%][%- mb_type_hash.$mb_type = { 'sum' => 0.00, 'billings' => [] } -%][%- END -%]
+                [%- IF ! mb_type_hash.$mb_type.defined( 'first_ts' ) -%][%- mb_type_hash.$mb_type.first_ts = mb.billing_ts -%][%- END -%]
+                [%- mb_type_hash.$mb_type.last_ts = mb.billing_ts -%]
+                [%- mb_type_hash.$mb_type.sum = mb_type_hash.$mb_type.sum + mb.amount -%]
+                [%- mb_type_hash.$mb_type.billings.push( mb ) -%]
+            [%- END -%]
+        [%- END -%]
+        [%- FOR mb_type IN mb_type_hash.keys.sort -%]
+            [%- IF mb_type == 1 %][%-# Consolidated view of overdue billings -%]
+                $[% mb_type_hash.$mb_type.sum %] for [% mb_type_hash.$mb_type.billings.0.btype.name %] 
+                    on [% mb_type_hash.$mb_type.first_ts %] through [% mb_type_hash.$mb_type.last_ts %]
+            [%- ELSE -%][%# all other billings show individually %]
+                [% FOR mb IN mb_type_hash.$mb_type.billings %]
+                    $[% mb.amount %] for [% mb.btype.name %] on [% mb.billing_ts %] [% mb.note %]
+                [% END %]
+            [% END %]
+        [% END %]
+    Line item payments:
+        [% FOR mp IN xact_mp_hash.$xact_id.payments %]
+            Payment ID: [% mp.id %]
+                Paid [% mp.amount %] via [% SWITCH mp.payment_type -%]
+                    [% CASE "cash_payment" %]cash
+                    [% CASE "check_payment" %]check
+                    [% CASE "credit_card_payment" %]credit card (
+                        [%- SET cc_chunks = mp.credit_card_payment.cc_number.replace(' ','').chunk(4); -%]
+                        [%- cc_chunks.slice(0, -1+cc_chunks.max).join.replace('\S','X') -%] 
+                        [% cc_chunks.last -%]
+                        exp [% mp.credit_card_payment.expire_month %]/[% mp.credit_card_payment.expire_year -%]
+                    )
+                    [% CASE "credit_payment" %]credit
+                    [% CASE "forgive_payment" %]forgiveness
+                    [% CASE "goods_payment" %]goods
+                    [% CASE "work_payment" %]work
+                [%- END %] on [% mp.payment_ts %] [% mp.note %]
+        [% END %]
+[% END %]
+$$;
+
+
+UPDATE action_trigger.event_definition SET template = 
+$$
+[%- USE date -%][%- SET user = target.0.xact.usr -%]
+<div style="li { padding: 8px; margin 5px; }">
+    <div>[% date.format %]</div><br/>
+    <ol>
+    [% SET xact_mp_hash = {} %]
+    [% FOR mp IN target %][%# Template is hooked around payments, but let us make the receipt focused on transactions %]
+        [% SET xact_id = mp.xact.id %]
+        [% IF ! xact_mp_hash.defined( xact_id ) %][% xact_mp_hash.$xact_id = { 'xact' => mp.xact, 'payments' => [] } %][% END %]
+        [% xact_mp_hash.$xact_id.payments.push(mp) %]
+    [% END %]
+    [% FOR xact_id IN xact_mp_hash.keys.sort %]
+        [% SET xact = xact_mp_hash.$xact_id.xact %]
+        <li>Transaction ID: [% xact_id %]
+            [% IF xact.circulation %][% helpers.get_copy_bib_basics(xact.circulation.target_copy).title %]
+            [% ELSE %]Miscellaneous
+            [% END %]
+            Line item billings:<ol>
+                [% SET mb_type_hash = {} %]
+                [% FOR mb IN xact.billings %][%# Group billings by their btype %]
+                    [% IF mb.voided == 'f' %]
+                        [% SET mb_type = mb.btype.id %]
+                        [% IF ! mb_type_hash.defined( mb_type ) %][% mb_type_hash.$mb_type = { 'sum' => 0.00, 'billings' => [] } %][% END %]
+                        [% IF ! mb_type_hash.$mb_type.defined( 'first_ts' ) %][% mb_type_hash.$mb_type.first_ts = mb.billing_ts %][% END %]
+                        [% mb_type_hash.$mb_type.last_ts = mb.billing_ts %]
+                        [% mb_type_hash.$mb_type.sum = mb_type_hash.$mb_type.sum + mb.amount %]
+                        [% mb_type_hash.$mb_type.billings.push( mb ) %]
+                    [% END %]
+                [% END %]
+                [% FOR mb_type IN mb_type_hash.keys.sort %]
+                    <li>[% IF mb_type == 1 %][%# Consolidated view of overdue billings %]
+                        $[% mb_type_hash.$mb_type.sum %] for [% mb_type_hash.$mb_type.billings.0.btype.name %] 
+                            on [% mb_type_hash.$mb_type.first_ts %] through [% mb_type_hash.$mb_type.last_ts %]
+                    [% ELSE %][%# all other billings show individually %]
+                        [% FOR mb IN mb_type_hash.$mb_type.billings %]
+                            $[% mb.amount %] for [% mb.btype.name %] on [% mb.billing_ts %] [% mb.note %]
+                        [% END %]
+                    [% END %]</li>
+                [% END %]
+            </ol>
+            Line item payments:<ol>
+                [% FOR mp IN xact_mp_hash.$xact_id.payments %]
+                    <li>Payment ID: [% mp.id %]
+                        Paid [% mp.amount %] via [% SWITCH mp.payment_type -%]
+                            [% CASE "cash_payment" %]cash
+                            [% CASE "check_payment" %]check
+                            [% CASE "credit_card_payment" %]credit card
+                            [%- IF mp.credit_card_payment.cc_number %] ([% mp.credit_card_payment.cc_number %])[% END %]
+                            [% CASE "credit_payment" %]credit
+                            [% CASE "forgive_payment" %]forgiveness
+                            [% CASE "goods_payment" %]goods
+                            [% CASE "work_payment" %]work
+                        [%- END %] on [% mp.payment_ts %] [% mp.note %]
+                    </li>
+                [% END %]
+            </ol>
+        </li>
+    [% END %]
+    </ol>
+</div>
+$$
+
+WHERE id = 30 AND template =
+
+$$
+[%- USE date -%][%- SET user = target.0.xact.usr -%]
+<div style="li { padding: 8px; margin 5px; }">
+    <div>[% date.format %]</div><br/>
+    <ol>
+    [% SET xact_mp_hash = {} %]
+    [% FOR mp IN target %][%# Template is hooked around payments, but let us make the receipt focused on transactions %]
+        [% SET xact_id = mp.xact.id %]
+        [% IF ! xact_mp_hash.defined( xact_id ) %][% xact_mp_hash.$xact_id = { 'xact' => mp.xact, 'payments' => [] } %][% END %]
+        [% xact_mp_hash.$xact_id.payments.push(mp) %]
+    [% END %]
+    [% FOR xact_id IN xact_mp_hash.keys.sort %]
+        [% SET xact = xact_mp_hash.$xact_id.xact %]
+        <li>Transaction ID: [% xact_id %]
+            [% IF xact.circulation %][% helpers.get_copy_bib_basics(xact.circulation.target_copy).title %]
+            [% ELSE %]Miscellaneous
+            [% END %]
+            Line item billings:<ol>
+                [% SET mb_type_hash = {} %]
+                [% FOR mb IN xact.billings %][%# Group billings by their btype %]
+                    [% IF mb.voided == 'f' %]
+                        [% SET mb_type = mb.btype.id %]
+                        [% IF ! mb_type_hash.defined( mb_type ) %][% mb_type_hash.$mb_type = { 'sum' => 0.00, 'billings' => [] } %][% END %]
+                        [% IF ! mb_type_hash.$mb_type.defined( 'first_ts' ) %][% mb_type_hash.$mb_type.first_ts = mb.billing_ts %][% END %]
+                        [% mb_type_hash.$mb_type.last_ts = mb.billing_ts %]
+                        [% mb_type_hash.$mb_type.sum = mb_type_hash.$mb_type.sum + mb.amount %]
+                        [% mb_type_hash.$mb_type.billings.push( mb ) %]
+                    [% END %]
+                [% END %]
+                [% FOR mb_type IN mb_type_hash.keys.sort %]
+                    <li>[% IF mb_type == 1 %][%# Consolidated view of overdue billings %]
+                        $[% mb_type_hash.$mb_type.sum %] for [% mb_type_hash.$mb_type.billings.0.btype.name %] 
+                            on [% mb_type_hash.$mb_type.first_ts %] through [% mb_type_hash.$mb_type.last_ts %]
+                    [% ELSE %][%# all other billings show individually %]
+                        [% FOR mb IN mb_type_hash.$mb_type.billings %]
+                            $[% mb.amount %] for [% mb.btype.name %] on [% mb.billing_ts %] [% mb.note %]
+                        [% END %]
+                    [% END %]</li>
+                [% END %]
+            </ol>
+            Line item payments:<ol>
+                [% FOR mp IN xact_mp_hash.$xact_id.payments %]
+                    <li>Payment ID: [% mp.id %]
+                        Paid [% mp.amount %] via [% SWITCH mp.payment_type -%]
+                            [% CASE "cash_payment" %]cash
+                            [% CASE "check_payment" %]check
+                            [% CASE "credit_card_payment" %]credit card (
+                                [%- SET cc_chunks = mp.credit_card_payment.cc_number.replace(' ','').chunk(4); -%]
+                                [%- cc_chunks.slice(0, -1+cc_chunks.max).join.replace('\S','X') -%] 
+                                [% cc_chunks.last -%]
+                                exp [% mp.credit_card_payment.expire_month %]/[% mp.credit_card_payment.expire_year -%]
+                            )
+                            [% CASE "credit_payment" %]credit
+                            [% CASE "forgive_payment" %]forgiveness
+                            [% CASE "goods_payment" %]goods
+                            [% CASE "work_payment" %]work
+                        [%- END %] on [% mp.payment_ts %] [% mp.note %]
+                    </li>
+                [% END %]
+            </ol>
+        </li>
+    [% END %]
+    </ol>
+</div>
+$$;
+
+
+SELECT evergreen.upgrade_deps_block_check('0958', :eg_version);
+
+CREATE OR REPLACE FUNCTION search.facets_for_record_set(ignore_facet_classes TEXT[], hits BIGINT[]) RETURNS TABLE (id INT, value TEXT, count BIGINT) AS $$
+    SELECT id, value, count FROM (
+        SELECT mfae.field AS id,
+               mfae.value,
+               COUNT(DISTINCT mmrsm.source),
+               row_number() OVER (
+                PARTITION BY mfae.field ORDER BY COUNT(distinct mmrsm.source) DESC
+               ) AS rownum
+        FROM metabib.facet_entry mfae
+        JOIN metabib.metarecord_source_map mmrsm ON (mfae.source = mmrsm.source)
+        JOIN config.metabib_field cmf ON (cmf.id = mfae.field)
+        WHERE mmrsm.source IN (SELECT * FROM unnest($2))
+        AND cmf.facet_field
+        AND cmf.field_class NOT IN (SELECT * FROM unnest($1))
+        GROUP by 1, 2
+    ) all_facets
+    WHERE rownum <= (SELECT COALESCE((SELECT value::INT FROM config.global_flag WHERE name = 'search.max_facets_per_field' AND enabled), 1000));
+$$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION search.facets_for_metarecord_set(ignore_facet_classes TEXT[], hits BIGINT[]) RETURNS TABLE (id INT, value TEXT, count BIGINT) AS $$
+    SELECT id, value, count FROM (
+        SELECT mfae.field AS id,
+               mfae.value,
+               COUNT(DISTINCT mmrsm.metarecord),
+               row_number() OVER (
+                PARTITION BY mfae.field ORDER BY COUNT(distinct mmrsm.metarecord) DESC
+               ) AS rownum
+        FROM metabib.facet_entry mfae
+        JOIN metabib.metarecord_source_map mmrsm ON (mfae.source = mmrsm.source)
+        JOIN config.metabib_field cmf ON (cmf.id = mfae.field)
+        WHERE mmrsm.metarecord IN (SELECT * FROM unnest($2))
+        AND cmf.facet_field
+        AND cmf.field_class NOT IN (SELECT * FROM unnest($1))
+        GROUP by 1, 2
+    ) all_facets
+    WHERE rownum <= (SELECT COALESCE((SELECT value::INT FROM config.global_flag WHERE name = 'search.max_facets_per_field' AND enabled), 1000));
+$$ LANGUAGE SQL;
+
+INSERT INTO config.global_flag (name, value, label, enabled)
+    VALUES (
+        'search.max_facets_per_field',
+        '1000',
+        oils_i18n_gettext(
+            'search.max_facets_per_field',
+            'Search: maximum number of facet values to retrieve for each facet field',
+            'cgf',
+            'label'
+        ),
+        TRUE
+    );
+
+SELECT evergreen.upgrade_deps_block_check('0960', :eg_version); 
+
+CREATE TABLE action.usr_circ_history (
+    id           BIGSERIAL PRIMARY KEY,
+    usr          INTEGER NOT NULL REFERENCES actor.usr(id)
+                 DEFERRABLE INITIALLY DEFERRED,
+    xact_start   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+    target_copy  BIGINT NOT NULL REFERENCES asset.copy(id)
+                 DEFERRABLE INITIALLY DEFERRED,
+    due_date     TIMESTAMP WITH TIME ZONE NOT NULL,
+    checkin_time TIMESTAMP WITH TIME ZONE,
+    source_circ  BIGINT REFERENCES action.circulation(id)
+                 ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED
+);
+
+CREATE OR REPLACE FUNCTION action.maintain_usr_circ_history() 
+    RETURNS TRIGGER AS $FUNK$
+DECLARE
+    cur_circ  BIGINT;
+    first_circ BIGINT;
+BEGIN                                                                          
+
+    -- Any retention value signifies history is enabled.
+    -- This assumes that clearing these values via external 
+    -- process deletes the action.usr_circ_history rows.
+    -- TODO: replace these settings w/ a single bool setting?
+    PERFORM 1 FROM actor.usr_setting 
+        WHERE usr = NEW.usr AND value IS NOT NULL AND name IN (
+            'history.circ.retention_age', 
+            'history.circ.retention_start'
+        );
+
+    IF NOT FOUND THEN
+        RETURN NEW;
+    END IF;
+
+    IF TG_OP = 'INSERT' AND NEW.parent_circ IS NULL THEN
+        -- Starting a new circulation.  Insert the history row.
+        INSERT INTO action.usr_circ_history 
+            (usr, xact_start, target_copy, due_date, source_circ)
+        VALUES (
+            NEW.usr, 
+            NEW.xact_start, 
+            NEW.target_copy, 
+            NEW.due_date, 
+            NEW.id
+        );
+
+        RETURN NEW;
+    END IF;
+
+    -- find the first and last circs in the circ chain 
+    -- for the currently modified circ.
+    FOR cur_circ IN SELECT id FROM action.circ_chain(NEW.id) LOOP
+        IF first_circ IS NULL THEN
+            first_circ := cur_circ;
+            CONTINUE;
+        END IF;
+        -- Allow the loop to continue so that at as the loop
+        -- completes cur_circ points to the final circulation.
+    END LOOP;
+
+    IF NEW.id <> cur_circ THEN
+        -- Modifying an intermediate circ.  Ignore it.
+        RETURN NEW;
+    END IF;
+
+    -- Update the due_date/checkin_time on the history row if the current 
+    -- circ is the last circ in the chain and an update is warranted.
+
+    UPDATE action.usr_circ_history 
+        SET 
+            due_date = NEW.due_date,
+            checkin_time = NEW.checkin_time
+        WHERE 
+            source_circ = first_circ 
+            AND (
+                due_date <> NEW.due_date OR (
+                    (checkin_time IS NULL AND NEW.checkin_time IS NOT NULL) OR
+                    (checkin_time IS NOT NULL AND NEW.checkin_time IS NULL) OR
+                    (checkin_time <> NEW.checkin_time)
+                )
+            );
+    RETURN NEW;
+END;                                                                           
+$FUNK$ LANGUAGE PLPGSQL; 
+
+CREATE TRIGGER maintain_usr_circ_history_tgr 
+    AFTER INSERT OR UPDATE ON action.circulation 
+    FOR EACH ROW EXECUTE PROCEDURE action.maintain_usr_circ_history();
+
+UPDATE action_trigger.hook 
+    SET core_type = 'auch' 
+    WHERE key ~ '^circ.format.history.'; 
+
+UPDATE action_trigger.event_definition SET template = 
+$$
+[%- USE date -%]
+[%- SET user = target.0.usr -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- params.sender_email || default_sender %]
+Subject: Circulation History
+
+    [% FOR circ IN target %]
+            [% helpers.get_copy_bib_basics(circ.target_copy.id).title %]
+            Barcode: [% circ.target_copy.barcode %]
+            Checked Out: [% date.format(helpers.format_date(circ.xact_start), '%Y-%m-%d') %]
+            Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]
+            Returned: [%
+                date.format(
+                    helpers.format_date(circ.checkin_time), '%Y-%m-%d') 
+                    IF circ.checkin_time; 
+            %]
+    [% END %]
+$$
+WHERE id = 25 AND template = 
+$$
+[%- USE date -%]
+[%- SET user = target.0.usr -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- params.sender_email || default_sender %]
+Subject: Circulation History
+
+    [% FOR circ IN target %]
+            [% helpers.get_copy_bib_basics(circ.target_copy.id).title %]
+            Barcode: [% circ.target_copy.barcode %]
+            Checked Out: [% date.format(helpers.format_date(circ.xact_start), '%Y-%m-%d') %]
+            Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]
+            Returned: [% date.format(helpers.format_date(circ.checkin_time), '%Y-%m-%d') %]
+    [% END %]
+$$;
+
+-- avoid TT undef date errors
+UPDATE action_trigger.event_definition SET template = 
+$$
+[%- USE date -%]
+<div>
+    <style> li { padding: 8px; margin 5px; }</style>
+    <div>[% date.format %]</div>
+    <br/>
+
+    [% user.family_name %], [% user.first_given_name %]
+    <ol>
+    [% FOR circ IN target %]
+        <li>
+            <div>[% helpers.get_copy_bib_basics(circ.target_copy.id).title %]</div>
+            <div>Barcode: [% circ.target_copy.barcode %]</div>
+            <div>Checked Out: [% date.format(helpers.format_date(circ.xact_start), '%Y-%m-%d') %]</div>
+            <div>Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]</div>
+            <div>Returned: [%
+                date.format(
+                    helpers.format_date(circ.checkin_time), '%Y-%m-%d') 
+                    IF circ.checkin_time; -%]
+            </div>
+        </li>
+    [% END %]
+    </ol>
+</div>
+$$
+WHERE id = 26 AND template = -- only replace template if it matches stock
+$$
+[%- USE date -%]
+<div>
+    <style> li { padding: 8px; margin 5px; }</style>
+    <div>[% date.format %]</div>
+    <br/>
+
+    [% user.family_name %], [% user.first_given_name %]
+    <ol>
+    [% FOR circ IN target %]
+        <li>
+            <div>[% helpers.get_copy_bib_basics(circ.target_copy.id).title %]</div>
+            <div>Barcode: [% circ.target_copy.barcode %]</div>
+            <div>Checked Out: [% date.format(helpers.format_date(circ.xact_start), '%Y-%m-%d') %]</div>
+            <div>Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]</div>
+            <div>Returned: [% date.format(helpers.format_date(circ.checkin_time), '%Y-%m-%d') %]</div>
+        </li>
+    [% END %]
+    </ol>
+</div>
+$$;
+
+-- NOTE: ^-- stock CSV template does not include checkin_time, so 
+-- no modifications are required.
+
+-- Create circ history rows for existing circ history data.
+DO $FUNK$
+DECLARE
+    cur_usr   INTEGER;
+    cur_circ  action.circulation%ROWTYPE;
+    last_circ action.circulation%ROWTYPE;
+    counter   INTEGER DEFAULT 1;
+BEGIN
+
+    RAISE NOTICE 
+        'Migrating circ history for % users.  This might take a while...',
+        (SELECT COUNT(DISTINCT(au.id)) FROM actor.usr au
+            JOIN actor.usr_setting aus ON (aus.usr = au.id)
+            WHERE NOT au.deleted AND 
+                aus.name ~ '^history.circ.retention_');
+
+    FOR cur_usr IN 
+        SELECT DISTINCT(au.id)
+            FROM actor.usr au 
+            JOIN actor.usr_setting aus ON (aus.usr = au.id)
+            WHERE NOT au.deleted AND 
+                aus.name ~ '^history.circ.retention_' LOOP
+
+        FOR cur_circ IN SELECT * FROM action.usr_visible_circs(cur_usr) LOOP
+
+            -- Find the last circ in the circ chain.
+            SELECT INTO last_circ * 
+                FROM action.circ_chain(cur_circ.id) 
+                ORDER BY xact_start DESC LIMIT 1;
+
+            -- Create the history row.
+            -- It's OK if last_circ = cur_circ
+            INSERT INTO action.usr_circ_history 
+                (usr, xact_start, target_copy, 
+                    due_date, checkin_time, source_circ)
+            VALUES (
+                cur_circ.usr, 
+                cur_circ.xact_start, 
+                cur_circ.target_copy, 
+                last_circ.due_date, 
+                last_circ.checkin_time,
+                cur_circ.id
+            );
+
+            -- useful for alleviating administrator anxiety.
+            IF counter % 10000 = 0 THEN
+                RAISE NOTICE 'Migrated history for % total users', counter;
+            END IF;
+
+            counter := counter + 1;
+
+        END LOOP;
+    END LOOP;
+
+END $FUNK$;
+
+DROP FUNCTION IF EXISTS action.usr_visible_circs (INTEGER);
+DROP FUNCTION IF EXISTS action.usr_visible_circ_copies (INTEGER);
+
+-- remove user retention age checks
+CREATE OR REPLACE FUNCTION action.purge_circulations () RETURNS INT AS $func$
+DECLARE
+    org_keep_age    INTERVAL;
+    org_use_last    BOOL = false;
+    org_age_is_min  BOOL = false;
+    org_keep_count  INT;
+
+    keep_age        INTERVAL;
+
+    target_acp      RECORD;
+    circ_chain_head action.circulation%ROWTYPE;
+    circ_chain_tail action.circulation%ROWTYPE;
+
+    count_purged    INT;
+    num_incomplete  INT;
+
+    last_finished   TIMESTAMP WITH TIME ZONE;
+BEGIN
+
+    count_purged := 0;
+
+    SELECT value::INTERVAL INTO org_keep_age FROM config.global_flag WHERE name = 'history.circ.retention_age' AND enabled;
+
+    SELECT value::INT INTO org_keep_count FROM config.global_flag WHERE name = 'history.circ.retention_count' AND enabled;
+    IF org_keep_count IS NULL THEN
+        RETURN count_purged; -- Gimme a count to keep, or I keep them all, forever
+    END IF;
+
+    SELECT enabled INTO org_use_last FROM config.global_flag WHERE name = 'history.circ.retention_uses_last_finished';
+    SELECT enabled INTO org_age_is_min FROM config.global_flag WHERE name = 'history.circ.retention_age_is_min';
+
+    -- First, find copies with more than keep_count non-renewal circs
+    FOR target_acp IN
+        SELECT  target_copy,
+                COUNT(*) AS total_real_circs
+          FROM  action.circulation
+          WHERE parent_circ IS NULL
+                AND xact_finish IS NOT NULL
+          GROUP BY target_copy
+          HAVING COUNT(*) > org_keep_count
+    LOOP
+        -- And, for those, select circs that are finished and older than keep_age
+        FOR circ_chain_head IN
+            -- For reference, the subquery uses a window function to order the circs newest to oldest and number them
+            -- The outer query then uses that information to skip the most recent set the library wants to keep
+            -- End result is we don't care what order they come out in, as they are all potentials for deletion.
+            SELECT ac.* FROM action.circulation ac JOIN (
+              SELECT  rank() OVER (ORDER BY xact_start DESC), ac.id
+                FROM  action.circulation ac
+                WHERE ac.target_copy = target_acp.target_copy
+                  AND ac.parent_circ IS NULL
+                ORDER BY ac.xact_start ) ranked USING (id)
+                WHERE ranked.rank > org_keep_count
+        LOOP
+
+            SELECT * INTO circ_chain_tail FROM action.circ_chain(circ_chain_head.id) ORDER BY xact_start DESC LIMIT 1;
+            SELECT COUNT(CASE WHEN xact_finish IS NULL THEN 1 ELSE NULL END), MAX(xact_finish) INTO num_incomplete, last_finished FROM action.circ_chain(circ_chain_head.id);
+            CONTINUE WHEN circ_chain_tail.xact_finish IS NULL OR num_incomplete > 0;
+
+            IF NOT org_use_last THEN
+                last_finished := circ_chain_tail.xact_finish;
+            END IF;
+
+            keep_age := COALESCE( org_keep_age, '2000 years'::INTERVAL );
+
+            IF org_age_is_min THEN
+                keep_age := GREATEST( keep_age, org_keep_age );
+            END IF;
+
+            CONTINUE WHEN AGE(NOW(), last_finished) < keep_age;
+
+            -- We've passed the purging tests, purge the circ chain starting at the end
+            -- A trigger should auto-purge the rest of the chain.
+            DELETE FROM action.circulation WHERE id = circ_chain_tail.id;
+
+            count_purged := count_purged + 1;
+
+        END LOOP;
+    END LOOP;
+
+    return count_purged;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+-- delete circ history rows when a user is purged.
+CREATE OR REPLACE FUNCTION actor.usr_purge_data(
+	src_usr  IN INTEGER,
+	specified_dest_usr IN INTEGER
+) RETURNS VOID AS $$
+DECLARE
+	suffix TEXT;
+	renamable_row RECORD;
+	dest_usr INTEGER;
+BEGIN
+
+	IF specified_dest_usr IS NULL THEN
+		dest_usr := 1; -- Admin user on stock installs
+	ELSE
+		dest_usr := specified_dest_usr;
+	END IF;
+
+	-- acq.*
+	UPDATE acq.fund_allocation SET allocator = dest_usr WHERE allocator = src_usr;
+	UPDATE acq.lineitem SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE acq.lineitem SET editor = dest_usr WHERE editor = src_usr;
+	UPDATE acq.lineitem SET selector = dest_usr WHERE selector = src_usr;
+	UPDATE acq.lineitem_note SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE acq.lineitem_note SET editor = dest_usr WHERE editor = src_usr;
+	DELETE FROM acq.lineitem_usr_attr_definition WHERE usr = src_usr;
+
+	-- Update with a rename to avoid collisions
+	FOR renamable_row in
+		SELECT id, name
+		FROM   acq.picklist
+		WHERE  owner = src_usr
+	LOOP
+		suffix := ' (' || src_usr || ')';
+		LOOP
+			BEGIN
+				UPDATE  acq.picklist
+				SET     owner = dest_usr, name = name || suffix
+				WHERE   id = renamable_row.id;
+			EXCEPTION WHEN unique_violation THEN
+				suffix := suffix || ' ';
+				CONTINUE;
+			END;
+			EXIT;
+		END LOOP;
+	END LOOP;
+
+	UPDATE acq.picklist SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE acq.picklist SET editor = dest_usr WHERE editor = src_usr;
+	UPDATE acq.po_note SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE acq.po_note SET editor = dest_usr WHERE editor = src_usr;
+	UPDATE acq.purchase_order SET owner = dest_usr WHERE owner = src_usr;
+	UPDATE acq.purchase_order SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE acq.purchase_order SET editor = dest_usr WHERE editor = src_usr;
+	UPDATE acq.claim_event SET creator = dest_usr WHERE creator = src_usr;
+
+	-- action.*
+	DELETE FROM action.circulation WHERE usr = src_usr;
+	UPDATE action.circulation SET circ_staff = dest_usr WHERE circ_staff = src_usr;
+	UPDATE action.circulation SET checkin_staff = dest_usr WHERE checkin_staff = src_usr;
+	UPDATE action.hold_notification SET notify_staff = dest_usr WHERE notify_staff = src_usr;
+	UPDATE action.hold_request SET fulfillment_staff = dest_usr WHERE fulfillment_staff = src_usr;
+	UPDATE action.hold_request SET requestor = dest_usr WHERE requestor = src_usr;
+	DELETE FROM action.hold_request WHERE usr = src_usr;
+	UPDATE action.in_house_use SET staff = dest_usr WHERE staff = src_usr;
+	UPDATE action.non_cat_in_house_use SET staff = dest_usr WHERE staff = src_usr;
+	DELETE FROM action.non_cataloged_circulation WHERE patron = src_usr;
+	UPDATE action.non_cataloged_circulation SET staff = dest_usr WHERE staff = src_usr;
+	DELETE FROM action.survey_response WHERE usr = src_usr;
+	UPDATE action.fieldset SET owner = dest_usr WHERE owner = src_usr;
+    DELETE FROM action.usr_circ_history WHERE usr = src_usr;
+
+	-- actor.*
+	DELETE FROM actor.card WHERE usr = src_usr;
+	DELETE FROM actor.stat_cat_entry_usr_map WHERE target_usr = src_usr;
+
+	-- The following update is intended to avoid transient violations of a foreign
+	-- key constraint, whereby actor.usr_address references itself.  It may not be
+	-- necessary, but it does no harm.
+	UPDATE actor.usr_address SET replaces = NULL
+		WHERE usr = src_usr AND replaces IS NOT NULL;
+	DELETE FROM actor.usr_address WHERE usr = src_usr;
+	DELETE FROM actor.usr_note WHERE usr = src_usr;
+	UPDATE actor.usr_note SET creator = dest_usr WHERE creator = src_usr;
+	DELETE FROM actor.usr_org_unit_opt_in WHERE usr = src_usr;
+	UPDATE actor.usr_org_unit_opt_in SET staff = dest_usr WHERE staff = src_usr;
+	DELETE FROM actor.usr_setting WHERE usr = src_usr;
+	DELETE FROM actor.usr_standing_penalty WHERE usr = src_usr;
+	UPDATE actor.usr_standing_penalty SET staff = dest_usr WHERE staff = src_usr;
+
+	-- asset.*
+	UPDATE asset.call_number SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE asset.call_number SET editor = dest_usr WHERE editor = src_usr;
+	UPDATE asset.call_number_note SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE asset.copy SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE asset.copy SET editor = dest_usr WHERE editor = src_usr;
+	UPDATE asset.copy_note SET creator = dest_usr WHERE creator = src_usr;
+
+	-- auditor.*
+	DELETE FROM auditor.actor_usr_address_history WHERE id = src_usr;
+	DELETE FROM auditor.actor_usr_history WHERE id = src_usr;
+	UPDATE auditor.asset_call_number_history SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE auditor.asset_call_number_history SET editor  = dest_usr WHERE editor  = src_usr;
+	UPDATE auditor.asset_copy_history SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE auditor.asset_copy_history SET editor  = dest_usr WHERE editor  = src_usr;
+	UPDATE auditor.biblio_record_entry_history SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE auditor.biblio_record_entry_history SET editor  = dest_usr WHERE editor  = src_usr;
+
+	-- biblio.*
+	UPDATE biblio.record_entry SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE biblio.record_entry SET editor = dest_usr WHERE editor = src_usr;
+	UPDATE biblio.record_note SET creator = dest_usr WHERE creator = src_usr;
+	UPDATE biblio.record_note SET editor = dest_usr WHERE editor = src_usr;
+
+	-- container.*
+	-- Update buckets with a rename to avoid collisions
+	FOR renamable_row in
+		SELECT id, name
+		FROM   container.biblio_record_entry_bucket
+		WHERE  owner = src_usr
+	LOOP
+		suffix := ' (' || src_usr || ')';
+		LOOP
+			BEGIN
+				UPDATE  container.biblio_record_entry_bucket
+				SET     owner = dest_usr, name = name || suffix
+				WHERE   id = renamable_row.id;
+			EXCEPTION WHEN unique_violation THEN
+				suffix := suffix || ' ';
+				CONTINUE;
+			END;
+			EXIT;
+		END LOOP;
+	END LOOP;
+
+	FOR renamable_row in
+		SELECT id, name
+		FROM   container.call_number_bucket
+		WHERE  owner = src_usr
+	LOOP
+		suffix := ' (' || src_usr || ')';
+		LOOP
+			BEGIN
+				UPDATE  container.call_number_bucket
+				SET     owner = dest_usr, name = name || suffix
+				WHERE   id = renamable_row.id;
+			EXCEPTION WHEN unique_violation THEN
+				suffix := suffix || ' ';
+				CONTINUE;
+			END;
+			EXIT;
+		END LOOP;
+	END LOOP;
+
+	FOR renamable_row in
+		SELECT id, name
+		FROM   container.copy_bucket
+		WHERE  owner = src_usr
+	LOOP
+		suffix := ' (' || src_usr || ')';
+		LOOP
+			BEGIN
+				UPDATE  container.copy_bucket
+				SET     owner = dest_usr, name = name || suffix
+				WHERE   id = renamable_row.id;
+			EXCEPTION WHEN unique_violation THEN
+				suffix := suffix || ' ';
+				CONTINUE;
+			END;
+			EXIT;
+		END LOOP;
+	END LOOP;
+
+	FOR renamable_row in
+		SELECT id, name
+		FROM   container.user_bucket
+		WHERE  owner = src_usr
+	LOOP
+		suffix := ' (' || src_usr || ')';
+		LOOP
+			BEGIN
+				UPDATE  container.user_bucket
+				SET     owner = dest_usr, name = name || suffix
+				WHERE   id = renamable_row.id;
+			EXCEPTION WHEN unique_violation THEN
+				suffix := suffix || ' ';
+				CONTINUE;
+			END;
+			EXIT;
+		END LOOP;
+	END LOOP;
+
+	DELETE FROM container.user_bucket_item WHERE target_user = src_usr;
+
+	-- money.*
+	DELETE FROM money.billable_xact WHERE usr = src_usr;
+	DELETE FROM money.collections_tracker WHERE usr = src_usr;
+	UPDATE money.collections_tracker SET collector = dest_usr WHERE collector = src_usr;
+
+	-- permission.*
+	DELETE FROM permission.usr_grp_map WHERE usr = src_usr;
+	DELETE FROM permission.usr_object_perm_map WHERE usr = src_usr;
+	DELETE FROM permission.usr_perm_map WHERE usr = src_usr;
+	DELETE FROM permission.usr_work_ou_map WHERE usr = src_usr;
+
+	-- reporter.*
+	-- Update with a rename to avoid collisions
+	BEGIN
+		FOR renamable_row in
+			SELECT id, name
+			FROM   reporter.output_folder
+			WHERE  owner = src_usr
+		LOOP
+			suffix := ' (' || src_usr || ')';
+			LOOP
+				BEGIN
+					UPDATE  reporter.output_folder
+					SET     owner = dest_usr, name = name || suffix
+					WHERE   id = renamable_row.id;
+				EXCEPTION WHEN unique_violation THEN
+					suffix := suffix || ' ';
+					CONTINUE;
+				END;
+				EXIT;
+			END LOOP;
+		END LOOP;
+	EXCEPTION WHEN undefined_table THEN
+		-- do nothing
+	END;
+
+	BEGIN
+		UPDATE reporter.report SET owner = dest_usr WHERE owner = src_usr;
+	EXCEPTION WHEN undefined_table THEN
+		-- do nothing
+	END;
+
+	-- Update with a rename to avoid collisions
+	BEGIN
+		FOR renamable_row in
+			SELECT id, name
+			FROM   reporter.report_folder
+			WHERE  owner = src_usr
+		LOOP
+			suffix := ' (' || src_usr || ')';
+			LOOP
+				BEGIN
+					UPDATE  reporter.report_folder
+					SET     owner = dest_usr, name = name || suffix
+					WHERE   id = renamable_row.id;
+				EXCEPTION WHEN unique_violation THEN
+					suffix := suffix || ' ';
+					CONTINUE;
+				END;
+				EXIT;
+			END LOOP;
+		END LOOP;
+	EXCEPTION WHEN undefined_table THEN
+		-- do nothing
+	END;
+
+	BEGIN
+		UPDATE reporter.schedule SET runner = dest_usr WHERE runner = src_usr;
+	EXCEPTION WHEN undefined_table THEN
+		-- do nothing
+	END;
+
+	BEGIN
+		UPDATE reporter.template SET owner = dest_usr WHERE owner = src_usr;
+	EXCEPTION WHEN undefined_table THEN
+		-- do nothing
+	END;
+
+	-- Update with a rename to avoid collisions
+	BEGIN
+		FOR renamable_row in
+			SELECT id, name
+			FROM   reporter.template_folder
+			WHERE  owner = src_usr
+		LOOP
+			suffix := ' (' || src_usr || ')';
+			LOOP
+				BEGIN
+					UPDATE  reporter.template_folder
+					SET     owner = dest_usr, name = name || suffix
+					WHERE   id = renamable_row.id;
+				EXCEPTION WHEN unique_violation THEN
+					suffix := suffix || ' ';
+					CONTINUE;
+				END;
+				EXIT;
+			END LOOP;
+		END LOOP;
+	EXCEPTION WHEN undefined_table THEN
+	-- do nothing
+	END;
+
+	-- vandelay.*
+	-- Update with a rename to avoid collisions
+	FOR renamable_row in
+		SELECT id, name
+		FROM   vandelay.queue
+		WHERE  owner = src_usr
+	LOOP
+		suffix := ' (' || src_usr || ')';
+		LOOP
+			BEGIN
+				UPDATE  vandelay.queue
+				SET     owner = dest_usr, name = name || suffix
+				WHERE   id = renamable_row.id;
+			EXCEPTION WHEN unique_violation THEN
+				suffix := suffix || ' ';
+				CONTINUE;
+			END;
+			EXIT;
+		END LOOP;
+	END LOOP;
+
+    -- NULL-ify addresses last so other cleanup (e.g. circ anonymization)
+    -- can access the information before deletion.
+	UPDATE actor.usr SET
+		active = FALSE,
+		card = NULL,
+		mailing_address = NULL,
+		billing_address = NULL
+	WHERE id = src_usr;
+
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT evergreen.upgrade_deps_block_check('0961', :eg_version);
+
+CREATE EXTENSION IF NOT EXISTS pgcrypto;
+
+CREATE TABLE actor.passwd_type (
+    code        TEXT PRIMARY KEY,
+    name        TEXT UNIQUE NOT NULL,
+    login       BOOLEAN NOT NULL DEFAULT FALSE,
+    regex       TEXT,   -- pending
+    crypt_algo  TEXT,   -- e.g. 'bf'
+
+    -- gen_salt() iter count used with each new salt.
+    -- A non-NULL value for iter_count is our indication the 
+    -- password is salted and encrypted via crypt()
+    iter_count  INTEGER CHECK (iter_count IS NULL OR iter_count > 0)
+);
+
+CREATE TABLE actor.passwd (
+    id          SERIAL PRIMARY KEY,
+    usr         INTEGER NOT NULL REFERENCES actor.usr(id)
+                ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    salt        TEXT, -- will be NULL for non-crypt'ed passwords
+    passwd      TEXT NOT NULL,
+    passwd_type TEXT NOT NULL REFERENCES actor.passwd_type(code)
+                DEFERRABLE INITIALLY DEFERRED,
+    create_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+    edit_date   TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+    CONSTRAINT  passwd_type_once_per_user UNIQUE (usr, passwd_type)
+);
+
+CREATE OR REPLACE FUNCTION actor.create_salt(pw_type TEXT)
+    RETURNS TEXT AS $$
+DECLARE
+    type_row actor.passwd_type%ROWTYPE;
+BEGIN
+    /* Returns a new salt based on the passwd_type encryption settings.
+     * Returns NULL If the password type is not crypt()'ed.
+     */
+
+    SELECT INTO type_row * FROM actor.passwd_type WHERE code = pw_type;
+
+    IF NOT FOUND THEN
+        RETURN EXCEPTION 'No such password type: %', pw_type;
+    END IF;
+
+    IF type_row.iter_count IS NULL THEN
+        -- This password type is unsalted.  That's OK.
+        RETURN NULL;
+    END IF;
+
+    RETURN gen_salt(type_row.crypt_algo, type_row.iter_count);
+END;
+$$ LANGUAGE PLPGSQL;
+
+
+/* 
+    TODO: when a user changes their password in the application, the
+    app layer has access to the bare password.  At that point, we have
+    the opportunity to store the new password without the MD5(MD5())
+    intermediate hashing.  Do we care?  We would need a way to indicate
+    which passwords have the legacy intermediate hashing and which don't
+    so the app layer would know whether it should perform the intermediate
+    hashing.  In either event, with the exception of migrate_passwd(), the
+    DB functions know or care nothing about intermediate hashing.  Every
+    password is just a value that may or may not be internally crypt'ed. 
+*/
+
+CREATE OR REPLACE FUNCTION actor.set_passwd(
+    pw_usr INTEGER, pw_type TEXT, new_pass TEXT, new_salt TEXT DEFAULT NULL)
+    RETURNS BOOLEAN AS $$
+DECLARE
+    pw_salt TEXT;
+    pw_text TEXT;
+BEGIN
+    /* Sets the password value, creating a new actor.passwd row if needed.
+     * If the password type supports it, the new_pass value is crypt()'ed.
+     * For crypt'ed passwords, the salt comes from one of 3 places in order:
+     * new_salt (if present), existing salt (if present), newly created 
+     * salt.
+     */
+
+    IF new_salt IS NOT NULL THEN
+        pw_salt := new_salt;
+    ELSE 
+        pw_salt := actor.get_salt(pw_usr, pw_type);
+
+        IF pw_salt IS NULL THEN
+            /* We have no salt for this user + type.  Assume they want a 
+             * new salt.  If this type is unsalted, create_salt() will 
+             * return NULL. */
+            pw_salt := actor.create_salt(pw_type);
+        END IF;
+    END IF;
+
+    IF pw_salt IS NULL THEN 
+        pw_text := new_pass; -- unsalted, use as-is.
+    ELSE
+        pw_text := CRYPT(new_pass, pw_salt);
+    END IF;
+
+    UPDATE actor.passwd 
+        SET passwd = pw_text, salt = pw_salt, edit_date = NOW()
+        WHERE usr = pw_usr AND passwd_type = pw_type;
+
+    IF NOT FOUND THEN
+        -- no password row exists for this user + type.  Create one.
+        INSERT INTO actor.passwd (usr, passwd_type, salt, passwd) 
+            VALUES (pw_usr, pw_type, pw_salt, pw_text);
+    END IF;
+
+    RETURN TRUE;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION actor.get_salt(pw_usr INTEGER, pw_type TEXT)
+    RETURNS TEXT AS $$
+DECLARE
+    pw_salt TEXT;
+    type_row actor.passwd_type%ROWTYPE;
+BEGIN
+    /* Returns the salt for the requested user + type.  If the password 
+     * type of "main" is requested and no password exists in actor.passwd, 
+     * the user's existing password is migrated and the new salt is returned.
+     * Returns NULL if the password type is not crypt'ed (iter_count is NULL).
+     */
+
+    SELECT INTO pw_salt salt FROM actor.passwd 
+        WHERE usr = pw_usr AND passwd_type = pw_type;
+
+    IF FOUND THEN
+        RETURN pw_salt;
+    END IF;
+
+    IF pw_type = 'main' THEN
+        -- Main password has not yet been migrated. 
+        -- Do it now and return the newly created salt.
+        RETURN actor.migrate_passwd(pw_usr);
+    END IF;
+
+    -- We have no salt to return.  actor.create_salt() needed.
+    RETURN NULL;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION 
+    actor.migrate_passwd(pw_usr INTEGER) RETURNS TEXT AS $$
+DECLARE
+    pw_salt TEXT;
+    usr_row actor.usr%ROWTYPE;
+BEGIN
+    /* Migrates legacy actor.usr.passwd value to actor.passwd with 
+     * a password type 'main' and returns the new salt.  For backwards
+     * compatibility with existing CHAP-style API's, we perform a 
+     * layer of intermediate MD5(MD5()) hashing.  This is intermediate
+     * hashing is not required of other passwords.
+     */
+
+    -- Avoid calling get_salt() here, because it may result in a 
+    -- migrate_passwd() call, creating a loop.
+    SELECT INTO pw_salt salt FROM actor.passwd 
+        WHERE usr = pw_usr AND passwd_type = 'main';
+
+    -- Only migrate passwords that have not already been migrated.
+    IF FOUND THEN
+        RETURN pw_salt;
+    END IF;
+
+    SELECT INTO usr_row * FROM actor.usr WHERE id = pw_usr;
+
+    pw_salt := actor.create_salt('main');
+
+    PERFORM actor.set_passwd(
+        pw_usr, 'main', MD5(pw_salt || usr_row.passwd), pw_salt);
+
+    -- clear the existing password
+    UPDATE actor.usr SET passwd = '' WHERE id = usr_row.id;
+
+    RETURN pw_salt;
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION 
+    actor.verify_passwd(pw_usr INTEGER, pw_type TEXT, test_passwd TEXT) 
+    RETURNS BOOLEAN AS $$
+DECLARE
+    pw_salt TEXT;
+BEGIN
+    /* Returns TRUE if the password provided matches the in-db password.  
+     * If the password type is salted, we compare the output of CRYPT().
+     * NOTE: test_passwd is MD5(salt || MD5(password)) for legacy 
+     * 'main' passwords.
+     */
+
+    SELECT INTO pw_salt salt FROM actor.passwd 
+        WHERE usr = pw_usr AND passwd_type = pw_type;
+
+    IF NOT FOUND THEN
+        -- no such password
+        RETURN FALSE;
+    END IF;
+
+    IF pw_salt IS NULL THEN
+        -- Password is unsalted, compare the un-CRYPT'ed values.
+        RETURN EXISTS (
+            SELECT TRUE FROM actor.passwd WHERE 
+                usr = pw_usr AND
+                passwd_type = pw_type AND
+                passwd = test_passwd
+        );
+    END IF;
+
+    RETURN EXISTS (
+        SELECT TRUE FROM actor.passwd WHERE 
+            usr = pw_usr AND
+            passwd_type = pw_type AND
+            passwd = CRYPT(test_passwd, pw_salt)
+    );
+END;
+$$ STRICT LANGUAGE PLPGSQL;
+
+--- DATA ----------------------
+
+INSERT INTO actor.passwd_type 
+    (code, name, login, crypt_algo, iter_count) 
+    VALUES ('main', 'Main Login Password', TRUE, 'bf', 10);
+
+SELECT evergreen.upgrade_deps_block_check('0962', :eg_version);
+
+ALTER TABLE vandelay.import_item_attr_definition
+    ADD COLUMN parts_data TEXT;
+
+ALTER TABLE vandelay.import_item
+    ADD COLUMN parts_data TEXT;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_items ( import_id BIGINT, attr_def_id BIGINT ) RETURNS SETOF vandelay.import_item AS $$
+DECLARE
+
+    owning_lib      TEXT;
+    circ_lib        TEXT;
+    call_number     TEXT;
+    copy_number     TEXT;
+    status          TEXT;
+    location        TEXT;
+    circulate       TEXT;
+    deposit         TEXT;
+    deposit_amount  TEXT;
+    ref             TEXT;
+    holdable        TEXT;
+    price           TEXT;
+    barcode         TEXT;
+    circ_modifier   TEXT;
+    circ_as_type    TEXT;
+    alert_message   TEXT;
+    opac_visible    TEXT;
+    pub_note        TEXT;
+    priv_note       TEXT;
+    internal_id     TEXT;
+    stat_cat_data   TEXT;
+    parts_data      TEXT;
+
+    attr_def        RECORD;
+    tmp_attr_set    RECORD;
+    attr_set        vandelay.import_item%ROWTYPE;
+
+    xpaths          TEXT[];
+    tmp_str         TEXT;
+
+BEGIN
+
+    SELECT * INTO attr_def FROM vandelay.import_item_attr_definition WHERE id = attr_def_id;
+
+    IF FOUND THEN
+
+        attr_set.definition := attr_def.id;
+
+        -- Build the combined XPath
+
+        owning_lib :=
+            CASE
+                WHEN attr_def.owning_lib IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.owning_lib ) = 1 THEN '*[@code="' || attr_def.owning_lib || '"]'
+                ELSE '*' || attr_def.owning_lib
+            END;
+
+        circ_lib :=
+            CASE
+                WHEN attr_def.circ_lib IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.circ_lib ) = 1 THEN '*[@code="' || attr_def.circ_lib || '"]'
+                ELSE '*' || attr_def.circ_lib
+            END;
+
+        call_number :=
+            CASE
+                WHEN attr_def.call_number IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.call_number ) = 1 THEN '*[@code="' || attr_def.call_number || '"]'
+                ELSE '*' || attr_def.call_number
+            END;
+
+        copy_number :=
+            CASE
+                WHEN attr_def.copy_number IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.copy_number ) = 1 THEN '*[@code="' || attr_def.copy_number || '"]'
+                ELSE '*' || attr_def.copy_number
+            END;
+
+        status :=
+            CASE
+                WHEN attr_def.status IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.status ) = 1 THEN '*[@code="' || attr_def.status || '"]'
+                ELSE '*' || attr_def.status
+            END;
+
+        location :=
+            CASE
+                WHEN attr_def.location IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.location ) = 1 THEN '*[@code="' || attr_def.location || '"]'
+                ELSE '*' || attr_def.location
+            END;
+
+        circulate :=
+            CASE
+                WHEN attr_def.circulate IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.circulate ) = 1 THEN '*[@code="' || attr_def.circulate || '"]'
+                ELSE '*' || attr_def.circulate
+            END;
+
+        deposit :=
+            CASE
+                WHEN attr_def.deposit IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.deposit ) = 1 THEN '*[@code="' || attr_def.deposit || '"]'
+                ELSE '*' || attr_def.deposit
+            END;
+
+        deposit_amount :=
+            CASE
+                WHEN attr_def.deposit_amount IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.deposit_amount ) = 1 THEN '*[@code="' || attr_def.deposit_amount || '"]'
+                ELSE '*' || attr_def.deposit_amount
+            END;
+
+        ref :=
+            CASE
+                WHEN attr_def.ref IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.ref ) = 1 THEN '*[@code="' || attr_def.ref || '"]'
+                ELSE '*' || attr_def.ref
+            END;
+
+        holdable :=
+            CASE
+                WHEN attr_def.holdable IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.holdable ) = 1 THEN '*[@code="' || attr_def.holdable || '"]'
+                ELSE '*' || attr_def.holdable
+            END;
+
+        price :=
+            CASE
+                WHEN attr_def.price IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.price ) = 1 THEN '*[@code="' || attr_def.price || '"]'
+                ELSE '*' || attr_def.price
+            END;
+
+        barcode :=
+            CASE
+                WHEN attr_def.barcode IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.barcode ) = 1 THEN '*[@code="' || attr_def.barcode || '"]'
+                ELSE '*' || attr_def.barcode
+            END;
+
+        circ_modifier :=
+            CASE
+                WHEN attr_def.circ_modifier IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.circ_modifier ) = 1 THEN '*[@code="' || attr_def.circ_modifier || '"]'
+                ELSE '*' || attr_def.circ_modifier
+            END;
+
+        circ_as_type :=
+            CASE
+                WHEN attr_def.circ_as_type IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.circ_as_type ) = 1 THEN '*[@code="' || attr_def.circ_as_type || '"]'
+                ELSE '*' || attr_def.circ_as_type
+            END;
+
+        alert_message :=
+            CASE
+                WHEN attr_def.alert_message IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.alert_message ) = 1 THEN '*[@code="' || attr_def.alert_message || '"]'
+                ELSE '*' || attr_def.alert_message
+            END;
+
+        opac_visible :=
+            CASE
+                WHEN attr_def.opac_visible IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.opac_visible ) = 1 THEN '*[@code="' || attr_def.opac_visible || '"]'
+                ELSE '*' || attr_def.opac_visible
+            END;
+
+        pub_note :=
+            CASE
+                WHEN attr_def.pub_note IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.pub_note ) = 1 THEN '*[@code="' || attr_def.pub_note || '"]'
+                ELSE '*' || attr_def.pub_note
+            END;
+        priv_note :=
+            CASE
+                WHEN attr_def.priv_note IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.priv_note ) = 1 THEN '*[@code="' || attr_def.priv_note || '"]'
+                ELSE '*' || attr_def.priv_note
+            END;
+
+        internal_id :=
+            CASE
+                WHEN attr_def.internal_id IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.internal_id ) = 1 THEN '*[@code="' || attr_def.internal_id || '"]'
+                ELSE '*' || attr_def.internal_id
+            END;
+
+        stat_cat_data :=
+            CASE
+                WHEN attr_def.stat_cat_data IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.stat_cat_data ) = 1 THEN '*[@code="' || attr_def.stat_cat_data || '"]'
+                ELSE '*' || attr_def.stat_cat_data
+            END;
+
+        parts_data :=
+            CASE
+                WHEN attr_def.parts_data IS NULL THEN 'null()'
+                WHEN LENGTH( attr_def.parts_data ) = 1 THEN '*[@code="' || attr
+                ELSE '*' || attr_def.parts_data
+            END;
+
+
+
+        xpaths := ARRAY[owning_lib, circ_lib, call_number, copy_number, status, location, circulate,
+                        deposit, deposit_amount, ref, holdable, price, barcode, circ_modifier, circ_as_type,
+                        alert_message, pub_note, priv_note, internal_id, stat_cat_data, parts_data, opac_visible];
+
+        FOR tmp_attr_set IN
+                SELECT  *
+                  FROM  oils_xpath_tag_to_table( (SELECT marc FROM vandelay.queued_bib_record WHERE id = import_id), attr_def.tag, xpaths)
+                            AS t( ol TEXT, clib TEXT, cn TEXT, cnum TEXT, cs TEXT, cl TEXT, circ TEXT,
+                                  dep TEXT, dep_amount TEXT, r TEXT, hold TEXT, pr TEXT, bc TEXT, circ_mod TEXT,
+                                  circ_as TEXT, amessage TEXT, note TEXT, pnote TEXT, internal_id TEXT,
+                                  stat_cat_data TEXT, parts_data TEXT, opac_vis TEXT )
+        LOOP
+
+            attr_set.import_error := NULL;
+            attr_set.error_detail := NULL;
+            attr_set.deposit_amount := NULL;
+            attr_set.copy_number := NULL;
+            attr_set.price := NULL;
+            attr_set.circ_modifier := NULL;
+            attr_set.location := NULL;
+            attr_set.barcode := NULL;
+            attr_set.call_number := NULL;
+
+            IF tmp_attr_set.pr != '' THEN
+                tmp_str = REGEXP_REPLACE(tmp_attr_set.pr, E'[^0-9\\.]', '', 'g');
+                IF tmp_str = '' THEN
+                    attr_set.import_error := 'import.item.invalid.price';
+                    attr_set.error_detail := tmp_attr_set.pr; -- original value
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+                attr_set.price := tmp_str::NUMERIC(8,2);
+            END IF;
+
+            IF tmp_attr_set.dep_amount != '' THEN
+                tmp_str = REGEXP_REPLACE(tmp_attr_set.dep_amount, E'[^0-9\\.]', '', 'g');
+                IF tmp_str = '' THEN
+                    attr_set.import_error := 'import.item.invalid.deposit_amount';
+                    attr_set.error_detail := tmp_attr_set.dep_amount;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+                attr_set.deposit_amount := tmp_str::NUMERIC(8,2);
+            END IF;
+
+            IF tmp_attr_set.cnum != '' THEN
+                tmp_str = REGEXP_REPLACE(tmp_attr_set.cnum, E'[^0-9]', '', 'g');
+                IF tmp_str = '' THEN
+                    attr_set.import_error := 'import.item.invalid.copy_number';
+                    attr_set.error_detail := tmp_attr_set.cnum;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+                attr_set.copy_number := tmp_str::INT;
+            END IF;
+
+            IF tmp_attr_set.ol != '' THEN
+                SELECT id INTO attr_set.owning_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.ol); -- INT
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.owning_lib';
+                    attr_set.error_detail := tmp_attr_set.ol;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+            END IF;
+
+            IF tmp_attr_set.clib != '' THEN
+                SELECT id INTO attr_set.circ_lib FROM actor.org_unit WHERE shortname = UPPER(tmp_attr_set.clib); -- INT
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.circ_lib';
+                    attr_set.error_detail := tmp_attr_set.clib;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+            END IF;
+
+            IF tmp_attr_set.cs != '' THEN
+                SELECT id INTO attr_set.status FROM config.copy_status WHERE LOWER(name) = LOWER(tmp_attr_set.cs); -- INT
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.status';
+                    attr_set.error_detail := tmp_attr_set.cs;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+            END IF;
+
+            IF COALESCE(tmp_attr_set.circ_mod, '') = '' THEN
+
+                -- no circ mod defined, see if we should apply a default
+                SELECT INTO attr_set.circ_modifier TRIM(BOTH '"' FROM value)
+                    FROM actor.org_unit_ancestor_setting(
+                        'vandelay.item.circ_modifier.default',
+                        attr_set.owning_lib
+                    );
+
+                -- make sure the value from the org setting is still valid
+                PERFORM 1 FROM config.circ_modifier WHERE code = attr_set.circ_modifier;
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.circ_modifier';
+                    attr_set.error_detail := tmp_attr_set.circ_mod;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+
+            ELSE
+
+                SELECT code INTO attr_set.circ_modifier FROM config.circ_modifier WHERE code = tmp_attr_set.circ_mod;
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.circ_modifier';
+                    attr_set.error_detail := tmp_attr_set.circ_mod;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+            END IF;
+
+            IF tmp_attr_set.circ_as != '' THEN
+                SELECT code INTO attr_set.circ_as_type FROM config.coded_value_map WHERE ctype = 'item_type' AND code = tmp_attr_set.circ_as;
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.circ_as_type';
+                    attr_set.error_detail := tmp_attr_set.circ_as;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+            END IF;
+
+            IF COALESCE(tmp_attr_set.cl, '') = '' THEN
+                -- no location specified, see if we should apply a default
+
+                SELECT INTO attr_set.location TRIM(BOTH '"' FROM value)
+                    FROM actor.org_unit_ancestor_setting(
+                        'vandelay.item.copy_location.default',
+                        attr_set.owning_lib
+                    );
+
+                -- make sure the value from the org setting is still valid
+                PERFORM 1 FROM asset.copy_location WHERE id = attr_set.location;
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.location';
+                    attr_set.error_detail := tmp_attr_set.cs;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+            ELSE
+
+                -- search up the org unit tree for a matching copy location
+                WITH RECURSIVE anscestor_depth AS (
+                    SELECT  ou.id,
+                        out.depth AS depth,
+                        ou.parent_ou
+                    FROM  actor.org_unit ou
+                        JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+                    WHERE ou.id = COALESCE(attr_set.owning_lib, attr_set.circ_lib)
+                        UNION ALL
+                    SELECT  ou.id,
+                        out.depth,
+                        ou.parent_ou
+                    FROM  actor.org_unit ou
+                        JOIN actor.org_unit_type out ON (out.id = ou.ou_type)
+                        JOIN anscestor_depth ot ON (ot.parent_ou = ou.id)
+                ) SELECT  cpl.id INTO attr_set.location
+                    FROM  anscestor_depth a
+                        JOIN asset.copy_location cpl ON (cpl.owning_lib = a.id)
+                    WHERE LOWER(cpl.name) = LOWER(tmp_attr_set.cl)
+                    ORDER BY a.depth DESC
+                    LIMIT 1;
+
+                IF NOT FOUND THEN
+                    attr_set.import_error := 'import.item.invalid.location';
+                    attr_set.error_detail := tmp_attr_set.cs;
+                    RETURN NEXT attr_set; CONTINUE;
+                END IF;
+            END IF;
+
+            attr_set.circulate      :=
+                LOWER( SUBSTRING( tmp_attr_set.circ, 1, 1)) IN ('t','y','1')
+                OR LOWER(tmp_attr_set.circ) = 'circulating'; -- BOOL
+
+            attr_set.deposit        :=
+                LOWER( SUBSTRING( tmp_attr_set.dep, 1, 1 ) ) IN ('t','y','1')
+                OR LOWER(tmp_attr_set.dep) = 'deposit'; -- BOOL
+
+            attr_set.holdable       :=
+                LOWER( SUBSTRING( tmp_attr_set.hold, 1, 1 ) ) IN ('t','y','1')
+                OR LOWER(tmp_attr_set.hold) = 'holdable'; -- BOOL
+
+            attr_set.opac_visible   :=
+                LOWER( SUBSTRING( tmp_attr_set.opac_vis, 1, 1 ) ) IN ('t','y','1')
+                OR LOWER(tmp_attr_set.opac_vis) = 'visible'; -- BOOL
+
+            attr_set.ref            :=
+                LOWER( SUBSTRING( tmp_attr_set.r, 1, 1 ) ) IN ('t','y','1')
+                OR LOWER(tmp_attr_set.r) = 'reference'; -- BOOL
+
+            attr_set.call_number    := tmp_attr_set.cn; -- TEXT
+            attr_set.barcode        := tmp_attr_set.bc; -- TEXT,
+            attr_set.alert_message  := tmp_attr_set.amessage; -- TEXT,
+            attr_set.pub_note       := tmp_attr_set.note; -- TEXT,
+            attr_set.priv_note      := tmp_attr_set.pnote; -- TEXT,
+            attr_set.alert_message  := tmp_attr_set.amessage; -- TEXT,
+            attr_set.internal_id    := tmp_attr_set.internal_id::BIGINT;
+            attr_set.stat_cat_data  := tmp_attr_set.stat_cat_data; -- TEXT,
+            attr_set.parts_data     := tmp_attr_set.parts_data; -- TEXT,
+
+            RETURN NEXT attr_set;
+
+        END LOOP;
+
+    END IF;
+
+    RETURN;
+
+END;
+$$ LANGUAGE PLPGSQL;
+
+CREATE OR REPLACE FUNCTION vandelay.ingest_bib_items ( ) RETURNS TRIGGER AS $func$
+DECLARE
+    attr_def    BIGINT;
+    item_data   vandelay.import_item%ROWTYPE;
+BEGIN
+
+    IF TG_OP IN ('INSERT','UPDATE') AND NEW.imported_as IS NOT NULL THEN
+        RETURN NEW;
+    END IF;
+
+    SELECT item_attr_def INTO attr_def FROM vandelay.bib_queue WHERE id = NEW.queue;
+
+    FOR item_data IN SELECT * FROM vandelay.ingest_items( NEW.id::BIGINT, attr_def ) LOOP
+        INSERT INTO vandelay.import_item (
+            record,
+            definition,
+            owning_lib,
+            circ_lib,
+            call_number,
+            copy_number,
+            status,
+            location,
+            circulate,
+            deposit,
+            deposit_amount,
+            ref,
+            holdable,
+            price,
+            barcode,
+            circ_modifier,
+            circ_as_type,
+            alert_message,
+            pub_note,
+            priv_note,
+            internal_id,
+            opac_visible,
+            stat_cat_data,
+            parts_data,
+            import_error,
+            error_detail
+        ) VALUES (
+            NEW.id,
+            item_data.definition,
+            item_data.owning_lib,
+            item_data.circ_lib,
+            item_data.call_number,
+            item_data.copy_number,
+            item_data.status,
+            item_data.location,
+            item_data.circulate,
+            item_data.deposit,
+            item_data.deposit_amount,
+            item_data.ref,
+            item_data.holdable,
+            item_data.price,
+            item_data.barcode,
+            item_data.circ_modifier,
+            item_data.circ_as_type,
+            item_data.alert_message,
+            item_data.pub_note,
+            item_data.priv_note,
+            item_data.internal_id,
+            item_data.opac_visible,
+            item_data.stat_cat_data,
+            item_data.parts_data,
+            item_data.import_error,
+            item_data.error_detail
+        );
+    END LOOP;
+
+    RETURN NULL;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+SELECT evergreen.upgrade_deps_block_check('0963', :eg_version);
+
+ALTER TABLE config.z3950_index_field_map DROP CONSTRAINT "valid_z3950_attr_type";
+
+DROP FUNCTION evergreen.z3950_attr_name_is_valid(text);
+
+CREATE OR REPLACE FUNCTION evergreen.z3950_attr_name_is_valid() RETURNS TRIGGER AS $func$
+BEGIN
+
+  PERFORM * FROM config.z3950_attr WHERE name = NEW.z3950_attr_type;
+
+  IF FOUND THEN
+    RETURN NULL;
+  END IF;
+
+  RAISE EXCEPTION '% is not a valid Z39.50 attribute type', NEW.z3950_attr_type;
+
+END;
+$func$ LANGUAGE PLPGSQL STABLE;
+
+COMMENT ON FUNCTION evergreen.z3950_attr_name_is_valid() IS $$
+Used by a config.z3950_index_field_map constraint trigger
+to verify z3950_attr_type maps.
+$$;
+
+CREATE CONSTRAINT TRIGGER valid_z3950_attr_type AFTER INSERT OR UPDATE ON config.z3950_index_field_map
+  DEFERRABLE INITIALLY DEFERRED FOR EACH ROW WHEN (NEW.z3950_attr_type IS NOT NULL)
+  EXECUTE PROCEDURE evergreen.z3950_attr_name_is_valid();
+
+SELECT evergreen.upgrade_deps_block_check('0964', :eg_version);
+
+INSERT INTO config.coded_value_map
+    (id, ctype, code, opac_visible, value, search_label) VALUES
+(712, 'search_format', 'electronic', FALSE,
+    oils_i18n_gettext(712, 'Electronic', 'ccvm', 'value'),
+    oils_i18n_gettext(712, 'Electronic', 'ccvm', 'search_label'));
+
+INSERT INTO config.composite_attr_entry_definition
+    (coded_value, definition) VALUES
+(712, '[{"_attr":"item_form","_val":"s"},{"_attr":"item_form","_val":"o"}]');
+
+
+SELECT evergreen.upgrade_deps_block_check('0965', :eg_version);
+
+UPDATE action_trigger.event_definition SET template =
+$$
+[%- USE date -%]
+[%- SET user = target.0.usr -%]
+[%- SET lib = target.0.circ_lib -%]
+[%- SET lib_addr = target.0.circ_lib.billing_address -%]
+[%- SET hours = lib.hours_of_operation -%]
+<div>
+    <style> li { padding: 8px; margin 5px; }</style>
+    <div>[% date.format %]</div>
+    <div>[% lib.name %]</div>
+    <div>[% lib_addr.street1 %] [% lib_addr.street2 %]</div>
+    <div>[% lib_addr.city %], [% lib_addr.state %] [% lib_addr.post_code %]</div>
+    <div>[% lib.phone %]</div>
+    <br/>
+
+    [% user.family_name %], [% user.first_given_name %]
+    <ol>
+    [% FOR circ IN target %]
+        [%-
+            SET idx = loop.count - 1;
+            SET udata =  user_data.$idx
+        -%]
+        <li>
+            <div>[% helpers.get_copy_bib_basics(circ.target_copy.id).title %]</div>
+            <div>Barcode: [% circ.target_copy.barcode %]</div>
+            [% IF user_data.renewal_failure %]
+                <div style='color:red;'>Renewal Failed</div>
+            [% ELSE %]
+                <div>Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]</div>
+            [% END %]
+        </li>
+    [% END %]
+    </ol>
+    
+    <div>
+        Library Hours
+        [%- BLOCK format_time; date.format(time _ ' 1/1/1000', format='%I:%M %p'); END -%]
+        <div>
+            Monday 
+            [% PROCESS format_time time = hours.dow_0_open %] 
+            [% PROCESS format_time time = hours.dow_0_close %] 
+        </div>
+        <div>
+            Tuesday 
+            [% PROCESS format_time time = hours.dow_1_open %] 
+            [% PROCESS format_time time = hours.dow_1_close %] 
+        </div>
+        <div>
+            Wednesday 
+            [% PROCESS format_time time = hours.dow_2_open %] 
+            [% PROCESS format_time time = hours.dow_2_close %] 
+        </div>
+        <div>
+            Thursday
+            [% PROCESS format_time time = hours.dow_3_open %] 
+            [% PROCESS format_time time = hours.dow_3_close %] 
+        </div>
+        <div>
+            Friday
+            [% PROCESS format_time time = hours.dow_4_open %] 
+            [% PROCESS format_time time = hours.dow_4_close %] 
+        </div>
+        <div>
+            Saturday
+            [% PROCESS format_time time = hours.dow_5_open %] 
+            [% PROCESS format_time time = hours.dow_5_close %] 
+        </div>
+        <div>
+            Sunday 
+            [% PROCESS format_time time = hours.dow_6_open %] 
+            [% PROCESS format_time time = hours.dow_6_close %] 
+        </div>
+    </div>
+</div>
+$$
+WHERE id = 10 AND template =
+$$
+[%- USE date -%]
+[%- SET user = target.0.usr -%]
+[%- SET lib = target.0.circ_lib -%]
+[%- SET lib_addr = target.0.circ_lib.billing_address -%]
+[%- SET hours = lib.hours_of_operation -%]
+<div>
+    <style> li { padding: 8px; margin 5px; }</style>
+    <div>[% date.format %]</div>
+    <div>[% lib.name %]</div>
+    <div>[% lib_addr.street1 %] [% lib_addr.street2 %]</div>
+    <div>[% lib_addr.city %], [% lib_addr.state %] [% lb_addr.post_code %]</div>
+    <div>[% lib.phone %]</div>
+    <br/>
+
+    [% user.family_name %], [% user.first_given_name %]
+    <ol>
+    [% FOR circ IN target %]
+        [%-
+            SET idx = loop.count - 1;
+            SET udata =  user_data.$idx
+        -%]
+        <li>
+            <div>[% helpers.get_copy_bib_basics(circ.target_copy.id).title %]</div>
+            <div>Barcode: [% circ.target_copy.barcode %]</div>
+            [% IF user_data.renewal_failure %]
+                <div style='color:red;'>Renewal Failed</div>
+            [% ELSE %]
+                <div>Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]</div>
+            [% END %]
+        </li>
+    [% END %]
+    </ol>
+    
+    <div>
+        Library Hours
+        [%- BLOCK format_time; date.format(time _ ' 1/1/1000', format='%I:%M %p'); END -%]
+        <div>
+            Monday 
+            [% PROCESS format_time time = hours.dow_0_open %] 
+            [% PROCESS format_time time = hours.dow_0_close %] 
+        </div>
+        <div>
+            Tuesday 
+            [% PROCESS format_time time = hours.dow_1_open %] 
+            [% PROCESS format_time time = hours.dow_1_close %] 
+        </div>
+        <div>
+            Wednesday 
+            [% PROCESS format_time time = hours.dow_2_open %] 
+            [% PROCESS format_time time = hours.dow_2_close %] 
+        </div>
+        <div>
+            Thursday
+            [% PROCESS format_time time = hours.dow_3_open %] 
+            [% PROCESS format_time time = hours.dow_3_close %] 
+        </div>
+        <div>
+            Friday
+            [% PROCESS format_time time = hours.dow_4_open %] 
+            [% PROCESS format_time time = hours.dow_4_close %] 
+        </div>
+        <div>
+            Saturday
+            [% PROCESS format_time time = hours.dow_5_open %] 
+            [% PROCESS format_time time = hours.dow_5_close %] 
+        </div>
+        <div>
+            Sunday 
+            [% PROCESS format_time time = hours.dow_6_open %] 
+            [% PROCESS format_time time = hours.dow_6_close %] 
+        </div>
+    </div>
+</div>
+$$;
+
+SELECT evergreen.upgrade_deps_block_check('0966', :eg_version); -- miker/jpringle/gmcharlt
+
+-- Allow NULL post-normalization sorters
+CREATE OR REPLACE FUNCTION metabib.reingest_record_attributes (rid BIGINT, pattr_list TEXT[] DEFAULT NULL, prmarc TEXT DEFAULT NULL, rdeleted BOOL DEFAULT TRUE) RETURNS VOID AS $func$
+DECLARE
+    transformed_xml TEXT;
+    rmarc           TEXT := prmarc;
+    tmp_val         TEXT;
+    prev_xfrm       TEXT;
+    normalizer      RECORD;
+    xfrm            config.xml_transform%ROWTYPE;
+    attr_vector     INT[] := '{}'::INT[];
+    attr_vector_tmp INT[];
+    attr_list       TEXT[] := pattr_list;
+    attr_value      TEXT[];
+    norm_attr_value TEXT[];
+    tmp_xml         TEXT;
+    attr_def        config.record_attr_definition%ROWTYPE;
+    ccvm_row        config.coded_value_map%ROWTYPE;
+BEGIN
+
+    IF attr_list IS NULL OR rdeleted THEN -- need to do the full dance on INSERT or undelete
+        SELECT ARRAY_AGG(name) INTO attr_list FROM config.record_attr_definition;
+    END IF;
+
+    IF rmarc IS NULL THEN
+        SELECT marc INTO rmarc FROM biblio.record_entry WHERE id = rid;
+    END IF;
+
+    FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE NOT composite AND name = ANY( attr_list ) ORDER BY format LOOP
+
+        attr_value := '{}'::TEXT[];
+        norm_attr_value := '{}'::TEXT[];
+        attr_vector_tmp := '{}'::INT[];
+
+        SELECT * INTO ccvm_row FROM config.coded_value_map c WHERE c.ctype = attr_def.name LIMIT 1; 
+
+        -- tag+sf attrs only support SVF
+        IF attr_def.tag IS NOT NULL THEN -- tag (and optional subfield list) selection
+            SELECT  ARRAY[ARRAY_TO_STRING(ARRAY_AGG(value), COALESCE(attr_def.joiner,' '))] INTO attr_value
+              FROM  (SELECT * FROM metabib.full_rec ORDER BY tag, subfield) AS x
+              WHERE record = rid
+                    AND tag LIKE attr_def.tag
+                    AND CASE
+                        WHEN attr_def.sf_list IS NOT NULL 
+                            THEN POSITION(subfield IN attr_def.sf_list) > 0
+                        ELSE TRUE
+                    END
+              GROUP BY tag
+              ORDER BY tag
+              LIMIT 1;
+
+        ELSIF attr_def.fixed_field IS NOT NULL THEN -- a named fixed field, see config.marc21_ff_pos_map.fixed_field
+            attr_value := vandelay.marc21_extract_fixed_field_list(rmarc, attr_def.fixed_field);
+
+            IF NOT attr_def.multi THEN
+                attr_value := ARRAY[attr_value[1]];
+            END IF;
+
+        ELSIF attr_def.xpath IS NOT NULL THEN -- and xpath expression
+
+            SELECT INTO xfrm * FROM config.xml_transform WHERE name = attr_def.format;
+        
+            -- See if we can skip the XSLT ... it's expensive
+            IF prev_xfrm IS NULL OR prev_xfrm <> xfrm.name THEN
+                -- Can't skip the transform
+                IF xfrm.xslt <> '---' THEN
+                    transformed_xml := oils_xslt_process(rmarc,xfrm.xslt);
+                ELSE
+                    transformed_xml := rmarc;
+                END IF;
+    
+                prev_xfrm := xfrm.name;
+            END IF;
+
+            IF xfrm.name IS NULL THEN
+                -- just grab the marcxml (empty) transform
+                SELECT INTO xfrm * FROM config.xml_transform WHERE xslt = '---' LIMIT 1;
+                prev_xfrm := xfrm.name;
+            END IF;
+
+            FOR tmp_xml IN SELECT UNNEST(oils_xpath(attr_def.xpath, transformed_xml, ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]])) LOOP
+                tmp_val := oils_xpath_string(
+                                '//*',
+                                tmp_xml,
+                                COALESCE(attr_def.joiner,' '),
+                                ARRAY[ARRAY[xfrm.prefix, xfrm.namespace_uri]]
+                            );
+                IF tmp_val IS NOT NULL AND BTRIM(tmp_val) <> '' THEN
+                    attr_value := attr_value || tmp_val;
+                    EXIT WHEN NOT attr_def.multi;
+                END IF;
+            END LOOP;
+
+        ELSIF attr_def.phys_char_sf IS NOT NULL THEN -- a named Physical Characteristic, see config.marc21_physical_characteristic_*_map
+            SELECT  ARRAY_AGG(m.value) INTO attr_value
+              FROM  vandelay.marc21_physical_characteristics(rmarc) v
+                    LEFT JOIN config.marc21_physical_characteristic_value_map m ON (m.id = v.value)
+              WHERE v.subfield = attr_def.phys_char_sf AND (m.value IS NOT NULL AND BTRIM(m.value) <> '')
+                    AND ( ccvm_row.id IS NULL OR ( ccvm_row.id IS NOT NULL AND v.id IS NOT NULL) );
+
+            IF NOT attr_def.multi THEN
+                attr_value := ARRAY[attr_value[1]];
+            END IF;
+
+        END IF;
+
+                -- apply index normalizers to attr_value
+        FOR tmp_val IN SELECT value FROM UNNEST(attr_value) x(value) LOOP
+            FOR normalizer IN
+                SELECT  n.func AS func,
+                        n.param_count AS param_count,
+                        m.params AS params
+                  FROM  config.index_normalizer n
+                        JOIN config.record_attr_index_norm_map m ON (m.norm = n.id)
+                  WHERE attr = attr_def.name
+                  ORDER BY m.pos LOOP
+                    EXECUTE 'SELECT ' || normalizer.func || '(' ||
+                    COALESCE( quote_literal( tmp_val ), 'NULL' ) ||
+                        CASE
+                            WHEN normalizer.param_count > 0
+                                THEN ',' || REPLACE(REPLACE(BTRIM(normalizer.params,'[]'),E'\'',E'\\\''),E'"',E'\'')
+                                ELSE ''
+                            END ||
+                    ')' INTO tmp_val;
+
+            END LOOP;
+            IF tmp_val IS NOT NULL AND tmp_val <> '' THEN
+                -- note that a string that contains only blanks
+                -- is a valid value for some attributes
+                norm_attr_value := norm_attr_value || tmp_val;
+            END IF;
+        END LOOP;
+        
+        IF attr_def.filter THEN
+            -- Create unknown uncontrolled values and find the IDs of the values
+            IF ccvm_row.id IS NULL THEN
+                FOR tmp_val IN SELECT value FROM UNNEST(norm_attr_value) x(value) LOOP
+                    IF tmp_val IS NOT NULL AND BTRIM(tmp_val) <> '' THEN
+                        BEGIN -- use subtransaction to isolate unique constraint violations
+                            INSERT INTO metabib.uncontrolled_record_attr_value ( attr, value ) VALUES ( attr_def.name, tmp_val );
+                        EXCEPTION WHEN unique_violation THEN END;
+                    END IF;
+                END LOOP;
+
+                SELECT ARRAY_AGG(id) INTO attr_vector_tmp FROM metabib.uncontrolled_record_attr_value WHERE attr = attr_def.name AND value = ANY( norm_attr_value );
+            ELSE
+                SELECT ARRAY_AGG(id) INTO attr_vector_tmp FROM config.coded_value_map WHERE ctype = attr_def.name AND code = ANY( norm_attr_value );
+            END IF;
+
+            -- Add the new value to the vector
+            attr_vector := attr_vector || attr_vector_tmp;
+        END IF;
+
+        IF attr_def.sorter THEN
+            DELETE FROM metabib.record_sorter WHERE source = rid AND attr = attr_def.name;
+            IF norm_attr_value[1] IS NOT NULL THEN
+                INSERT INTO metabib.record_sorter (source, attr, value) VALUES (rid, attr_def.name, norm_attr_value[1]);
+            END IF;
+        END IF;
+
+    END LOOP;
+
+/* We may need to rewrite the vlist to contain
+   the intersection of new values for requested
+   attrs and old values for ignored attrs. To
+   do this, we take the old attr vlist and
+   subtract any values that are valid for the
+   requested attrs, and then add back the new
+   set of attr values. */
+
+    IF ARRAY_LENGTH(pattr_list, 1) > 0 THEN 
+        SELECT vlist INTO attr_vector_tmp FROM metabib.record_attr_vector_list WHERE source = rid;
+        SELECT attr_vector_tmp - ARRAY_AGG(id::INT) INTO attr_vector_tmp FROM metabib.full_attr_id_map WHERE attr = ANY (pattr_list);
+        attr_vector := attr_vector || attr_vector_tmp;
+    END IF;
+
+    -- On to composite attributes, now that the record attrs have been pulled.  Processed in name order, so later composite
+    -- attributes can depend on earlier ones.
+    PERFORM metabib.compile_composite_attr_cache_init();
+    FOR attr_def IN SELECT * FROM config.record_attr_definition WHERE composite AND name = ANY( attr_list ) ORDER BY name LOOP
+
+        FOR ccvm_row IN SELECT * FROM config.coded_value_map c WHERE c.ctype = attr_def.name ORDER BY value LOOP
+
+            tmp_val := metabib.compile_composite_attr( ccvm_row.id );
+            CONTINUE WHEN tmp_val IS NULL OR tmp_val = ''; -- nothing to do
+
+            IF attr_def.filter THEN
+                IF attr_vector @@ tmp_val::query_int THEN
+                    attr_vector = attr_vector + intset(ccvm_row.id);
+                    EXIT WHEN NOT attr_def.multi;
+                END IF;
+            END IF;
+
+            IF attr_def.sorter THEN
+                IF attr_vector @@ tmp_val THEN
+                    DELETE FROM metabib.record_sorter WHERE source = rid AND attr = attr_def.name;
+                    INSERT INTO metabib.record_sorter (source, attr, value) VALUES (rid, attr_def.name, ccvm_row.code);
+                END IF;
+            END IF;
+
+        END LOOP;
+
+    END LOOP;
+
+    IF ARRAY_LENGTH(attr_vector, 1) > 0 THEN
+        IF rdeleted THEN -- initial insert OR revivication
+            DELETE FROM metabib.record_attr_vector_list WHERE source = rid;
+            INSERT INTO metabib.record_attr_vector_list (source, vlist) VALUES (rid, attr_vector);
+        ELSE
+            UPDATE metabib.record_attr_vector_list SET vlist = attr_vector WHERE source = rid;
+        END IF;
+    END IF;
+
+END;
+
+$func$ LANGUAGE PLPGSQL;
+
+-- Correct SER and COM records, add most other subfields and make them usable as CCVMs
+
+SELECT evergreen.upgrade_deps_block_check('0967', :eg_version);
+
+-- Fix SER
+DELETE FROM config.marc21_ff_pos_map WHERE fixed_field = 'Audn' AND rec_type = 'SER';
+
+
+-- Map Fields to Record Types
+-- Form was already defined but missing from COM
+INSERT INTO config.marc21_ff_pos_map (fixed_field, tag, rec_type,start_pos, length, default_val) VALUES
+    ('Form', '006', 'COM', 6, 1, ' '),
+    ('Form', '008', 'COM', 23, 1, ' '),
+
+    ('Relf', '006', 'MAP', 1, 4, '    '),
+    ('Relf', '008', 'MAP', 18, 4, '    '),
+    ('Proj', '006', 'MAP', 5, 2, '  '),
+    ('Proj', '008', 'MAP', 22, 2, '  '),
+    ('CrTp', '006', 'MAP', 8, 1, 'a'),
+    ('CrTp', '008', 'MAP', 25, 1, 'a'),
+    ('SpFm', '006', 'MAP', 16, 2, '  '),
+    ('SpFm', '008', 'MAP', 33, 2, '  '),
+    ('Relf1', '006', 'MAP', 1, 1, ' '),
+    ('Relf1', '008', 'MAP', 18, 1, ' '),
+    ('Relf2', '006', 'MAP', 2, 1, ' '),
+    ('Relf2', '008', 'MAP', 19, 1, ' '),
+    ('Relf3', '006', 'MAP', 3, 1, ' '),
+    ('Relf3', '008', 'MAP', 20, 1, ' '),
+    ('Relf4', '006', 'MAP', 4, 1, ' '),
+    ('Relf4', '008', 'MAP', 21, 1, ' '),
+    ('SpFm1', '006', 'MAP', 16, 1, ' '),
+    ('SpFm1', '008', 'MAP', 33, 1, ' '),
+    ('SpFm2', '006', 'MAP', 17, 1, ' '),
+    ('SpFm2', '008', 'MAP', 34, 1, ' '),
+
+    ('Comp', '006', 'REC', 1, 2, 'uu'),
+    ('Comp', '008', 'REC', 18, 2, 'uu'),
+    ('FMus', '006', 'REC', 3, 1, 'n'),
+    ('FMus', '008', 'REC', 20, 1, 'n'),
+    ('Part', '006', 'REC', 4, 1, 'n'),
+    ('Part', '008', 'REC', 21, 1, 'n'),
+    ('AccM', '006', 'REC', 7, 6, '      '),
+    ('AccM', '008', 'REC', 24, 6, '      '),
+    ('LTxt', '006', 'REC', 13, 2, '  '),
+    ('LTxt', '008', 'REC', 30, 2, '  '),
+    ('TrAr', '006', 'REC', 16, 1, 'n'),
+    ('TrAr', '008', 'REC', 33, 1, 'n'),
+    ('AccM1', '006', 'REC', 7, 1, ' '),
+    ('AccM1', '008', 'REC', 24, 1, ' '),
+    ('AccM2', '006', 'REC', 8, 1, ' '),
+    ('AccM2', '008', 'REC', 25, 1, ' '),
+    ('AccM3', '006', 'REC', 9, 1, ' '),
+    ('AccM3', '008', 'REC', 26, 1, ' '),
+    ('AccM4', '006', 'REC', 10, 1, ' '),
+    ('AccM4', '008', 'REC', 27, 1, ' '),
+    ('AccM5', '006', 'REC', 11, 1, ' '),
+    ('AccM5', '008', 'REC', 28, 1, ' '),
+    ('AccM6', '006', 'REC', 12, 1, ' '),
+    ('AccM6', '008', 'REC', 29, 1, ' '),
+    ('LTxt1', '006', 'REC', 13, 1, ' '),
+    ('LTxt1', '008', 'REC', 30, 1, ' '),
+    ('LTxt2', '006', 'REC', 14, 1, ' '),
+    ('LTxt2', '008', 'REC', 31, 1, ' '),
+
+    ('Comp', '006', 'SCO', 1, 2, 'uu'),
+    ('Comp', '008', 'SCO', 18, 2, 'uu'),
+    ('FMus', '006', 'SCO', 3, 1, 'u'),
+    ('FMus', '008', 'SCO', 20, 1, 'u'),
+    ('Part', '006', 'SCO', 4, 1, ' '),
+    ('Part', '008', 'SCO', 21, 1, ' '),
+    ('AccM', '006', 'SCO', 7, 6, '      '),
+    ('AccM', '008', 'SCO', 24, 6, '      '),
+    ('LTxt', '006', 'SCO', 13, 2, 'n '),
+    ('LTxt', '008', 'SCO', 30, 2, 'n '),
+    ('TrAr', '006', 'SCO', 16, 1, ' '),
+    ('TrAr', '008', 'SCO', 33, 1, ' '),
+    ('AccM1', '006', 'SCO', 7, 1, ' '),
+    ('AccM1', '008', 'SCO', 24, 1, ' '),
+    ('AccM2', '006', 'SCO', 8, 1, ' '),
+    ('AccM2', '008', 'SCO', 25, 1, ' '),
+    ('AccM3', '006', 'SCO', 9, 1, ' '),
+    ('AccM3', '008', 'SCO', 26, 1, ' '),
+    ('AccM4', '006', 'SCO', 10, 1, ' '),
+    ('AccM4', '008', 'SCO', 27, 1, ' '),
+    ('AccM5', '006', 'SCO', 11, 1, ' '),
+    ('AccM5', '008', 'SCO', 28, 1, ' '),
+    ('AccM6', '006', 'SCO', 12, 1, ' '),
+    ('AccM6', '008', 'SCO', 29, 1, ' '),
+    ('LTxt1', '006', 'SCO', 13, 1, 'n'),
+    ('LTxt1', '008', 'SCO', 30, 1, 'n'),
+    ('LTxt2', '006', 'SCO', 14, 1, 'n'),
+    ('LTxt2', '008', 'SCO', 31, 1, 'n'),
+
+    ('SrTp', '006', 'SER', 4, 1, ' '),
+    ('SrTp', '008', 'SER', 21, 1, ' '),
+    ('Orig', '006', 'SER', 5, 1, ' '),
+    ('Orig', '008', 'SER', 22, 1, ' '),
+    ('EntW', '006', 'SER', 7, 1, ' '),
+    ('EntW', '008', 'SER', 24, 1, ' '),
+
+    ('Time', '006', 'VIS', 1, 3, '   '),
+    ('Time', '008', 'VIS', 18, 3, '   '),
+    ('Tech', '006', 'VIS', 17, 1, 'n'),
+    ('Tech', '008', 'VIS', 34, 1, 'n'),
+	
+	('Ills1', '006', 'BKS', 1, 1, ' '),
+    ('Ills1', '008', 'BKS', 18, 1, ' '),
+    ('Ills2', '006', 'BKS', 2, 1, ' '),
+    ('Ills2', '008', 'BKS', 19, 1, ' '),
+    ('Ills3', '006', 'BKS', 3, 1, ' '),
+    ('Ills3', '008', 'BKS', 20, 1, ' '),
+    ('Ills4', '006', 'BKS', 4, 1, ' '),
+    ('Ills4', '008', 'BKS', 21, 1, ' '),
+    ('Cont1', '006', 'BKS', 7, 1, ' '),
+    ('Cont1', '008', 'BKS', 24, 1, ' '),
+    ('Cont2', '006', 'BKS', 8, 1, ' '),
+    ('Cont2', '008', 'BKS', 25, 1, ' '),
+    ('Cont3', '006', 'BKS', 9, 1, ' '),
+    ('Cont3', '008', 'BKS', 26, 1, ' '),
+    ('Cont4', '006', 'BKS', 10, 1, ' '),
+    ('Cont4', '008', 'BKS', 27, 1, ' '),
+
+    ('Cont1', '006', 'SER', 8, 1, ' '),
+    ('Cont1', '008', 'SER', 25, 1, ' '),
+    ('Cont2', '006', 'SER', 9, 1, ' '),
+    ('Cont2', '008', 'SER', 26, 1, ' '),
+    ('Cont3', '006', 'SER', 10, 1, ' '),
+    ('Cont3', '008', 'SER', 27, 1, ' ');
+
+
+-- Add record_attr_definitions
+-- The xxx1,2,etc. are for multi-position single character code fields.
+INSERT INTO config.record_attr_definition (name,label,fixed_field) VALUES
+    ('accm','AccM','AccM'),
+    ('comp','Comp','Comp'),
+    ('crtp','CrTp','CrTp'),
+    ('entw','EntW','EntW'),
+    ('cont','Cont','Cont'),
+    ('fmus','FMus','FMus'),
+    ('ltxt','LTxt','LTxt'),
+    ('orig','Orig','Orig'),
+    ('part','Part','Part'),
+    ('proj','Proj','Proj'),
+    ('relf','Relf','Relf'),
+    ('spfm','SpFm','SpFm'),
+    ('srtp','SrTp','SrTp'),
+    ('tech','Tech','Tech'),
+    ('trar','TrAr','TrAr'),
+    ('accm1','AccM(1)','AccM1'),
+    ('accm2','AccM(2)','AccM2'),
+    ('accm3','AccM(3)','AccM3'),
+    ('accm4','AccM(4)','AccM4'),
+    ('accm5','AccM(5)','AccM5'),
+    ('accm6','AccM(6)','AccM6'),
+    ('cont1','Cont(1)','Cont1'),
+    ('cont2','Cont(2)','Cont2'),
+    ('cont3','Cont(3)','Cont3'),
+    ('cont4','Cont(4)','Cont4'),
+    ('ills1','Ills(1)','Ills1'),
+    ('ills2','Ills(2)','Ills2'),
+    ('ills3','Ills(3)','Ills3'),
+    ('ills4','Ills(4)','Ills4'),
+    ('ltxt1','LTxt(1)','LTxt1'),
+    ('ltxt2','LTxt(2)','LTxt2'),
+    ('relf1','Relf(1)','Relf1'),
+    ('relf2','Relf(2)','Relf2'),
+    ('relf3','Relf(3)','Relf3'),
+    ('relf4','Relf(4)','Relf4'),
+    ('spfm1','SpFm(1)','SpFm1'),
+    ('spfm2','SpFm(2)','SpFm2');
+
+UPDATE config.record_attr_definition SET composite = TRUE WHERE name IN ('accm', 'cont', 'ills', 'ltxt', 'relf', 'spfm');
+
+-- "Next" id for stock config.coded_value_map is 634 as of 7/16/15, but there's an incoming patch that takes 634-711
+INSERT INTO config.coded_value_map (id, ctype, code, value) VALUES
+    (1735, 'accm', ' ', 		oils_i18n_gettext('1735', 'No accompanying matter', 'ccvm', 'value')),
+    (713, 'accm', 'a', 			oils_i18n_gettext('713', 'Discography', 'ccvm', 'value')),
+    (714, 'accm', 'b', 			oils_i18n_gettext('714', 'Bibliography', 'ccvm', 'value')),
+    (715, 'accm', 'c', 			oils_i18n_gettext('715', 'Thematic index', 'ccvm', 'value')),
+    (716, 'accm', 'd', 			oils_i18n_gettext('716', 'Libretto or text', 'ccvm', 'value')),
+    (717, 'accm', 'e', 			oils_i18n_gettext('717', 'Biography of composer or author', 'ccvm', 'value')),
+    (718, 'accm', 'f', 			oils_i18n_gettext('718', 'Biography or performer or history of ensemble', 'ccvm', 'value')),
+    (719, 'accm', 'g', 			oils_i18n_gettext('719', 'Technical and/or historical information on instruments', 'ccvm', 'value')),
+    (720, 'accm', 'h', 			oils_i18n_gettext('720', 'Technical information on music', 'ccvm', 'value')),
+    (721, 'accm', 'i', 			oils_i18n_gettext('721', 'Historical information', 'ccvm', 'value')),
+    (722, 'accm', 'k', 			oils_i18n_gettext('722', 'Ethnological information', 'ccvm', 'value')),
+    (723, 'accm', 'r', 			oils_i18n_gettext('723', 'Instructional materials', 'ccvm', 'value')),
+    (724, 'accm', 's', 			oils_i18n_gettext('724', 'Music', 'ccvm', 'value')),
+    (725, 'accm', 'z', 			oils_i18n_gettext('725', 'Other accompanying matter', 'ccvm', 'value')),
+	
+    (726, 'comp', '  ', 		oils_i18n_gettext('726', 'No information supplied', 'ccvm', 'value')),
+    (727, 'comp', 'an', 		oils_i18n_gettext('727', 'Anthems', 'ccvm', 'value')),
+    (728, 'comp', 'bd', 		oils_i18n_gettext('728', 'Ballads', 'ccvm', 'value')),
+    (729, 'comp', 'bt', 		oils_i18n_gettext('729', 'Ballets', 'ccvm', 'value')),
+    (730, 'comp', 'bg', 		oils_i18n_gettext('730', 'Bluegrass music', 'ccvm', 'value')),
+    (731, 'comp', 'bl', 		oils_i18n_gettext('731', 'Blues', 'ccvm', 'value')),
+    (732, 'comp', 'cn', 		oils_i18n_gettext('732', 'Canons and rounds', 'ccvm', 'value')),
+    (733, 'comp', 'ct', 		oils_i18n_gettext('733', 'Cantatas', 'ccvm', 'value')),
+    (734, 'comp', 'cz', 		oils_i18n_gettext('734', 'Canzonas', 'ccvm', 'value')),
+    (735, 'comp', 'cr', 		oils_i18n_gettext('735', 'Carols', 'ccvm', 'value')),
+    (736, 'comp', 'ca', 		oils_i18n_gettext('736', 'Chaconnes', 'ccvm', 'value')),
+    (737, 'comp', 'cs', 		oils_i18n_gettext('737', 'Chance compositions', 'ccvm', 'value')),
+    (738, 'comp', 'cp', 		oils_i18n_gettext('738', 'Chansons, Polyphonic', 'ccvm', 'value')),
+    (739, 'comp', 'cc', 		oils_i18n_gettext('739', 'Chant, Christian', 'ccvm', 'value')),
+    (740, 'comp', 'cb', 		oils_i18n_gettext('740', 'Chants, other', 'ccvm', 'value')),
+    (741, 'comp', 'cl', 		oils_i18n_gettext('741', 'Chorale preludes', 'ccvm', 'value')),
+    (742, 'comp', 'ch', 		oils_i18n_gettext('742', 'Chorales', 'ccvm', 'value')),
+    (743, 'comp', 'cg', 		oils_i18n_gettext('743', 'Concerti grossi', 'ccvm', 'value')),
+    (744, 'comp', 'co', 		oils_i18n_gettext('744', 'Concertos', 'ccvm', 'value')),
+    (745, 'comp', 'cy', 		oils_i18n_gettext('745', 'Country music', 'ccvm', 'value')),
+    (746, 'comp', 'df', 		oils_i18n_gettext('746', 'Dance forms', 'ccvm', 'value')),
+    (747, 'comp', 'dv', 		oils_i18n_gettext('747', 'Divertimentos, serenades, cassations, divertissements, and notturni', 'ccvm', 'value')),
+    (748, 'comp', 'ft', 		oils_i18n_gettext('748', 'Fantasias', 'ccvm', 'value')),
+    (749, 'comp', 'fl', 		oils_i18n_gettext('749', 'Flamenco', 'ccvm', 'value')),
+    (750, 'comp', 'fm', 		oils_i18n_gettext('750', 'Folk music', 'ccvm', 'value')),
+    (751, 'comp', 'fg', 		oils_i18n_gettext('751', 'Fugues', 'ccvm', 'value')),
+    (752, 'comp', 'gm', 		oils_i18n_gettext('752', 'Gospel music', 'ccvm', 'value')),
+    (753, 'comp', 'hy', 		oils_i18n_gettext('753', 'Hymns', 'ccvm', 'value')),
+    (754, 'comp', 'jz', 		oils_i18n_gettext('754', 'Jazz', 'ccvm', 'value')),
+    (755, 'comp', 'md', 		oils_i18n_gettext('755', 'Madrigals', 'ccvm', 'value')),
+    (756, 'comp', 'mr', 		oils_i18n_gettext('756', 'Marches', 'ccvm', 'value')),
+    (757, 'comp', 'ms', 		oils_i18n_gettext('757', 'Masses', 'ccvm', 'value')),
+    (758, 'comp', 'mz', 		oils_i18n_gettext('758', 'Mazurkas', 'ccvm', 'value')),
+    (759, 'comp', 'mi', 		oils_i18n_gettext('759', 'Minuets', 'ccvm', 'value')),
+    (760, 'comp', 'mo', 		oils_i18n_gettext('760', 'Motets', 'ccvm', 'value')),
+    (761, 'comp', 'mp', 		oils_i18n_gettext('761', 'Motion picture music', 'ccvm', 'value')),
+    (762, 'comp', 'mu', 		oils_i18n_gettext('762', 'Multiple forms', 'ccvm', 'value')),
+    (763, 'comp', 'mc', 		oils_i18n_gettext('763', 'Musical reviews and comedies', 'ccvm', 'value')),
+    (764, 'comp', 'nc', 		oils_i18n_gettext('764', 'Nocturnes', 'ccvm', 'value')),
+    (765, 'comp', 'nn', 		oils_i18n_gettext('765', 'Not applicable', 'ccvm', 'value')),
+    (766, 'comp', 'op', 		oils_i18n_gettext('766', 'Operas', 'ccvm', 'value')),
+    (767, 'comp', 'or', 		oils_i18n_gettext('767', 'Oratorios', 'ccvm', 'value')),
+    (768, 'comp', 'ov', 		oils_i18n_gettext('768', 'Overtures', 'ccvm', 'value')),
+    (769, 'comp', 'pt', 		oils_i18n_gettext('769', 'Part-songs', 'ccvm', 'value')),
+    (770, 'comp', 'ps', 		oils_i18n_gettext('770', 'Passacaglias', 'ccvm', 'value')),
+    (771, 'comp', 'pm', 		oils_i18n_gettext('771', 'Passion music', 'ccvm', 'value')),
+    (772, 'comp', 'pv', 		oils_i18n_gettext('772', 'Pavans', 'ccvm', 'value')),
+    (773, 'comp', 'po', 		oils_i18n_gettext('773', 'Polonaises', 'ccvm', 'value')),
+    (774, 'comp', 'pp', 		oils_i18n_gettext('774', 'Popular music', 'ccvm', 'value')),
+    (775, 'comp', 'pr', 		oils_i18n_gettext('775', 'Preludes', 'ccvm', 'value')),
+    (776, 'comp', 'pg', 		oils_i18n_gettext('776', 'Program music', 'ccvm', 'value')),
+    (777, 'comp', 'rg', 		oils_i18n_gettext('777', 'Ragtime music', 'ccvm', 'value')),
+    (778, 'comp', 'rq', 		oils_i18n_gettext('778', 'Requiems', 'ccvm', 'value')),
+    (779, 'comp', 'rp', 		oils_i18n_gettext('779', 'Rhapsodies', 'ccvm', 'value')),
+    (780, 'comp', 'ri', 		oils_i18n_gettext('780', 'Ricercars', 'ccvm', 'value')),
+    (781, 'comp', 'rc', 		oils_i18n_gettext('781', 'Rock music', 'ccvm', 'value')),
+    (782, 'comp', 'rd', 		oils_i18n_gettext('782', 'Rondos', 'ccvm', 'value')),
+    (783, 'comp', 'sn', 		oils_i18n_gettext('783', 'Sonatas', 'ccvm', 'value')),
+    (784, 'comp', 'sg', 		oils_i18n_gettext('784', 'Songs', 'ccvm', 'value')),
+    (785, 'comp', 'sd', 		oils_i18n_gettext('785', 'Square dance music', 'ccvm', 'value')),
+    (786, 'comp', 'st', 		oils_i18n_gettext('786', 'Studies and exercises', 'ccvm', 'value')),
+    (787, 'comp', 'su', 		oils_i18n_gettext('787', 'Suites', 'ccvm', 'value')),
+    (788, 'comp', 'sp', 		oils_i18n_gettext('788', 'Symphonic poems', 'ccvm', 'value')),
+    (789, 'comp', 'sy', 		oils_i18n_gettext('789', 'Symphonies', 'ccvm', 'value')),
+    (790, 'comp', 'tl', 		oils_i18n_gettext('790', 'Teatro lirico', 'ccvm', 'value')),
+    (791, 'comp', 'tc', 		oils_i18n_gettext('791', 'Toccatas', 'ccvm', 'value')),
+    (792, 'comp', 'ts', 		oils_i18n_gettext('792', 'Trio-sonatas', 'ccvm', 'value')),
+    (793, 'comp', 'uu', 		oils_i18n_gettext('793', 'Unknown', 'ccvm', 'value')),
+    (794, 'comp', 'vi', 		oils_i18n_gettext('794', 'Villancicos', 'ccvm', 'value')),
+    (795, 'comp', 'vr', 		oils_i18n_gettext('795', 'Variations', 'ccvm', 'value')),
+    (796, 'comp', 'wz', 		oils_i18n_gettext('796', 'Waltzes', 'ccvm', 'value')),
+    (797, 'comp', 'za', 		oils_i18n_gettext('797', 'Zarzuelas', 'ccvm', 'value')),
+    (798, 'comp', 'zz', 		oils_i18n_gettext('798', 'Other forms', 'ccvm', 'value')),
+	
+    (799, 'crtp', 'a', 			oils_i18n_gettext('799', 'Single map', 'ccvm', 'value')),
+    (800, 'crtp', 'b', 			oils_i18n_gettext('800', 'Map series', 'ccvm', 'value')),
+    (801, 'crtp', 'c', 			oils_i18n_gettext('801', 'Map serial', 'ccvm', 'value')),
+    (802, 'crtp', 'd', 			oils_i18n_gettext('802', 'Globe', 'ccvm', 'value')),
+    (803, 'crtp', 'e', 			oils_i18n_gettext('803', 'Atlas', 'ccvm', 'value')),
+    (804, 'crtp', 'f', 			oils_i18n_gettext('804', 'Separate supplement to another work', 'ccvm', 'value')),
+    (805, 'crtp', 'g', 			oils_i18n_gettext('805', 'Bound as part of another work', 'ccvm', 'value')),
+    (806, 'crtp', 'u', 			oils_i18n_gettext('806', 'Unknown', 'ccvm', 'value')),
+    (807, 'crtp', 'z', 			oils_i18n_gettext('807', 'Other', 'ccvm', 'value')),
+	
+    (808, 'entw', ' ', 			oils_i18n_gettext('808', 'Not specified', 'ccvm', 'value')),
+    (809, 'entw', 'a', 			oils_i18n_gettext('809', 'Abstracts/summaries', 'ccvm', 'value')),
+    (810, 'entw', 'b', 			oils_i18n_gettext('810', 'Bibliographies', 'ccvm', 'value')),
+    (811, 'entw', 'c', 			oils_i18n_gettext('811', 'Catalogs', 'ccvm', 'value')),
+    (812, 'entw', 'd', 			oils_i18n_gettext('812', 'Dictionaries', 'ccvm', 'value')),
+    (813, 'entw', 'e', 			oils_i18n_gettext('813', 'Encyclopedias', 'ccvm', 'value')),
+    (814, 'entw', 'f', 			oils_i18n_gettext('814', 'Handbooks', 'ccvm', 'value')),
+    (815, 'entw', 'g', 			oils_i18n_gettext('815', 'Legal articles', 'ccvm', 'value')),
+    (816, 'entw', 'h', 			oils_i18n_gettext('816', 'Biography', 'ccvm', 'value')),
+    (817, 'entw', 'i', 			oils_i18n_gettext('817', 'Indexes', 'ccvm', 'value')),
+    (818, 'entw', 'k', 			oils_i18n_gettext('818', 'Discographies', 'ccvm', 'value')),
+    (819, 'entw', 'l', 			oils_i18n_gettext('819', 'Legislation', 'ccvm', 'value')),
+    (820, 'entw', 'm', 			oils_i18n_gettext('820', 'Theses', 'ccvm', 'value')),
+    (821, 'entw', 'n', 			oils_i18n_gettext('821', 'Surveys of the literature in a subject area', 'ccvm', 'value')),
+    (822, 'entw', 'o', 			oils_i18n_gettext('822', 'Reviews', 'ccvm', 'value')),
+    (823, 'entw', 'p', 			oils_i18n_gettext('823', 'Programmed texts', 'ccvm', 'value')),
+    (824, 'entw', 'q', 			oils_i18n_gettext('824', 'Filmographies', 'ccvm', 'value')),
+    (825, 'entw', 'r', 			oils_i18n_gettext('825', 'Directories', 'ccvm', 'value')),
+    (826, 'entw', 's', 			oils_i18n_gettext('826', 'Statistics', 'ccvm', 'value')),
+    (827, 'entw', 't', 			oils_i18n_gettext('827', 'Technical reports', 'ccvm', 'value')),
+    (828, 'entw', 'u', 			oils_i18n_gettext('828', 'Standards/specifications', 'ccvm', 'value')),
+    (829, 'entw', 'v', 			oils_i18n_gettext('829', 'Legal cases and case notes', 'ccvm', 'value')),
+    (830, 'entw', 'w', 			oils_i18n_gettext('830', 'Law reports and digests', 'ccvm', 'value')),
+    (831, 'entw', 'y', 			oils_i18n_gettext('831', 'Yearbooks', 'ccvm', 'value')),
+    (832, 'entw', 'z', 			oils_i18n_gettext('832', 'Treaties', 'ccvm', 'value')),
+    (833, 'entw', '5', 			oils_i18n_gettext('833', 'Calendars', 'ccvm', 'value')),
+    (834, 'entw', '6', 			oils_i18n_gettext('834', 'Comics/graphic novels', 'ccvm', 'value')),
+	
+    (835, 'cont', ' ', 			oils_i18n_gettext('835', 'Not specified', 'ccvm', 'value')),
+    (836, 'cont', 'a', 			oils_i18n_gettext('836', 'Abstracts/summaries', 'ccvm', 'value')),
+    (837, 'cont', 'b', 			oils_i18n_gettext('837', 'Bibliographies', 'ccvm', 'value')),
+    (838, 'cont', 'c', 			oils_i18n_gettext('838', 'Catalogs', 'ccvm', 'value')),
+    (839, 'cont', 'd', 			oils_i18n_gettext('839', 'Dictionaries', 'ccvm', 'value')),
+    (840, 'cont', 'e', 			oils_i18n_gettext('840', 'Encyclopedias', 'ccvm', 'value')),
+    (841, 'cont', 'f', 			oils_i18n_gettext('841', 'Handbooks', 'ccvm', 'value')),
+    (842, 'cont', 'g', 			oils_i18n_gettext('842', 'Legal articles', 'ccvm', 'value')),
+    (843, 'cont', 'h', 			oils_i18n_gettext('843', 'Biography', 'ccvm', 'value')),
+    (844, 'cont', 'i', 			oils_i18n_gettext('844', 'Indexes', 'ccvm', 'value')),
+    (845, 'cont', 'j', 			oils_i18n_gettext('845', 'Patent document', 'ccvm', 'value')),
+    (846, 'cont', 'k', 			oils_i18n_gettext('846', 'Discographies', 'ccvm', 'value')),
+    (847, 'cont', 'l', 			oils_i18n_gettext('847', 'Legislation', 'ccvm', 'value')),
+    (848, 'cont', 'm', 			oils_i18n_gettext('848', 'Theses', 'ccvm', 'value')),
+    (849, 'cont', 'n', 			oils_i18n_gettext('849', 'Surveys of the literature in a subject area', 'ccvm', 'value')),
+    (850, 'cont', 'o', 			oils_i18n_gettext('850', 'Reviews', 'ccvm', 'value')),
+    (851, 'cont', 'p', 			oils_i18n_gettext('851', 'Programmed texts', 'ccvm', 'value')),
+    (852, 'cont', 'q', 			oils_i18n_gettext('852', 'Filmographies', 'ccvm', 'value')),
+    (853, 'cont', 'r', 			oils_i18n_gettext('853', 'Directories', 'ccvm', 'value')),
+    (854, 'cont', 's', 			oils_i18n_gettext('854', 'Statistics', 'ccvm', 'value')),
+    (855, 'cont', 't', 			oils_i18n_gettext('855', 'Technical reports', 'ccvm', 'value')),
+    (856, 'cont', 'u', 			oils_i18n_gettext('856', 'Standards/specifications', 'ccvm', 'value')),
+    (857, 'cont', 'v', 			oils_i18n_gettext('857', 'Legal cases and case notes', 'ccvm', 'value')),
+    (858, 'cont', 'w', 			oils_i18n_gettext('858', 'Law reports and digests', 'ccvm', 'value')),
+    (859, 'cont', 'x', 			oils_i18n_gettext('859', 'Other reports', 'ccvm', 'value')),
+    (860, 'cont', 'y', 			oils_i18n_gettext('860', 'Yearbooks', 'ccvm', 'value')),
+    (861, 'cont', 'z', 			oils_i18n_gettext('861', 'Treaties', 'ccvm', 'value')),
+    (862, 'cont', '2', 			oils_i18n_gettext('862', 'Offprints', 'ccvm', 'value')),
+    (863, 'cont', '5', 			oils_i18n_gettext('863', 'Calendars', 'ccvm', 'value')),
+    (864, 'cont', '6', 			oils_i18n_gettext('864', 'Comics/graphic novels', 'ccvm', 'value')),
+	
+    (865, 'fmus', ' ', 			oils_i18n_gettext('865', 'Information not supplied', 'ccvm', 'value')),
+    (866, 'fmus', 'a', 			oils_i18n_gettext('866', 'Full score', 'ccvm', 'value')),
+    (867, 'fmus', 'b', 			oils_i18n_gettext('867', 'Full score, miniature or study size', 'ccvm', 'value')),
+    (868, 'fmus', 'c', 			oils_i18n_gettext('868', 'Accompaniment reduced for keyboard', 'ccvm', 'value')),
+    (869, 'fmus', 'd', 			oils_i18n_gettext('869', 'Voice score with accompaniment omitted', 'ccvm', 'value')),
+    (870, 'fmus', 'e', 			oils_i18n_gettext('870', 'Condensed score or piano-conductor score', 'ccvm', 'value')),
+    (871, 'fmus', 'g', 			oils_i18n_gettext('871', 'Close score', 'ccvm', 'value')),
+    (872, 'fmus', 'h', 			oils_i18n_gettext('872', 'Chorus score', 'ccvm', 'value')),
+    (873, 'fmus', 'i', 			oils_i18n_gettext('873', 'Condensed score', 'ccvm', 'value')),
+    (874, 'fmus', 'j', 			oils_i18n_gettext('874', 'Performer-conductor part', 'ccvm', 'value')),
+    (875, 'fmus', 'k', 			oils_i18n_gettext('875', 'Vocal score', 'ccvm', 'value')),
+    (876, 'fmus', 'l', 			oils_i18n_gettext('876', 'Score', 'ccvm', 'value')),
+    (877, 'fmus', 'm', 			oils_i18n_gettext('877', 'Multiple score formats', 'ccvm', 'value')),
+    (878, 'fmus', 'n', 			oils_i18n_gettext('878', 'Not applicable', 'ccvm', 'value')),
+    (879, 'fmus', 'u', 			oils_i18n_gettext('879', 'Unknown', 'ccvm', 'value')),
+    (880, 'fmus', 'z', 			oils_i18n_gettext('880', 'Other', 'ccvm', 'value')),
+	
+    (881, 'ltxt', ' ', 			oils_i18n_gettext('881', 'Item is a music sound recording', 'ccvm', 'value')),
+    (882, 'ltxt', 'a', 			oils_i18n_gettext('882', 'Autobiography', 'ccvm', 'value')),
+    (883, 'ltxt', 'b', 			oils_i18n_gettext('883', 'Biography', 'ccvm', 'value')),
+    (884, 'ltxt', 'c', 			oils_i18n_gettext('884', 'Conference proceedings', 'ccvm', 'value')),
+    (885, 'ltxt', 'd', 			oils_i18n_gettext('885', 'Drama', 'ccvm', 'value')),
+    (886, 'ltxt', 'e', 			oils_i18n_gettext('886', 'Essays', 'ccvm', 'value')),
+    (887, 'ltxt', 'f', 			oils_i18n_gettext('887', 'Fiction', 'ccvm', 'value')),
+    (888, 'ltxt', 'g', 			oils_i18n_gettext('888', 'Reporting', 'ccvm', 'value')),
+    (889, 'ltxt', 'h', 			oils_i18n_gettext('889', 'History', 'ccvm', 'value')),
+    (890, 'ltxt', 'i', 			oils_i18n_gettext('890', 'Instruction', 'ccvm', 'value')),
+    (891, 'ltxt', 'j', 			oils_i18n_gettext('891', 'Language instruction', 'ccvm', 'value')),
+    (892, 'ltxt', 'k', 			oils_i18n_gettext('892', 'Comedy', 'ccvm', 'value')),
+    (893, 'ltxt', 'l', 			oils_i18n_gettext('893', 'Lectures, speeches', 'ccvm', 'value')),
+    (894, 'ltxt', 'm', 			oils_i18n_gettext('894', 'Memoirs', 'ccvm', 'value')),
+    (895, 'ltxt', 'n', 			oils_i18n_gettext('895', 'Not applicable', 'ccvm', 'value')),
+    (896, 'ltxt', 'o', 			oils_i18n_gettext('896', 'Folktales', 'ccvm', 'value')),
+    (897, 'ltxt', 'p', 			oils_i18n_gettext('897', 'Poetry', 'ccvm', 'value')),
+    (898, 'ltxt', 'r', 			oils_i18n_gettext('898', 'Rehearsals', 'ccvm', 'value')),
+    (899, 'ltxt', 's', 			oils_i18n_gettext('899', 'Sounds', 'ccvm', 'value')),
+    (900, 'ltxt', 't', 			oils_i18n_gettext('900', 'Interviews', 'ccvm', 'value')),
+    (901, 'ltxt', 'z', 			oils_i18n_gettext('901', 'Other', 'ccvm', 'value')),
+	
+    (902, 'orig', ' ', 			oils_i18n_gettext('902', 'None of the following', 'ccvm', 'value')),
+    (903, 'orig', 'a', 			oils_i18n_gettext('903', 'Microfilm', 'ccvm', 'value')),
+    (904, 'orig', 'b', 			oils_i18n_gettext('904', 'Microfiche', 'ccvm', 'value')),
+    (905, 'orig', 'c', 			oils_i18n_gettext('905', 'Microopaque', 'ccvm', 'value')),
+    (906, 'orig', 'd', 			oils_i18n_gettext('906', 'Large print', 'ccvm', 'value')),
+    (907, 'orig', 'e', 			oils_i18n_gettext('907', 'Newspaper format', 'ccvm', 'value')),
+    (908, 'orig', 'f', 			oils_i18n_gettext('908', 'Braille', 'ccvm', 'value')),
+    (909, 'orig', 'o', 			oils_i18n_gettext('909', 'Online', 'ccvm', 'value')),
+    (910, 'orig', 'q', 			oils_i18n_gettext('910', 'Direct electronic', 'ccvm', 'value')),
+    (911, 'orig', 's', 			oils_i18n_gettext('911', 'Electronic', 'ccvm', 'value')),
+	
+    (912, 'part', ' ', 			oils_i18n_gettext('912', 'No parts in hand or not specified', 'ccvm', 'value')),
+    (913, 'part', 'd', 			oils_i18n_gettext('913', 'Instrumental and vocal parts', 'ccvm', 'value')),
+    (914, 'part', 'e', 			oils_i18n_gettext('914', 'Instrumental parts', 'ccvm', 'value')),
+    (915, 'part', 'f', 			oils_i18n_gettext('915', 'Vocal parts', 'ccvm', 'value')),
+    (916, 'part', 'n', 			oils_i18n_gettext('916', 'Not Applicable', 'ccvm', 'value')),
+    (917, 'part', 'u', 			oils_i18n_gettext('917', 'Unknown', 'ccvm', 'value')),
+	
+    (918, 'proj', '  ', 		oils_i18n_gettext('918', 'Project not specified', 'ccvm', 'value')),
+    (919, 'proj', 'aa', 		oils_i18n_gettext('919', 'Aitoff', 'ccvm', 'value')),
+    (920, 'proj', 'ab', 		oils_i18n_gettext('920', 'Gnomic', 'ccvm', 'value')),
+    (921, 'proj', 'ac', 		oils_i18n_gettext('921', 'Lambert''s azimuthal equal area', 'ccvm', 'value')),
+    (922, 'proj', 'ad', 		oils_i18n_gettext('922', 'Orthographic', 'ccvm', 'value')),
+    (923, 'proj', 'ae', 		oils_i18n_gettext('923', 'Azimuthal equidistant', 'ccvm', 'value')),
+    (924, 'proj', 'af', 		oils_i18n_gettext('924', 'Stereographic', 'ccvm', 'value')),
+    (925, 'proj', 'ag', 		oils_i18n_gettext('925', 'General vertical near-sided', 'ccvm', 'value')),
+    (926, 'proj', 'am', 		oils_i18n_gettext('926', 'Modified stereographic for Alaska', 'ccvm', 'value')),
+    (927, 'proj', 'an', 		oils_i18n_gettext('927', 'Chamberlin trimetric', 'ccvm', 'value')),
+    (928, 'proj', 'ap', 		oils_i18n_gettext('928', 'Polar stereographic', 'ccvm', 'value')),
+    (929, 'proj', 'au', 		oils_i18n_gettext('929', 'Azimuthal, specific type unknown', 'ccvm', 'value')),
+    (930, 'proj', 'az', 		oils_i18n_gettext('930', 'Azimuthal, other', 'ccvm', 'value')),
+    (931, 'proj', 'ba', 		oils_i18n_gettext('931', 'Gall', 'ccvm', 'value')),
+    (932, 'proj', 'bb', 		oils_i18n_gettext('932', 'Goode''s homolographic', 'ccvm', 'value')),
+    (933, 'proj', 'bc', 		oils_i18n_gettext('933', 'Lambert''s cylindrical equal area', 'ccvm', 'value')),
+    (934, 'proj', 'bd', 		oils_i18n_gettext('934', 'Mercator', 'ccvm', 'value')),
+    (935, 'proj', 'be', 		oils_i18n_gettext('935', 'Miller', 'ccvm', 'value')),
+    (936, 'proj', 'bf', 		oils_i18n_gettext('936', 'Mollweide', 'ccvm', 'value')),
+    (937, 'proj', 'bg', 		oils_i18n_gettext('937', 'Sinusoidal', 'ccvm', 'value')),
+    (938, 'proj', 'bh', 		oils_i18n_gettext('938', 'Transverse Mercator', 'ccvm', 'value')),
+    (939, 'proj', 'bi', 		oils_i18n_gettext('939', 'Gauss-Kruger', 'ccvm', 'value')),
+    (940, 'proj', 'bj', 		oils_i18n_gettext('940', 'Equirectangular', 'ccvm', 'value')),
+    (941, 'proj', 'bk', 		oils_i18n_gettext('941', 'Krovak', 'ccvm', 'value')),
+    (942, 'proj', 'bl', 		oils_i18n_gettext('942', 'Cassini-Soldner', 'ccvm', 'value')),
+    (943, 'proj', 'bo', 		oils_i18n_gettext('943', 'Oblique Mercator', 'ccvm', 'value')),
+    (944, 'proj', 'br', 		oils_i18n_gettext('944', 'Robinson', 'ccvm', 'value')),
+    (945, 'proj', 'bs', 		oils_i18n_gettext('945', 'Space oblique Mercator', 'ccvm', 'value')),
+    (946, 'proj', 'bu', 		oils_i18n_gettext('946', 'Cylindrical, specific type unknown', 'ccvm', 'value')),
+    (947, 'proj', 'bz', 		oils_i18n_gettext('947', 'Cylindrical, other', 'ccvm', 'value')),
+    (948, 'proj', 'ca', 		oils_i18n_gettext('948', 'Alber''s equal area', 'ccvm', 'value')),
+    (949, 'proj', 'cb', 		oils_i18n_gettext('949', 'Bonne', 'ccvm', 'value')),
+    (950, 'proj', 'cc', 		oils_i18n_gettext('950', 'Lambert''s conformal conic', 'ccvm', 'value')),
+    (951, 'proj', 'ce', 		oils_i18n_gettext('951', 'Equidistant conic', 'ccvm', 'value')),
+    (952, 'proj', 'cp', 		oils_i18n_gettext('952', 'Polyconic', 'ccvm', 'value')),
+    (953, 'proj', 'cu', 		oils_i18n_gettext('953', 'Conic, specific type unknown', 'ccvm', 'value')),
+    (954, 'proj', 'cz', 		oils_i18n_gettext('954', 'Conic, other', 'ccvm', 'value')),
+    (955, 'proj', 'da', 		oils_i18n_gettext('955', 'Armadillo', 'ccvm', 'value')),
+    (956, 'proj', 'db', 		oils_i18n_gettext('956', 'Butterfly', 'ccvm', 'value')),
+    (957, 'proj', 'dc', 		oils_i18n_gettext('957', 'Eckert', 'ccvm', 'value')),
+    (958, 'proj', 'dd', 		oils_i18n_gettext('958', 'Goode''s homolosine', 'ccvm', 'value')),
+    (959, 'proj', 'de', 		oils_i18n_gettext('959', 'Miller''s bipolar oblique conformal conic', 'ccvm', 'value')),
+    (960, 'proj', 'df', 		oils_i18n_gettext('960', 'Van Der Grinten', 'ccvm', 'value')),
+    (961, 'proj', 'dg', 		oils_i18n_gettext('961', 'Dymaxion', 'ccvm', 'value')),
+    (962, 'proj', 'dh', 		oils_i18n_gettext('962', 'Cordiform', 'ccvm', 'value')),
+    (963, 'proj', 'dl', 		oils_i18n_gettext('963', 'Lambert conformal', 'ccvm', 'value')),
+    (964, 'proj', 'zz', 		oils_i18n_gettext('964', 'Other', 'ccvm', 'value')),
+	
+    (965, 'relf', ' ', 			oils_i18n_gettext('965', 'No relief shown', 'ccvm', 'value')),
+    (966, 'relf', 'a', 			oils_i18n_gettext('966', 'Contours', 'ccvm', 'value')),
+    (967, 'relf', 'b', 			oils_i18n_gettext('967', 'Shading', 'ccvm', 'value')),
+    (968, 'relf', 'c', 			oils_i18n_gettext('968', 'Gradient and bathymetric tints', 'ccvm', 'value')),
+    (969, 'relf', 'd', 			oils_i18n_gettext('969', 'Hachures', 'ccvm', 'value')),
+    (970, 'relf', 'e', 			oils_i18n_gettext('970', 'Bathymetry, soundings', 'ccvm', 'value')),
+    (971, 'relf', 'f', 			oils_i18n_gettext('971', 'Form lines', 'ccvm', 'value')),
+    (972, 'relf', 'g', 			oils_i18n_gettext('972', 'Spot heights', 'ccvm', 'value')),
+    (973, 'relf', 'i', 			oils_i18n_gettext('973', 'Pictorially', 'ccvm', 'value')),
+    (974, 'relf', 'j', 			oils_i18n_gettext('974', 'Land forms', 'ccvm', 'value')),
+    (975, 'relf', 'k', 			oils_i18n_gettext('975', 'Bathymetry, isolines', 'ccvm', 'value')),
+    (976, 'relf', 'm', 			oils_i18n_gettext('976', 'Rock drawings', 'ccvm', 'value')),
+    (977, 'relf', 'z', 			oils_i18n_gettext('977', 'Other', 'ccvm', 'value')),
+	
+    (978, 'spfm', ' ', 			oils_i18n_gettext('978', 'No specified special format characteristics', 'ccvm', 'value')),
+    (979, 'spfm', 'e', 			oils_i18n_gettext('979', 'Manuscript', 'ccvm', 'value')),
+    (980, 'spfm', 'j', 			oils_i18n_gettext('980', 'Picture card, post card', 'ccvm', 'value')),
+    (981, 'spfm', 'k', 			oils_i18n_gettext('981', 'Calendar', 'ccvm', 'value')),
+    (982, 'spfm', 'l', 			oils_i18n_gettext('982', 'Puzzle', 'ccvm', 'value')),
+    (983, 'spfm', 'n', 			oils_i18n_gettext('983', 'Game', 'ccvm', 'value')),
+    (984, 'spfm', 'o', 			oils_i18n_gettext('984', 'Wall map', 'ccvm', 'value')),
+    (985, 'spfm', 'p', 			oils_i18n_gettext('985', 'Playing cards', 'ccvm', 'value')),
+    (986, 'spfm', 'r', 			oils_i18n_gettext('986', 'Loose-leaf', 'ccvm', 'value')),
+    (987, 'spfm', 'z', 			oils_i18n_gettext('987', 'Other', 'ccvm', 'value')),
+	
+    (988, 'srtp', ' ', 			oils_i18n_gettext('988', 'None of the following', 'ccvm', 'value')),
+    (989, 'srtp', 'd', 			oils_i18n_gettext('989', 'Updating database', 'ccvm', 'value')),
+    (990, 'srtp', 'l', 			oils_i18n_gettext('990', 'Updating loose-leaf', 'ccvm', 'value')),
+    (991, 'srtp', 'm', 			oils_i18n_gettext('991', 'Monographic series', 'ccvm', 'value')),
+    (992, 'srtp', 'n', 			oils_i18n_gettext('992', 'Newspaper', 'ccvm', 'value')),
+    (993, 'srtp', 'p', 			oils_i18n_gettext('993', 'Periodical', 'ccvm', 'value')),
+    (994, 'srtp', 'w', 			oils_i18n_gettext('994', 'Updating Web site', 'ccvm', 'value')),
+	
+    (995, 'tech', 'a', 			oils_i18n_gettext('995', 'Animation', 'ccvm', 'value')),
+    (996, 'tech', 'c', 			oils_i18n_gettext('996', 'Animation and live action', 'ccvm', 'value')),
+    (997, 'tech', 'l', 			oils_i18n_gettext('997', 'Live action', 'ccvm', 'value')),
+    (998, 'tech', 'n', 			oils_i18n_gettext('998', 'Not applicable', 'ccvm', 'value')),
+    (999, 'tech', 'u', 			oils_i18n_gettext('999', 'Unknown', 'ccvm', 'value')),
+    (1000, 'tech', 'z', 		oils_i18n_gettext('1000', 'Other', 'ccvm', 'value')),
+	
+    (1001, 'trar', ' ', 		oils_i18n_gettext('1001', 'Not arrangement or transposition or not specified', 'ccvm', 'value')),
+    (1002, 'trar', 'a', 		oils_i18n_gettext('1002', 'Transposition', 'ccvm', 'value')),
+    (1003, 'trar', 'b', 		oils_i18n_gettext('1003', 'Arrangement', 'ccvm', 'value')),
+    (1004, 'trar', 'c', 		oils_i18n_gettext('1004', 'Both transposed and arranged', 'ccvm', 'value')),
+    (1005, 'trar', 'n', 		oils_i18n_gettext('1005', 'Not applicable', 'ccvm', 'value')),
+    (1006, 'trar', 'u', 		oils_i18n_gettext('1006', 'Unknown', 'ccvm', 'value')),
+	
+    (1007, 'ctry', 'aa ', 		oils_i18n_gettext('1007', 'Albania ', 'ccvm', 'value')),
+    (1008, 'ctry', 'abc', 		oils_i18n_gettext('1008', 'Alberta ', 'ccvm', 'value')),
+    (1009, 'ctry', 'aca', 		oils_i18n_gettext('1009', 'Australian Capital Territory ', 'ccvm', 'value')),
+    (1010, 'ctry', 'ae ', 		oils_i18n_gettext('1010', 'Algeria ', 'ccvm', 'value')),
+    (1011, 'ctry', 'af ', 		oils_i18n_gettext('1011', 'Afghanistan ', 'ccvm', 'value')),
+    (1012, 'ctry', 'ag ', 		oils_i18n_gettext('1012', 'Argentina ', 'ccvm', 'value')),
+    (1013, 'ctry', 'ai ', 		oils_i18n_gettext('1013', 'Armenia (Republic) ', 'ccvm', 'value')),
+    (1014, 'ctry', 'aj ', 		oils_i18n_gettext('1014', 'Azerbaijan ', 'ccvm', 'value')),
+    (1015, 'ctry', 'aku', 		oils_i18n_gettext('1015', 'Alaska ', 'ccvm', 'value')),
+    (1016, 'ctry', 'alu', 		oils_i18n_gettext('1016', 'Alabama ', 'ccvm', 'value')),
+    (1017, 'ctry', 'am ', 		oils_i18n_gettext('1017', 'Anguilla ', 'ccvm', 'value')),
+    (1018, 'ctry', 'an ', 		oils_i18n_gettext('1018', 'Andorra ', 'ccvm', 'value')),
+    (1019, 'ctry', 'ao ', 		oils_i18n_gettext('1019', 'Angola ', 'ccvm', 'value')),
+    (1020, 'ctry', 'aq ', 		oils_i18n_gettext('1020', 'Antigua and Barbuda ', 'ccvm', 'value')),
+    (1021, 'ctry', 'aru', 		oils_i18n_gettext('1021', 'Arkansas ', 'ccvm', 'value')),
+    (1022, 'ctry', 'as ', 		oils_i18n_gettext('1022', 'American Samoa ', 'ccvm', 'value')),
+    (1023, 'ctry', 'at ', 		oils_i18n_gettext('1023', 'Australia ', 'ccvm', 'value')),
+    (1024, 'ctry', 'au ', 		oils_i18n_gettext('1024', 'Austria ', 'ccvm', 'value')),
+    (1025, 'ctry', 'aw ', 		oils_i18n_gettext('1025', 'Aruba ', 'ccvm', 'value')),
+    (1026, 'ctry', 'ay ', 		oils_i18n_gettext('1026', 'Antarctica ', 'ccvm', 'value')),
+    (1027, 'ctry', 'azu', 		oils_i18n_gettext('1027', 'Arizona ', 'ccvm', 'value')),
+    (1028, 'ctry', 'ba ', 		oils_i18n_gettext('1028', 'Bahrain ', 'ccvm', 'value')),
+    (1029, 'ctry', 'bb ', 		oils_i18n_gettext('1029', 'Barbados ', 'ccvm', 'value')),
+    (1030, 'ctry', 'bcc', 		oils_i18n_gettext('1030', 'British Columbia ', 'ccvm', 'value')),
+    (1031, 'ctry', 'bd ', 		oils_i18n_gettext('1031', 'Burundi ', 'ccvm', 'value')),
+    (1032, 'ctry', 'be ', 		oils_i18n_gettext('1032', 'Belgium ', 'ccvm', 'value')),
+    (1033, 'ctry', 'bf ', 		oils_i18n_gettext('1033', 'Bahamas ', 'ccvm', 'value')),
+    (1034, 'ctry', 'bg ', 		oils_i18n_gettext('1034', 'Bangladesh ', 'ccvm', 'value')),
+    (1035, 'ctry', 'bh ', 		oils_i18n_gettext('1035', 'Belize ', 'ccvm', 'value')),
+    (1036, 'ctry', 'bi ', 		oils_i18n_gettext('1036', 'British Indian Ocean Territory ', 'ccvm', 'value')),
+    (1037, 'ctry', 'bl ', 		oils_i18n_gettext('1037', 'Brazil ', 'ccvm', 'value')),
+    (1038, 'ctry', 'bm ', 		oils_i18n_gettext('1038', 'Bermuda Islands ', 'ccvm', 'value')),
+    (1039, 'ctry', 'bn ', 		oils_i18n_gettext('1039', 'Bosnia and Herzegovina ', 'ccvm', 'value')),
+    (1040, 'ctry', 'bo ', 		oils_i18n_gettext('1040', 'Bolivia ', 'ccvm', 'value')),
+    (1041, 'ctry', 'bp ', 		oils_i18n_gettext('1041', 'Solomon Islands ', 'ccvm', 'value')),
+    (1042, 'ctry', 'br ', 		oils_i18n_gettext('1042', 'Burma ', 'ccvm', 'value')),
+    (1043, 'ctry', 'bs ', 		oils_i18n_gettext('1043', 'Botswana ', 'ccvm', 'value')),
+    (1044, 'ctry', 'bt ', 		oils_i18n_gettext('1044', 'Bhutan ', 'ccvm', 'value')),
+    (1045, 'ctry', 'bu ', 		oils_i18n_gettext('1045', 'Bulgaria ', 'ccvm', 'value')),
+    (1046, 'ctry', 'bv ', 		oils_i18n_gettext('1046', 'Bouvet Island ', 'ccvm', 'value')),
+    (1047, 'ctry', 'bw ', 		oils_i18n_gettext('1047', 'Belarus ', 'ccvm', 'value')),
+    (1048, 'ctry', 'bx ', 		oils_i18n_gettext('1048', 'Brunei ', 'ccvm', 'value')),
+    (1049, 'ctry', 'ca ', 		oils_i18n_gettext('1049', 'Caribbean Netherlands ', 'ccvm', 'value')),
+    (1050, 'ctry', 'cau', 		oils_i18n_gettext('1050', 'California ', 'ccvm', 'value')),
+    (1051, 'ctry', 'cb ', 		oils_i18n_gettext('1051', 'Cambodia ', 'ccvm', 'value')),
+    (1052, 'ctry', 'cc ', 		oils_i18n_gettext('1052', 'China ', 'ccvm', 'value')),
+    (1053, 'ctry', 'cd ', 		oils_i18n_gettext('1053', 'Chad ', 'ccvm', 'value')),
+    (1054, 'ctry', 'ce ', 		oils_i18n_gettext('1054', 'Sri Lanka ', 'ccvm', 'value')),
+    (1055, 'ctry', 'cf ', 		oils_i18n_gettext('1055', 'Congo (Brazzaville) ', 'ccvm', 'value')),
+    (1056, 'ctry', 'cg ', 		oils_i18n_gettext('1056', 'Congo (Democratic Republic) ', 'ccvm', 'value')),
+    (1057, 'ctry', 'ch ', 		oils_i18n_gettext('1057', 'China (Republic : 1949', 'ccvm', 'value')),
+    (1058, 'ctry', 'ci ', 		oils_i18n_gettext('1058', 'Croatia ', 'ccvm', 'value')),
+    (1059, 'ctry', 'cj ', 		oils_i18n_gettext('1059', 'Cayman Islands ', 'ccvm', 'value')),
+    (1060, 'ctry', 'ck ', 		oils_i18n_gettext('1060', 'Colombia ', 'ccvm', 'value')),
+    (1061, 'ctry', 'cl ', 		oils_i18n_gettext('1061', 'Chile ', 'ccvm', 'value')),
+    (1062, 'ctry', 'cm ', 		oils_i18n_gettext('1062', 'Cameroon ', 'ccvm', 'value')),
+    (1063, 'ctry', 'co ', 		oils_i18n_gettext('1063', 'Curaçao ', 'ccvm', 'value')),
+    (1064, 'ctry', 'cou', 		oils_i18n_gettext('1064', 'Colorado ', 'ccvm', 'value')),
+    (1065, 'ctry', 'cq ', 		oils_i18n_gettext('1065', 'Comoros ', 'ccvm', 'value')),
+    (1066, 'ctry', 'cr ', 		oils_i18n_gettext('1066', 'Costa Rica ', 'ccvm', 'value')),
+    (1067, 'ctry', 'ctu', 		oils_i18n_gettext('1067', 'Connecticut ', 'ccvm', 'value')),
+    (1068, 'ctry', 'cu ', 		oils_i18n_gettext('1068', 'Cuba ', 'ccvm', 'value')),
+    (1069, 'ctry', 'cv ', 		oils_i18n_gettext('1069', 'Cabo Verde ', 'ccvm', 'value')),
+    (1070, 'ctry', 'cw ', 		oils_i18n_gettext('1070', 'Cook Islands ', 'ccvm', 'value')),
+    (1071, 'ctry', 'cx ', 		oils_i18n_gettext('1071', 'Central African Republic ', 'ccvm', 'value')),
+    (1072, 'ctry', 'cy ', 		oils_i18n_gettext('1072', 'Cyprus ', 'ccvm', 'value')),
+    (1073, 'ctry', 'dcu', 		oils_i18n_gettext('1073', 'District of Columbia ', 'ccvm', 'value')),
+    (1074, 'ctry', 'deu', 		oils_i18n_gettext('1074', 'Delaware ', 'ccvm', 'value')),
+    (1075, 'ctry', 'dk ', 		oils_i18n_gettext('1075', 'Denmark ', 'ccvm', 'value')),
+    (1076, 'ctry', 'dm ', 		oils_i18n_gettext('1076', 'Benin ', 'ccvm', 'value')),
+    (1077, 'ctry', 'dq ', 		oils_i18n_gettext('1077', 'Dominica ', 'ccvm', 'value')),
+    (1078, 'ctry', 'dr ', 		oils_i18n_gettext('1078', 'Dominican Republic ', 'ccvm', 'value')),
+    (1079, 'ctry', 'ea ', 		oils_i18n_gettext('1079', 'Eritrea ', 'ccvm', 'value')),
+    (1080, 'ctry', 'ec ', 		oils_i18n_gettext('1080', 'Ecuador ', 'ccvm', 'value')),
+    (1081, 'ctry', 'eg ', 		oils_i18n_gettext('1081', 'Equatorial Guinea ', 'ccvm', 'value')),
+    (1082, 'ctry', 'em ', 		oils_i18n_gettext('1082', 'Timor', 'ccvm', 'value')),
+    (1083, 'ctry', 'enk', 		oils_i18n_gettext('1083', 'England ', 'ccvm', 'value')),
+    (1084, 'ctry', 'er ', 		oils_i18n_gettext('1084', 'Estonia ', 'ccvm', 'value')),
+    (1085, 'ctry', 'es ', 		oils_i18n_gettext('1085', 'El Salvador ', 'ccvm', 'value')),
+    (1086, 'ctry', 'et ', 		oils_i18n_gettext('1086', 'Ethiopia ', 'ccvm', 'value')),
+    (1087, 'ctry', 'fa ', 		oils_i18n_gettext('1087', 'Faroe Islands ', 'ccvm', 'value')),
+    (1088, 'ctry', 'fg ', 		oils_i18n_gettext('1088', 'French Guiana ', 'ccvm', 'value')),
+    (1089, 'ctry', 'fi ', 		oils_i18n_gettext('1089', 'Finland ', 'ccvm', 'value')),
+    (1090, 'ctry', 'fj ', 		oils_i18n_gettext('1090', 'Fiji ', 'ccvm', 'value')),
+    (1091, 'ctry', 'fk ', 		oils_i18n_gettext('1091', 'Falkland Islands ', 'ccvm', 'value')),
+    (1092, 'ctry', 'flu', 		oils_i18n_gettext('1092', 'Florida ', 'ccvm', 'value')),
+    (1093, 'ctry', 'fm ', 		oils_i18n_gettext('1093', 'Micronesia (Federated States) ', 'ccvm', 'value')),
+    (1094, 'ctry', 'fp ', 		oils_i18n_gettext('1094', 'French Polynesia ', 'ccvm', 'value')),
+    (1095, 'ctry', 'fr ', 		oils_i18n_gettext('1095', 'France ', 'ccvm', 'value')),
+    (1096, 'ctry', 'fs ', 		oils_i18n_gettext('1096', 'Terres australes et antarctiques françaises ', 'ccvm', 'value')),
+    (1097, 'ctry', 'ft ', 		oils_i18n_gettext('1097', 'Djibouti ', 'ccvm', 'value')),
+    (1098, 'ctry', 'gau', 		oils_i18n_gettext('1098', 'Georgia ', 'ccvm', 'value')),
+    (1099, 'ctry', 'gb ', 		oils_i18n_gettext('1099', 'Kiribati ', 'ccvm', 'value')),
+    (1100, 'ctry', 'gd ', 		oils_i18n_gettext('1100', 'Grenada ', 'ccvm', 'value')),
+    (1101, 'ctry', 'gh ', 		oils_i18n_gettext('1101', 'Ghana ', 'ccvm', 'value')),
+    (1102, 'ctry', 'gi ', 		oils_i18n_gettext('1102', 'Gibraltar ', 'ccvm', 'value')),
+    (1103, 'ctry', 'gl ', 		oils_i18n_gettext('1103', 'Greenland ', 'ccvm', 'value')),
+    (1104, 'ctry', 'gm ', 		oils_i18n_gettext('1104', 'Gambia ', 'ccvm', 'value')),
+    (1105, 'ctry', 'go ', 		oils_i18n_gettext('1105', 'Gabon ', 'ccvm', 'value')),
+    (1106, 'ctry', 'gp ', 		oils_i18n_gettext('1106', 'Guadeloupe ', 'ccvm', 'value')),
+    (1107, 'ctry', 'gr ', 		oils_i18n_gettext('1107', 'Greece ', 'ccvm', 'value')),
+    (1108, 'ctry', 'gs ', 		oils_i18n_gettext('1108', 'Georgia (Republic) ', 'ccvm', 'value')),
+    (1109, 'ctry', 'gt ', 		oils_i18n_gettext('1109', 'Guatemala ', 'ccvm', 'value')),
+    (1110, 'ctry', 'gu ', 		oils_i18n_gettext('1110', 'Guam ', 'ccvm', 'value')),
+    (1111, 'ctry', 'gv ', 		oils_i18n_gettext('1111', 'Guinea ', 'ccvm', 'value')),
+    (1112, 'ctry', 'gw ', 		oils_i18n_gettext('1112', 'Germany ', 'ccvm', 'value')),
+    (1113, 'ctry', 'gy ', 		oils_i18n_gettext('1113', 'Guyana ', 'ccvm', 'value')),
+    (1114, 'ctry', 'gz ', 		oils_i18n_gettext('1114', 'Gaza Strip ', 'ccvm', 'value')),
+    (1115, 'ctry', 'hiu', 		oils_i18n_gettext('1115', 'Hawaii ', 'ccvm', 'value')),
+    (1116, 'ctry', 'hm ', 		oils_i18n_gettext('1116', 'Heard and McDonald Islands ', 'ccvm', 'value')),
+    (1117, 'ctry', 'ho ', 		oils_i18n_gettext('1117', 'Honduras ', 'ccvm', 'value')),
+    (1118, 'ctry', 'ht ', 		oils_i18n_gettext('1118', 'Haiti ', 'ccvm', 'value')),
+    (1119, 'ctry', 'hu ', 		oils_i18n_gettext('1119', 'Hungary ', 'ccvm', 'value')),
+    (1120, 'ctry', 'iau', 		oils_i18n_gettext('1120', 'Iowa ', 'ccvm', 'value')),
+    (1121, 'ctry', 'ic ', 		oils_i18n_gettext('1121', 'Iceland ', 'ccvm', 'value')),
+    (1122, 'ctry', 'idu', 		oils_i18n_gettext('1122', 'Idaho ', 'ccvm', 'value')),
+    (1123, 'ctry', 'ie ', 		oils_i18n_gettext('1123', 'Ireland ', 'ccvm', 'value')),
+    (1124, 'ctry', 'ii ', 		oils_i18n_gettext('1124', 'India ', 'ccvm', 'value')),
+    (1125, 'ctry', 'ilu', 		oils_i18n_gettext('1125', 'Illinois ', 'ccvm', 'value')),
+    (1126, 'ctry', 'inu', 		oils_i18n_gettext('1126', 'Indiana ', 'ccvm', 'value')),
+    (1127, 'ctry', 'io ', 		oils_i18n_gettext('1127', 'Indonesia ', 'ccvm', 'value')),
+    (1128, 'ctry', 'iq ', 		oils_i18n_gettext('1128', 'Iraq ', 'ccvm', 'value')),
+    (1129, 'ctry', 'ir ', 		oils_i18n_gettext('1129', 'Iran ', 'ccvm', 'value')),
+    (1130, 'ctry', 'is ', 		oils_i18n_gettext('1130', 'Israel ', 'ccvm', 'value')),
+    (1131, 'ctry', 'it ', 		oils_i18n_gettext('1131', 'Italy ', 'ccvm', 'value')),
+    (1132, 'ctry', 'iv ', 		oils_i18n_gettext('1132', 'Côte d''Ivoire ', 'ccvm', 'value')),
+    (1133, 'ctry', 'iy ', 		oils_i18n_gettext('1133', 'Iraq', 'ccvm', 'value')),
+    (1134, 'ctry', 'ja ', 		oils_i18n_gettext('1134', 'Japan ', 'ccvm', 'value')),
+    (1135, 'ctry', 'ji ', 		oils_i18n_gettext('1135', 'Johnston Atoll ', 'ccvm', 'value')),
+    (1136, 'ctry', 'jm ', 		oils_i18n_gettext('1136', 'Jamaica ', 'ccvm', 'value')),
+    (1137, 'ctry', 'jo ', 		oils_i18n_gettext('1137', 'Jordan ', 'ccvm', 'value')),
+    (1138, 'ctry', 'ke ', 		oils_i18n_gettext('1138', 'Kenya ', 'ccvm', 'value')),
+    (1139, 'ctry', 'kg ', 		oils_i18n_gettext('1139', 'Kyrgyzstan ', 'ccvm', 'value')),
+    (1140, 'ctry', 'kn ', 		oils_i18n_gettext('1140', 'Korea (North) ', 'ccvm', 'value')),
+    (1141, 'ctry', 'ko ', 		oils_i18n_gettext('1141', 'Korea (South) ', 'ccvm', 'value')),
+    (1142, 'ctry', 'ksu', 		oils_i18n_gettext('1142', 'Kansas ', 'ccvm', 'value')),
+    (1143, 'ctry', 'ku ', 		oils_i18n_gettext('1143', 'Kuwait ', 'ccvm', 'value')),
+    (1144, 'ctry', 'kv ', 		oils_i18n_gettext('1144', 'Kosovo ', 'ccvm', 'value')),
+    (1145, 'ctry', 'kyu', 		oils_i18n_gettext('1145', 'Kentucky ', 'ccvm', 'value')),
+    (1146, 'ctry', 'kz ', 		oils_i18n_gettext('1146', 'Kazakhstan ', 'ccvm', 'value')),
+    (1147, 'ctry', 'lau', 		oils_i18n_gettext('1147', 'Louisiana ', 'ccvm', 'value')),
+    (1148, 'ctry', 'lb ', 		oils_i18n_gettext('1148', 'Liberia ', 'ccvm', 'value')),
+    (1149, 'ctry', 'le ', 		oils_i18n_gettext('1149', 'Lebanon ', 'ccvm', 'value')),
+    (1150, 'ctry', 'lh ', 		oils_i18n_gettext('1150', 'Liechtenstein ', 'ccvm', 'value')),
+    (1151, 'ctry', 'li ', 		oils_i18n_gettext('1151', 'Lithuania ', 'ccvm', 'value')),
+    (1152, 'ctry', 'lo ', 		oils_i18n_gettext('1152', 'Lesotho ', 'ccvm', 'value')),
+    (1153, 'ctry', 'ls ', 		oils_i18n_gettext('1153', 'Laos ', 'ccvm', 'value')),
+    (1154, 'ctry', 'lu ', 		oils_i18n_gettext('1154', 'Luxembourg ', 'ccvm', 'value')),
+    (1155, 'ctry', 'lv ', 		oils_i18n_gettext('1155', 'Latvia ', 'ccvm', 'value')),
+    (1156, 'ctry', 'ly ', 		oils_i18n_gettext('1156', 'Libya ', 'ccvm', 'value')),
+    (1157, 'ctry', 'mau', 		oils_i18n_gettext('1157', 'Massachusetts ', 'ccvm', 'value')),
+    (1158, 'ctry', 'mbc', 		oils_i18n_gettext('1158', 'Manitoba ', 'ccvm', 'value')),
+    (1159, 'ctry', 'mc ', 		oils_i18n_gettext('1159', 'Monaco ', 'ccvm', 'value')),
+    (1160, 'ctry', 'mdu', 		oils_i18n_gettext('1160', 'Maryland ', 'ccvm', 'value')),
+    (1161, 'ctry', 'meu', 		oils_i18n_gettext('1161', 'Maine ', 'ccvm', 'value')),
+    (1162, 'ctry', 'mf ', 		oils_i18n_gettext('1162', 'Mauritius ', 'ccvm', 'value')),
+    (1163, 'ctry', 'mg ', 		oils_i18n_gettext('1163', 'Madagascar ', 'ccvm', 'value')),
+    (1164, 'ctry', 'miu', 		oils_i18n_gettext('1164', 'Michigan ', 'ccvm', 'value')),
+    (1165, 'ctry', 'mj ', 		oils_i18n_gettext('1165', 'Montserrat ', 'ccvm', 'value')),
+    (1166, 'ctry', 'mk ', 		oils_i18n_gettext('1166', 'Oman ', 'ccvm', 'value')),
+    (1167, 'ctry', 'ml ', 		oils_i18n_gettext('1167', 'Mali ', 'ccvm', 'value')),
+    (1168, 'ctry', 'mm ', 		oils_i18n_gettext('1168', 'Malta ', 'ccvm', 'value')),
+    (1169, 'ctry', 'mnu', 		oils_i18n_gettext('1169', 'Minnesota ', 'ccvm', 'value')),
+    (1170, 'ctry', 'mo ', 		oils_i18n_gettext('1170', 'Montenegro ', 'ccvm', 'value')),
+    (1171, 'ctry', 'mou', 		oils_i18n_gettext('1171', 'Missouri ', 'ccvm', 'value')),
+    (1172, 'ctry', 'mp ', 		oils_i18n_gettext('1172', 'Mongolia ', 'ccvm', 'value')),
+    (1173, 'ctry', 'mq ', 		oils_i18n_gettext('1173', 'Martinique ', 'ccvm', 'value')),
+    (1174, 'ctry', 'mr ', 		oils_i18n_gettext('1174', 'Morocco ', 'ccvm', 'value')),
+    (1175, 'ctry', 'msu', 		oils_i18n_gettext('1175', 'Mississippi ', 'ccvm', 'value')),
+    (1176, 'ctry', 'mtu', 		oils_i18n_gettext('1176', 'Montana ', 'ccvm', 'value')),
+    (1177, 'ctry', 'mu ', 		oils_i18n_gettext('1177', 'Mauritania ', 'ccvm', 'value')),
+    (1178, 'ctry', 'mv ', 		oils_i18n_gettext('1178', 'Moldova ', 'ccvm', 'value')),
+    (1179, 'ctry', 'mw ', 		oils_i18n_gettext('1179', 'Malawi ', 'ccvm', 'value')),
+    (1180, 'ctry', 'mx ', 		oils_i18n_gettext('1180', 'Mexico ', 'ccvm', 'value')),
+    (1181, 'ctry', 'my ', 		oils_i18n_gettext('1181', 'Malaysia ', 'ccvm', 'value')),
+    (1182, 'ctry', 'mz ', 		oils_i18n_gettext('1182', 'Mozambique ', 'ccvm', 'value')),
+    (1183, 'ctry', 'nbu', 		oils_i18n_gettext('1183', 'Nebraska ', 'ccvm', 'value')),
+    (1184, 'ctry', 'ncu', 		oils_i18n_gettext('1184', 'North Carolina ', 'ccvm', 'value')),
+    (1185, 'ctry', 'ndu', 		oils_i18n_gettext('1185', 'North Dakota ', 'ccvm', 'value')),
+    (1186, 'ctry', 'ne ', 		oils_i18n_gettext('1186', 'Netherlands ', 'ccvm', 'value')),
+    (1187, 'ctry', 'nfc', 		oils_i18n_gettext('1187', 'Newfoundland and Labrador ', 'ccvm', 'value')),
+    (1188, 'ctry', 'ng ', 		oils_i18n_gettext('1188', 'Niger ', 'ccvm', 'value')),
+    (1189, 'ctry', 'nhu', 		oils_i18n_gettext('1189', 'New Hampshire ', 'ccvm', 'value')),
+    (1190, 'ctry', 'nik', 		oils_i18n_gettext('1190', 'Northern Ireland ', 'ccvm', 'value')),
+    (1191, 'ctry', 'nju', 		oils_i18n_gettext('1191', 'New Jersey ', 'ccvm', 'value')),
+    (1192, 'ctry', 'nkc', 		oils_i18n_gettext('1192', 'New Brunswick ', 'ccvm', 'value')),
+    (1193, 'ctry', 'nl ', 		oils_i18n_gettext('1193', 'New Caledonia ', 'ccvm', 'value')),
+    (1194, 'ctry', 'nmu', 		oils_i18n_gettext('1194', 'New Mexico ', 'ccvm', 'value')),
+    (1195, 'ctry', 'nn ', 		oils_i18n_gettext('1195', 'Vanuatu ', 'ccvm', 'value')),
+    (1196, 'ctry', 'no ', 		oils_i18n_gettext('1196', 'Norway ', 'ccvm', 'value')),
+    (1197, 'ctry', 'np ', 		oils_i18n_gettext('1197', 'Nepal ', 'ccvm', 'value')),
+    (1198, 'ctry', 'nq ', 		oils_i18n_gettext('1198', 'Nicaragua ', 'ccvm', 'value')),
+    (1199, 'ctry', 'nr ', 		oils_i18n_gettext('1199', 'Nigeria ', 'ccvm', 'value')),
+    (1200, 'ctry', 'nsc', 		oils_i18n_gettext('1200', 'Nova Scotia ', 'ccvm', 'value')),
+    (1201, 'ctry', 'ntc', 		oils_i18n_gettext('1201', 'Northwest Territories ', 'ccvm', 'value')),
+    (1202, 'ctry', 'nu ', 		oils_i18n_gettext('1202', 'Nauru ', 'ccvm', 'value')),
+    (1203, 'ctry', 'nuc', 		oils_i18n_gettext('1203', 'Nunavut ', 'ccvm', 'value')),
+    (1204, 'ctry', 'nvu', 		oils_i18n_gettext('1204', 'Nevada ', 'ccvm', 'value')),
+    (1205, 'ctry', 'nw ', 		oils_i18n_gettext('1205', 'Northern Mariana Islands ', 'ccvm', 'value')),
+    (1206, 'ctry', 'nx ', 		oils_i18n_gettext('1206', 'Norfolk Island ', 'ccvm', 'value')),
+    (1207, 'ctry', 'nyu', 		oils_i18n_gettext('1207', 'New York (State) ', 'ccvm', 'value')),
+    (1208, 'ctry', 'nz ', 		oils_i18n_gettext('1208', 'New Zealand ', 'ccvm', 'value')),
+    (1209, 'ctry', 'ohu', 		oils_i18n_gettext('1209', 'Ohio ', 'ccvm', 'value')),
+    (1210, 'ctry', 'oku', 		oils_i18n_gettext('1210', 'Oklahoma ', 'ccvm', 'value')),
+    (1211, 'ctry', 'onc', 		oils_i18n_gettext('1211', 'Ontario ', 'ccvm', 'value')),
+    (1212, 'ctry', 'oru', 		oils_i18n_gettext('1212', 'Oregon ', 'ccvm', 'value')),
+    (1213, 'ctry', 'ot ', 		oils_i18n_gettext('1213', 'Mayotte ', 'ccvm', 'value')),
+    (1214, 'ctry', 'pau', 		oils_i18n_gettext('1214', 'Pennsylvania ', 'ccvm', 'value')),
+    (1215, 'ctry', 'pc ', 		oils_i18n_gettext('1215', 'Pitcairn Island ', 'ccvm', 'value')),
+    (1216, 'ctry', 'pe ', 		oils_i18n_gettext('1216', 'Peru ', 'ccvm', 'value')),
+    (1217, 'ctry', 'pf ', 		oils_i18n_gettext('1217', 'Paracel Islands ', 'ccvm', 'value')),
+    (1218, 'ctry', 'pg ', 		oils_i18n_gettext('1218', 'Guinea', 'ccvm', 'value')),
+    (1219, 'ctry', 'ph ', 		oils_i18n_gettext('1219', 'Philippines ', 'ccvm', 'value')),
+    (1220, 'ctry', 'pic', 		oils_i18n_gettext('1220', 'Prince Edward Island ', 'ccvm', 'value')),
+    (1221, 'ctry', 'pk ', 		oils_i18n_gettext('1221', 'Pakistan ', 'ccvm', 'value')),
+    (1222, 'ctry', 'pl ', 		oils_i18n_gettext('1222', 'Poland ', 'ccvm', 'value')),
+    (1223, 'ctry', 'pn ', 		oils_i18n_gettext('1223', 'Panama ', 'ccvm', 'value')),
+    (1224, 'ctry', 'po ', 		oils_i18n_gettext('1224', 'Portugal ', 'ccvm', 'value')),
+    (1225, 'ctry', 'pp ', 		oils_i18n_gettext('1225', 'Papua New Guinea ', 'ccvm', 'value')),
+    (1226, 'ctry', 'pr ', 		oils_i18n_gettext('1226', 'Puerto Rico ', 'ccvm', 'value')),
+    (1227, 'ctry', 'pw ', 		oils_i18n_gettext('1227', 'Palau ', 'ccvm', 'value')),
+    (1228, 'ctry', 'py ', 		oils_i18n_gettext('1228', 'Paraguay ', 'ccvm', 'value')),
+    (1229, 'ctry', 'qa ', 		oils_i18n_gettext('1229', 'Qatar ', 'ccvm', 'value')),
+    (1230, 'ctry', 'qea', 		oils_i18n_gettext('1230', 'Queensland ', 'ccvm', 'value')),
+    (1231, 'ctry', 'quc', 		oils_i18n_gettext('1231', 'Québec (Province) ', 'ccvm', 'value')),
+    (1232, 'ctry', 'rb ', 		oils_i18n_gettext('1232', 'Serbia ', 'ccvm', 'value')),
+    (1233, 'ctry', 're ', 		oils_i18n_gettext('1233', 'Réunion ', 'ccvm', 'value')),
+    (1234, 'ctry', 'rh ', 		oils_i18n_gettext('1234', 'Zimbabwe ', 'ccvm', 'value')),
+    (1235, 'ctry', 'riu', 		oils_i18n_gettext('1235', 'Rhode Island ', 'ccvm', 'value')),
+    (1236, 'ctry', 'rm ', 		oils_i18n_gettext('1236', 'Romania ', 'ccvm', 'value')),
+    (1237, 'ctry', 'ru ', 		oils_i18n_gettext('1237', 'Russia (Federation) ', 'ccvm', 'value')),
+    (1238, 'ctry', 'rw ', 		oils_i18n_gettext('1238', 'Rwanda ', 'ccvm', 'value')),
+    (1239, 'ctry', 'sa ', 		oils_i18n_gettext('1239', 'South Africa ', 'ccvm', 'value')),
+    (1240, 'ctry', 'sc ', 		oils_i18n_gettext('1240', 'Saint', 'ccvm', 'value')),
+    (1241, 'ctry', 'scu', 		oils_i18n_gettext('1241', 'South Carolina ', 'ccvm', 'value')),
+    (1242, 'ctry', 'sd ', 		oils_i18n_gettext('1242', 'South Sudan ', 'ccvm', 'value')),
+    (1243, 'ctry', 'sdu', 		oils_i18n_gettext('1243', 'South Dakota ', 'ccvm', 'value')),
+    (1244, 'ctry', 'se ', 		oils_i18n_gettext('1244', 'Seychelles ', 'ccvm', 'value')),
+    (1245, 'ctry', 'sf ', 		oils_i18n_gettext('1245', 'Sao Tome and Principe ', 'ccvm', 'value')),
+    (1246, 'ctry', 'sg ', 		oils_i18n_gettext('1246', 'Senegal ', 'ccvm', 'value')),
+    (1247, 'ctry', 'sh ', 		oils_i18n_gettext('1247', 'Spanish North Africa ', 'ccvm', 'value')),
+    (1248, 'ctry', 'si ', 		oils_i18n_gettext('1248', 'Singapore ', 'ccvm', 'value')),
+    (1249, 'ctry', 'sj ', 		oils_i18n_gettext('1249', 'Sudan ', 'ccvm', 'value')),
+    (1250, 'ctry', 'sl ', 		oils_i18n_gettext('1250', 'Sierra Leone ', 'ccvm', 'value')),
+    (1251, 'ctry', 'sm ', 		oils_i18n_gettext('1251', 'San Marino ', 'ccvm', 'value')),
+    (1252, 'ctry', 'sn ', 		oils_i18n_gettext('1252', 'Sint Maarten ', 'ccvm', 'value')),
+    (1253, 'ctry', 'snc', 		oils_i18n_gettext('1253', 'Saskatchewan ', 'ccvm', 'value')),
+    (1254, 'ctry', 'so ', 		oils_i18n_gettext('1254', 'Somalia ', 'ccvm', 'value')),
+    (1255, 'ctry', 'sp ', 		oils_i18n_gettext('1255', 'Spain ', 'ccvm', 'value')),
+    (1256, 'ctry', 'sq ', 		oils_i18n_gettext('1256', 'Swaziland ', 'ccvm', 'value')),
+    (1257, 'ctry', 'sr ', 		oils_i18n_gettext('1257', 'Surinam ', 'ccvm', 'value')),
+    (1258, 'ctry', 'ss ', 		oils_i18n_gettext('1258', 'Western Sahara ', 'ccvm', 'value')),
+    (1259, 'ctry', 'st ', 		oils_i18n_gettext('1259', 'Saint', 'ccvm', 'value')),
+    (1260, 'ctry', 'stk', 		oils_i18n_gettext('1260', 'Scotland ', 'ccvm', 'value')),
+    (1261, 'ctry', 'su ', 		oils_i18n_gettext('1261', 'Saudi Arabia ', 'ccvm', 'value')),
+    (1262, 'ctry', 'sw ', 		oils_i18n_gettext('1262', 'Sweden ', 'ccvm', 'value')),
+    (1263, 'ctry', 'sx ', 		oils_i18n_gettext('1263', 'Namibia ', 'ccvm', 'value')),
+    (1264, 'ctry', 'sy ', 		oils_i18n_gettext('1264', 'Syria ', 'ccvm', 'value')),
+    (1265, 'ctry', 'sz ', 		oils_i18n_gettext('1265', 'Switzerland ', 'ccvm', 'value')),
+    (1266, 'ctry', 'ta ', 		oils_i18n_gettext('1266', 'Tajikistan ', 'ccvm', 'value')),
+    (1267, 'ctry', 'tc ', 		oils_i18n_gettext('1267', 'Turks and Caicos Islands ', 'ccvm', 'value')),
+    (1268, 'ctry', 'tg ', 		oils_i18n_gettext('1268', 'Togo ', 'ccvm', 'value')),
+    (1269, 'ctry', 'th ', 		oils_i18n_gettext('1269', 'Thailand ', 'ccvm', 'value')),
+    (1270, 'ctry', 'ti ', 		oils_i18n_gettext('1270', 'Tunisia ', 'ccvm', 'value')),
+    (1271, 'ctry', 'tk ', 		oils_i18n_gettext('1271', 'Turkmenistan ', 'ccvm', 'value')),
+    (1272, 'ctry', 'tl ', 		oils_i18n_gettext('1272', 'Tokelau ', 'ccvm', 'value')),
+    (1273, 'ctry', 'tma', 		oils_i18n_gettext('1273', 'Tasmania ', 'ccvm', 'value')),
+    (1274, 'ctry', 'tnu', 		oils_i18n_gettext('1274', 'Tennessee ', 'ccvm', 'value')),
+    (1275, 'ctry', 'to ', 		oils_i18n_gettext('1275', 'Tonga ', 'ccvm', 'value')),
+    (1276, 'ctry', 'tr ', 		oils_i18n_gettext('1276', 'Trinidad and Tobago ', 'ccvm', 'value')),
+    (1277, 'ctry', 'ts ', 		oils_i18n_gettext('1277', 'United Arab Emirates ', 'ccvm', 'value')),
+    (1278, 'ctry', 'tu ', 		oils_i18n_gettext('1278', 'Turkey ', 'ccvm', 'value')),
+    (1279, 'ctry', 'tv ', 		oils_i18n_gettext('1279', 'Tuvalu ', 'ccvm', 'value')),
+    (1280, 'ctry', 'txu', 		oils_i18n_gettext('1280', 'Texas ', 'ccvm', 'value')),
+    (1281, 'ctry', 'tz ', 		oils_i18n_gettext('1281', 'Tanzania ', 'ccvm', 'value')),
+    (1282, 'ctry', 'ua ', 		oils_i18n_gettext('1282', 'Egypt ', 'ccvm', 'value')),
+    (1283, 'ctry', 'uc ', 		oils_i18n_gettext('1283', 'United States Misc. Caribbean Islands ', 'ccvm', 'value')),
+    (1284, 'ctry', 'ug ', 		oils_i18n_gettext('1284', 'Uganda ', 'ccvm', 'value')),
+    (1285, 'ctry', 'uik', 		oils_i18n_gettext('1285', 'United Kingdom Misc. Islands ', 'ccvm', 'value')),
+    (1286, 'ctry', 'un ', 		oils_i18n_gettext('1286', 'Ukraine ', 'ccvm', 'value')),
+    (1287, 'ctry', 'up ', 		oils_i18n_gettext('1287', 'United States Misc. Pacific Islands ', 'ccvm', 'value')),
+    (1288, 'ctry', 'utu', 		oils_i18n_gettext('1288', 'Utah ', 'ccvm', 'value')),
+    (1289, 'ctry', 'uv ', 		oils_i18n_gettext('1289', 'Burkina Faso ', 'ccvm', 'value')),
+    (1290, 'ctry', 'uy ', 		oils_i18n_gettext('1290', 'Uruguay ', 'ccvm', 'value')),
+    (1291, 'ctry', 'uz ', 		oils_i18n_gettext('1291', 'Uzbekistan ', 'ccvm', 'value')),
+    (1292, 'ctry', 'vau', 		oils_i18n_gettext('1292', 'Virginia ', 'ccvm', 'value')),
+    (1293, 'ctry', 'vb ', 		oils_i18n_gettext('1293', 'British Virgin Islands ', 'ccvm', 'value')),
+    (1294, 'ctry', 'vc ', 		oils_i18n_gettext('1294', 'Vatican City ', 'ccvm', 'value')),
+    (1295, 'ctry', 've ', 		oils_i18n_gettext('1295', 'Venezuela ', 'ccvm', 'value')),
+    (1296, 'ctry', 'vi ', 		oils_i18n_gettext('1296', 'Virgin Islands of the United States ', 'ccvm', 'value')),
+    (1297, 'ctry', 'vm ', 		oils_i18n_gettext('1297', 'Vietnam ', 'ccvm', 'value')),
+    (1298, 'ctry', 'vp ', 		oils_i18n_gettext('1298', 'Various places ', 'ccvm', 'value')),
+    (1299, 'ctry', 'vra', 		oils_i18n_gettext('1299', 'Victoria ', 'ccvm', 'value')),
+    (1300, 'ctry', 'vtu', 		oils_i18n_gettext('1300', 'Vermont ', 'ccvm', 'value')),
+    (1301, 'ctry', 'wau', 		oils_i18n_gettext('1301', 'Washington (State) ', 'ccvm', 'value')),
+    (1302, 'ctry', 'wea', 		oils_i18n_gettext('1302', 'Western Australia ', 'ccvm', 'value')),
+    (1303, 'ctry', 'wf ', 		oils_i18n_gettext('1303', 'Wallis and Futuna ', 'ccvm', 'value')),
+    (1304, 'ctry', 'wiu', 		oils_i18n_gettext('1304', 'Wisconsin ', 'ccvm', 'value')),
+    (1305, 'ctry', 'wj ', 		oils_i18n_gettext('1305', 'West Bank of the Jordan River ', 'ccvm', 'value')),
+    (1306, 'ctry', 'wk ', 		oils_i18n_gettext('1306', 'Wake Island ', 'ccvm', 'value')),
+    (1307, 'ctry', 'wlk', 		oils_i18n_gettext('1307', 'Wales ', 'ccvm', 'value')),
+    (1308, 'ctry', 'ws ', 		oils_i18n_gettext('1308', 'Samoa ', 'ccvm', 'value')),
+    (1309, 'ctry', 'wvu', 		oils_i18n_gettext('1309', 'West Virginia ', 'ccvm', 'value')),
+    (1310, 'ctry', 'wyu', 		oils_i18n_gettext('1310', 'Wyoming ', 'ccvm', 'value')),
+    (1311, 'ctry', 'xa ', 		oils_i18n_gettext('1311', 'Christmas Island (Indian Ocean) ', 'ccvm', 'value')),
+    (1312, 'ctry', 'xb ', 		oils_i18n_gettext('1312', 'Cocos (Keeling) Islands ', 'ccvm', 'value')),
+    (1313, 'ctry', 'xc ', 		oils_i18n_gettext('1313', 'Maldives ', 'ccvm', 'value')),
+    (1314, 'ctry', 'xd ', 		oils_i18n_gettext('1314', 'Saint Kitts', 'ccvm', 'value')),
+    (1315, 'ctry', 'xe ', 		oils_i18n_gettext('1315', 'Marshall Islands ', 'ccvm', 'value')),
+    (1316, 'ctry', 'xf ', 		oils_i18n_gettext('1316', 'Midway Islands ', 'ccvm', 'value')),
+    (1317, 'ctry', 'xga', 		oils_i18n_gettext('1317', 'Coral Sea Islands Territory ', 'ccvm', 'value')),
+    (1318, 'ctry', 'xh ', 		oils_i18n_gettext('1318', 'Niue ', 'ccvm', 'value')),
+    (1319, 'ctry', 'xj ', 		oils_i18n_gettext('1319', 'Saint Helena ', 'ccvm', 'value')),
+    (1320, 'ctry', 'xk ', 		oils_i18n_gettext('1320', 'Saint Lucia ', 'ccvm', 'value')),
+    (1321, 'ctry', 'xl ', 		oils_i18n_gettext('1321', 'Saint Pierre and Miquelon ', 'ccvm', 'value')),
+    (1322, 'ctry', 'xm ', 		oils_i18n_gettext('1322', 'Saint Vincent and the Grenadines ', 'ccvm', 'value')),
+    (1323, 'ctry', 'xn ', 		oils_i18n_gettext('1323', 'Macedonia ', 'ccvm', 'value')),
+    (1324, 'ctry', 'xna', 		oils_i18n_gettext('1324', 'New South Wales ', 'ccvm', 'value')),
+    (1325, 'ctry', 'xo ', 		oils_i18n_gettext('1325', 'Slovakia ', 'ccvm', 'value')),
+    (1326, 'ctry', 'xoa', 		oils_i18n_gettext('1326', 'Northern Territory ', 'ccvm', 'value')),
+    (1327, 'ctry', 'xp ', 		oils_i18n_gettext('1327', 'Spratly Island ', 'ccvm', 'value')),
+    (1328, 'ctry', 'xr ', 		oils_i18n_gettext('1328', 'Czech Republic ', 'ccvm', 'value')),
+    (1329, 'ctry', 'xra', 		oils_i18n_gettext('1329', 'South Australia ', 'ccvm', 'value')),
+    (1330, 'ctry', 'xs ', 		oils_i18n_gettext('1330', 'South Georgia and the South Sandwich Islands ', 'ccvm', 'value')),
+    (1331, 'ctry', 'xv ', 		oils_i18n_gettext('1331', 'Slovenia ', 'ccvm', 'value')),
+    (1332, 'ctry', 'xx ', 		oils_i18n_gettext('1332', 'No place, unknown, or undetermined ', 'ccvm', 'value')),
+    (1333, 'ctry', 'xxc', 		oils_i18n_gettext('1333', 'Canada ', 'ccvm', 'value')),
+    (1334, 'ctry', 'xxk', 		oils_i18n_gettext('1334', 'United Kingdom ', 'ccvm', 'value')),
+    (1335, 'ctry', 'xxu', 		oils_i18n_gettext('1335', 'United States ', 'ccvm', 'value')),
+    (1336, 'ctry', 'ye ', 		oils_i18n_gettext('1336', 'Yemen ', 'ccvm', 'value')),
+    (1337, 'ctry', 'ykc', 		oils_i18n_gettext('1337', 'Yukon Territory ', 'ccvm', 'value')),
+    (1338, 'ctry', 'za ', 		oils_i18n_gettext('1338', 'Zambia ', 'ccvm', 'value')),
+	
+    (1339, 'pub_status', 'b', 	oils_i18n_gettext('1339', 'No dates given; B.C. date involved', 'ccvm', 'value')),
+    (1340, 'pub_status', 'c', 	oils_i18n_gettext('1340', 'Continuing resource currently published', 'ccvm', 'value')),
+    (1341, 'pub_status', 'd', 	oils_i18n_gettext('1341', 'Continuing resource ceased publication', 'ccvm', 'value')),
+    (1342, 'pub_status', 'e', 	oils_i18n_gettext('1342', 'Detailed date', 'ccvm', 'value')),
+    (1343, 'pub_status', 'i', 	oils_i18n_gettext('1343', 'Inclusive dates of collection', 'ccvm', 'value')),
+    (1344, 'pub_status', 'k', 	oils_i18n_gettext('1344', 'Range of years of bulk of collection', 'ccvm', 'value')),
+    (1345, 'pub_status', 'm', 	oils_i18n_gettext('1345', 'Multiple dates', 'ccvm', 'value')),
+    (1346, 'pub_status', 'n', 	oils_i18n_gettext('1346', 'Dates unknown', 'ccvm', 'value')),
+    (1347, 'pub_status', 'p', 	oils_i18n_gettext('1347', 'Date of distribution/release/issue and production/recording session when different', 'ccvm', 'value')),
+    (1348, 'pub_status', 'q', 	oils_i18n_gettext('1348', 'Questionable date', 'ccvm', 'value')),
+    (1349, 'pub_status', 'r', 	oils_i18n_gettext('1349', 'Reprint/reissue date and original date', 'ccvm', 'value')),
+    (1350, 'pub_status', 's', 	oils_i18n_gettext('1350', 'Single known date/probable date', 'ccvm', 'value')),
+    (1351, 'pub_status', 't', 	oils_i18n_gettext('1351', 'Publication date and copyright date', 'ccvm', 'value')),
+    (1352, 'pub_status', 'u', 	oils_i18n_gettext('1352', 'Continuing resource status unknown', 'ccvm', 'value'));
+	
+
+-- These are fixed fields that are made up of multiple single-character codes. These are the actual fields that are used to define relevent attributes,
+-- the "unnumbered" version of these fields are used for the MARC editor and as composite attributes for use in the OPAC if desired.
+-- i18n ids are left as-is because there's no need to have multiple translations for the same value.
+-- The ' ' codes only apply to the first position because if there's anything in pos 1 then the rest of the spaces are just filler.
+-- There's also no need for them to be opac visible because there will be composite attributes that OR these numbered attributes together.
+INSERT INTO config.coded_value_map (id, ctype, code, value, opac_visible) VALUES
+    (1353, 'accm1', ' ', 	oils_i18n_gettext('1735', 'No accompanying matter', 'ccvm', 'value'), FALSE),
+    (1354, 'accm1', 'a', 	oils_i18n_gettext('713', 'Discography', 'ccvm', 'value'), FALSE),
+    (1355, 'accm1', 'b', 	oils_i18n_gettext('714', 'Bibliography', 'ccvm', 'value'), FALSE),
+    (1356, 'accm1', 'c', 	oils_i18n_gettext('715', 'Thematic index', 'ccvm', 'value'), FALSE),
+    (1357, 'accm1', 'd', 	oils_i18n_gettext('716', 'Libretto or text', 'ccvm', 'value'), FALSE),
+    (1358, 'accm1', 'e', 	oils_i18n_gettext('717', 'Biography of composer or author', 'ccvm', 'value'), FALSE),
+    (1359, 'accm1', 'f', 	oils_i18n_gettext('718', 'Biography or performer or history of ensemble', 'ccvm', 'value'), FALSE),
+    (1360, 'accm1', 'g', 	oils_i18n_gettext('719', 'Technical and/or historical information on instruments', 'ccvm', 'value'), FALSE),
+    (1361, 'accm1', 'h', 	oils_i18n_gettext('720', 'Technical information on music', 'ccvm', 'value'), FALSE),
+    (1362, 'accm1', 'i', 	oils_i18n_gettext('721', 'Historical information', 'ccvm', 'value'), FALSE),
+    (1363, 'accm1', 'k', 	oils_i18n_gettext('722', 'Ethnological information', 'ccvm', 'value'), FALSE),
+    (1364, 'accm1', 'r', 	oils_i18n_gettext('723', 'Instructional materials', 'ccvm', 'value'), FALSE),
+    (1365, 'accm1', 's', 	oils_i18n_gettext('724', 'Music', 'ccvm', 'value'), FALSE),
+    (1366, 'accm1', 'z', 	oils_i18n_gettext('725', 'Other accompanying matter', 'ccvm', 'value'), FALSE),
+	
+    (1367, 'accm2', 'a', 	oils_i18n_gettext('713', 'Discography', 'ccvm', 'value'), FALSE),
+    (1368, 'accm2', 'b', 	oils_i18n_gettext('714', 'Bibliography', 'ccvm', 'value'), FALSE),
+    (1369, 'accm2', 'c', 	oils_i18n_gettext('715', 'Thematic index', 'ccvm', 'value'), FALSE),
+    (1370, 'accm2', 'd', 	oils_i18n_gettext('716', 'Libretto or text', 'ccvm', 'value'), FALSE),
+    (1371, 'accm2', 'e', 	oils_i18n_gettext('717', 'Biography of composer or author', 'ccvm', 'value'), FALSE),
+    (1372, 'accm2', 'f', 	oils_i18n_gettext('718', 'Biography or performer or history of ensemble', 'ccvm', 'value'), FALSE),
+    (1373, 'accm2', 'g', 	oils_i18n_gettext('719', 'Technical and/or historical information on instruments', 'ccvm', 'value'), FALSE),
+    (1374, 'accm2', 'h', 	oils_i18n_gettext('720', 'Technical information on music', 'ccvm', 'value'), FALSE),
+    (1375, 'accm2', 'i', 	oils_i18n_gettext('721', 'Historical information', 'ccvm', 'value'), FALSE),
+    (1376, 'accm2', 'k', 	oils_i18n_gettext('722', 'Ethnological information', 'ccvm', 'value'), FALSE),
+    (1377, 'accm2', 'r', 	oils_i18n_gettext('723', 'Instructional materials', 'ccvm', 'value'), FALSE),
+    (1378, 'accm2', 's', 	oils_i18n_gettext('724', 'Music', 'ccvm', 'value'), FALSE),
+    (1379, 'accm2', 'z', 	oils_i18n_gettext('725', 'Other accompanying matter', 'ccvm', 'value'), FALSE),
+	
+    (1380, 'accm3', 'a', 	oils_i18n_gettext('713', 'Discography', 'ccvm', 'value'), FALSE),
+    (1381, 'accm3', 'b', 	oils_i18n_gettext('714', 'Bibliography', 'ccvm', 'value'), FALSE),
+    (1382, 'accm3', 'c', 	oils_i18n_gettext('715', 'Thematic index', 'ccvm', 'value'), FALSE),
+    (1383, 'accm3', 'd', 	oils_i18n_gettext('716', 'Libretto or text', 'ccvm', 'value'), FALSE),
+    (1384, 'accm3', 'e', 	oils_i18n_gettext('717', 'Biography of composer or author', 'ccvm', 'value'), FALSE),
+    (1385, 'accm3', 'f', 	oils_i18n_gettext('718', 'Biography or performer or history of ensemble', 'ccvm', 'value'), FALSE),
+    (1386, 'accm3', 'g', 	oils_i18n_gettext('719', 'Technical and/or historical information on instruments', 'ccvm', 'value'), FALSE),
+    (1387, 'accm3', 'h', 	oils_i18n_gettext('720', 'Technical information on music', 'ccvm', 'value'), FALSE),
+    (1388, 'accm3', 'i', 	oils_i18n_gettext('721', 'Historical information', 'ccvm', 'value'), FALSE),
+    (1389, 'accm3', 'k', 	oils_i18n_gettext('722', 'Ethnological information', 'ccvm', 'value'), FALSE),
+    (1390, 'accm3', 'r', 	oils_i18n_gettext('723', 'Instructional materials', 'ccvm', 'value'), FALSE),
+    (1391, 'accm3', 's', 	oils_i18n_gettext('724', 'Music', 'ccvm', 'value'), FALSE),
+    (1392, 'accm3', 'z', 	oils_i18n_gettext('725', 'Other accompanying matter', 'ccvm', 'value'), FALSE),
+	
+    (1393, 'accm4', 'a', 	oils_i18n_gettext('713', 'Discography', 'ccvm', 'value'), FALSE),
+    (1394, 'accm4', 'b', 	oils_i18n_gettext('714', 'Bibliography', 'ccvm', 'value'), FALSE),
+    (1395, 'accm4', 'c', 	oils_i18n_gettext('715', 'Thematic index', 'ccvm', 'value'), FALSE),
+    (1396, 'accm4', 'd', 	oils_i18n_gettext('716', 'Libretto or text', 'ccvm', 'value'), FALSE),
+    (1397, 'accm4', 'e', 	oils_i18n_gettext('717', 'Biography of composer or author', 'ccvm', 'value'), FALSE),
+    (1398, 'accm4', 'f', 	oils_i18n_gettext('718', 'Biography or performer or history of ensemble', 'ccvm', 'value'), FALSE),
+    (1399, 'accm4', 'g', 	oils_i18n_gettext('719', 'Technical and/or historical information on instruments', 'ccvm', 'value'), FALSE),
+    (1400, 'accm4', 'h', 	oils_i18n_gettext('720', 'Technical information on music', 'ccvm', 'value'), FALSE),
+    (1401, 'accm4', 'i', 	oils_i18n_gettext('721', 'Historical information', 'ccvm', 'value'), FALSE),
+    (1402, 'accm4', 'k', 	oils_i18n_gettext('722', 'Ethnological information', 'ccvm', 'value'), FALSE),
+    (1403, 'accm4', 'r', 	oils_i18n_gettext('723', 'Instructional materials', 'ccvm', 'value'), FALSE),
+    (1404, 'accm4', 's', 	oils_i18n_gettext('724', 'Music', 'ccvm', 'value'), FALSE),
+    (1405, 'accm4', 'z', 	oils_i18n_gettext('725', 'Other accompanying matter', 'ccvm', 'value'), FALSE),
+	
+    (1406, 'accm5', 'a', 	oils_i18n_gettext('713', 'Discography', 'ccvm', 'value'), FALSE),
+    (1407, 'accm5', 'b', 	oils_i18n_gettext('714', 'Bibliography', 'ccvm', 'value'), FALSE),
+    (1408, 'accm5', 'c', 	oils_i18n_gettext('715', 'Thematic index', 'ccvm', 'value'), FALSE),
+    (1409, 'accm5', 'd', 	oils_i18n_gettext('716', 'Libretto or text', 'ccvm', 'value'), FALSE),
+    (1410, 'accm5', 'e', 	oils_i18n_gettext('717', 'Biography of composer or author', 'ccvm', 'value'), FALSE),
+    (1411, 'accm5', 'f', 	oils_i18n_gettext('718', 'Biography or performer or history of ensemble', 'ccvm', 'value'), FALSE),
+    (1412, 'accm5', 'g', 	oils_i18n_gettext('719', 'Technical and/or historical information on instruments', 'ccvm', 'value'), FALSE),
+    (1413, 'accm5', 'h', 	oils_i18n_gettext('720', 'Technical information on music', 'ccvm', 'value'), FALSE),
+    (1414, 'accm5', 'i', 	oils_i18n_gettext('721', 'Historical information', 'ccvm', 'value'), FALSE),
+    (1415, 'accm5', 'k', 	oils_i18n_gettext('722', 'Ethnological information', 'ccvm', 'value'), FALSE),
+    (1416, 'accm5', 'r', 	oils_i18n_gettext('723', 'Instructional materials', 'ccvm', 'value'), FALSE),
+    (1417, 'accm5', 's', 	oils_i18n_gettext('724', 'Music', 'ccvm', 'value'), FALSE),
+    (1418, 'accm5', 'z', 	oils_i18n_gettext('725', 'Other accompanying matter', 'ccvm', 'value'), FALSE),
+	
+    (1419, 'accm6', 'a', 	oils_i18n_gettext('713', 'Discography', 'ccvm', 'value'), FALSE),
+    (1420, 'accm6', 'b', 	oils_i18n_gettext('714', 'Bibliography', 'ccvm', 'value'), FALSE),
+    (1421, 'accm6', 'c', 	oils_i18n_gettext('715', 'Thematic index', 'ccvm', 'value'), FALSE),
+    (1422, 'accm6', 'd', 	oils_i18n_gettext('716', 'Libretto or text', 'ccvm', 'value'), FALSE),
+    (1423, 'accm6', 'e', 	oils_i18n_gettext('717', 'Biography of composer or author', 'ccvm', 'value'), FALSE),
+    (1424, 'accm6', 'f', 	oils_i18n_gettext('718', 'Biography or performer or history of ensemble', 'ccvm', 'value'), FALSE),
+    (1425, 'accm6', 'g', 	oils_i18n_gettext('719', 'Technical and/or historical information on instruments', 'ccvm', 'value'), FALSE),
+    (1426, 'accm6', 'h', 	oils_i18n_gettext('720', 'Technical information on music', 'ccvm', 'value'), FALSE),
+    (1427, 'accm6', 'i', 	oils_i18n_gettext('721', 'Historical information', 'ccvm', 'value'), FALSE),
+    (1428, 'accm6', 'k', 	oils_i18n_gettext('722', 'Ethnological information', 'ccvm', 'value'), FALSE),
+    (1429, 'accm6', 'r', 	oils_i18n_gettext('723', 'Instructional materials', 'ccvm', 'value'), FALSE),
+    (1430, 'accm6', 's', 	oils_i18n_gettext('724', 'Music', 'ccvm', 'value'), FALSE),
+    (1431, 'accm6', 'z', 	oils_i18n_gettext('725', 'Other accompanying matter', 'ccvm', 'value'), FALSE),
+	
+    (1432, 'cont1', ' ', 	oils_i18n_gettext('835', 'Not specified', 'ccvm', 'value'), FALSE),
+    (1433, 'cont1', 'a', 	oils_i18n_gettext('836', 'Abstracts/summaries', 'ccvm', 'value'), FALSE),
+    (1434, 'cont1', 'b', 	oils_i18n_gettext('837', 'Bibliographies', 'ccvm', 'value'), FALSE),
+    (1435, 'cont1', 'c', 	oils_i18n_gettext('838', 'Catalogs', 'ccvm', 'value'), FALSE),
+    (1436, 'cont1', 'd', 	oils_i18n_gettext('839', 'Dictionaries', 'ccvm', 'value'), FALSE),
+    (1437, 'cont1', 'e', 	oils_i18n_gettext('840', 'Encyclopedias', 'ccvm', 'value'), FALSE),
+    (1438, 'cont1', 'f', 	oils_i18n_gettext('841', 'Handbooks', 'ccvm', 'value'), FALSE),
+    (1439, 'cont1', 'g', 	oils_i18n_gettext('842', 'Legal articles', 'ccvm', 'value'), FALSE),
+    (1440, 'cont1', 'h', 	oils_i18n_gettext('843', 'Biography', 'ccvm', 'value'), FALSE),
+    (1441, 'cont1', 'i', 	oils_i18n_gettext('844', 'Indexes', 'ccvm', 'value'), FALSE),
+    (1442, 'cont1', 'j', 	oils_i18n_gettext('845', 'Patent document', 'ccvm', 'value'), FALSE),
+    (1443, 'cont1', 'k', 	oils_i18n_gettext('846', 'Discographies', 'ccvm', 'value'), FALSE),
+    (1444, 'cont1', 'l', 	oils_i18n_gettext('847', 'Legislation', 'ccvm', 'value'), FALSE),
+    (1445, 'cont1', 'm', 	oils_i18n_gettext('848', 'Theses', 'ccvm', 'value'), FALSE),
+    (1446, 'cont1', 'n', 	oils_i18n_gettext('849', 'Surveys of the literature in a subject area', 'ccvm', 'value'), FALSE),
+    (1447, 'cont1', 'o', 	oils_i18n_gettext('850', 'Reviews', 'ccvm', 'value'), FALSE),
+    (1448, 'cont1', 'p', 	oils_i18n_gettext('851', 'Programmed texts', 'ccvm', 'value'), FALSE),
+    (1449, 'cont1', 'q', 	oils_i18n_gettext('852', 'Filmographies', 'ccvm', 'value'), FALSE),
+    (1450, 'cont1', 'r', 	oils_i18n_gettext('853', 'Directories', 'ccvm', 'value'), FALSE),
+    (1451, 'cont1', 's', 	oils_i18n_gettext('854', 'Statistics', 'ccvm', 'value'), FALSE),
+    (1452, 'cont1', 't', 	oils_i18n_gettext('855', 'Technical reports', 'ccvm', 'value'), FALSE),
+    (1453, 'cont1', 'u', 	oils_i18n_gettext('856', 'Standards/specifications', 'ccvm', 'value'), FALSE),
+    (1454, 'cont1', 'v', 	oils_i18n_gettext('857', 'Legal cases and case notes', 'ccvm', 'value'), FALSE),
+    (1455, 'cont1', 'w', 	oils_i18n_gettext('858', 'Law reports and digests', 'ccvm', 'value'), FALSE),
+    (1456, 'cont1', 'x', 	oils_i18n_gettext('859', 'Other reports', 'ccvm', 'value'), FALSE),
+    (1457, 'cont1', 'y', 	oils_i18n_gettext('860', 'Yearbooks', 'ccvm', 'value'), FALSE),
+    (1458, 'cont1', 'z', 	oils_i18n_gettext('861', 'Treaties', 'ccvm', 'value'), FALSE),
+    (1459, 'cont1', '2', 	oils_i18n_gettext('862', 'Offprints', 'ccvm', 'value'), FALSE),
+    (1460, 'cont1', '5', 	oils_i18n_gettext('863', 'Calendars', 'ccvm', 'value'), FALSE),
+    (1461, 'cont1', '6', 	oils_i18n_gettext('864', 'Comics/graphic novels', 'ccvm', 'value'), FALSE),
+	
+    (1462, 'cont2', 'a', 	oils_i18n_gettext('836', 'Abstracts/summaries', 'ccvm', 'value'), FALSE),
+    (1463, 'cont2', 'b', 	oils_i18n_gettext('837', 'Bibliographies', 'ccvm', 'value'), FALSE),
+    (1464, 'cont2', 'c', 	oils_i18n_gettext('838', 'Catalogs', 'ccvm', 'value'), FALSE),
+    (1465, 'cont2', 'd', 	oils_i18n_gettext('839', 'Dictionaries', 'ccvm', 'value'), FALSE),
+    (1466, 'cont2', 'e', 	oils_i18n_gettext('840', 'Encyclopedias', 'ccvm', 'value'), FALSE),
+    (1467, 'cont2', 'f', 	oils_i18n_gettext('841', 'Handbooks', 'ccvm', 'value'), FALSE),
+    (1468, 'cont2', 'g', 	oils_i18n_gettext('842', 'Legal articles', 'ccvm', 'value'), FALSE),
+    (1469, 'cont2', 'h', 	oils_i18n_gettext('843', 'Biography', 'ccvm', 'value'), FALSE),
+    (1470, 'cont2', 'i', 	oils_i18n_gettext('844', 'Indexes', 'ccvm', 'value'), FALSE),
+    (1471, 'cont2', 'j', 	oils_i18n_gettext('845', 'Patent document', 'ccvm', 'value'), FALSE),
+    (1472, 'cont2', 'k', 	oils_i18n_gettext('846', 'Discographies', 'ccvm', 'value'), FALSE),
+    (1473, 'cont2', 'l', 	oils_i18n_gettext('847', 'Legislation', 'ccvm', 'value'), FALSE),
+    (1474, 'cont2', 'm', 	oils_i18n_gettext('848', 'Theses', 'ccvm', 'value'), FALSE),
+    (1475, 'cont2', 'n', 	oils_i18n_gettext('849', 'Surveys of the literature in a subject area', 'ccvm', 'value'), FALSE),
+    (1476, 'cont2', 'o', 	oils_i18n_gettext('850', 'Reviews', 'ccvm', 'value'), FALSE),
+    (1477, 'cont2', 'p', 	oils_i18n_gettext('851', 'Programmed texts', 'ccvm', 'value'), FALSE),
+    (1478, 'cont2', 'q', 	oils_i18n_gettext('852', 'Filmographies', 'ccvm', 'value'), FALSE),
+    (1479, 'cont2', 'r', 	oils_i18n_gettext('853', 'Directories', 'ccvm', 'value'), FALSE),
+    (1480, 'cont2', 's', 	oils_i18n_gettext('854', 'Statistics', 'ccvm', 'value'), FALSE),
+    (1481, 'cont2', 't', 	oils_i18n_gettext('855', 'Technical reports', 'ccvm', 'value'), FALSE),
+    (1482, 'cont2', 'u', 	oils_i18n_gettext('856', 'Standards/specifications', 'ccvm', 'value'), FALSE),
+    (1483, 'cont2', 'v', 	oils_i18n_gettext('857', 'Legal cases and case notes', 'ccvm', 'value'), FALSE),
+    (1484, 'cont2', 'w', 	oils_i18n_gettext('858', 'Law reports and digests', 'ccvm', 'value'), FALSE),
+    (1485, 'cont2', 'x', 	oils_i18n_gettext('859', 'Other reports', 'ccvm', 'value'), FALSE),
+    (1486, 'cont2', 'y', 	oils_i18n_gettext('860', 'Yearbooks', 'ccvm', 'value'), FALSE),
+    (1487, 'cont2', 'z', 	oils_i18n_gettext('861', 'Treaties', 'ccvm', 'value'), FALSE),
+    (1488, 'cont2', '2', 	oils_i18n_gettext('862', 'Offprints', 'ccvm', 'value'), FALSE),
+    (1489, 'cont2', '5', 	oils_i18n_gettext('863', 'Calendars', 'ccvm', 'value'), FALSE),
+    (1490, 'cont2', '6', 	oils_i18n_gettext('864', 'Comics/graphic novels', 'ccvm', 'value'), FALSE),
+	
+    (1491, 'cont3', 'a', 	oils_i18n_gettext('836', 'Abstracts/summaries', 'ccvm', 'value'), FALSE),
+    (1492, 'cont3', 'b', 	oils_i18n_gettext('837', 'Bibliographies', 'ccvm', 'value'), FALSE),
+    (1493, 'cont3', 'c', 	oils_i18n_gettext('838', 'Catalogs', 'ccvm', 'value'), FALSE),
+    (1494, 'cont3', 'd', 	oils_i18n_gettext('839', 'Dictionaries', 'ccvm', 'value'), FALSE),
+    (1495, 'cont3', 'e', 	oils_i18n_gettext('840', 'Encyclopedias', 'ccvm', 'value'), FALSE),
+    (1496, 'cont3', 'f', 	oils_i18n_gettext('841', 'Handbooks', 'ccvm', 'value'), FALSE),
+    (1497, 'cont3', 'g', 	oils_i18n_gettext('842', 'Legal articles', 'ccvm', 'value'), FALSE),
+    (1498, 'cont3', 'h', 	oils_i18n_gettext('843', 'Biography', 'ccvm', 'value'), FALSE),
+    (1499, 'cont3', 'i', 	oils_i18n_gettext('844', 'Indexes', 'ccvm', 'value'), FALSE),
+    (1500, 'cont3', 'j', 	oils_i18n_gettext('845', 'Patent document', 'ccvm', 'value'), FALSE),
+    (1501, 'cont3', 'k', 	oils_i18n_gettext('846', 'Discographies', 'ccvm', 'value'), FALSE),
+    (1502, 'cont3', 'l', 	oils_i18n_gettext('847', 'Legislation', 'ccvm', 'value'), FALSE),
+    (1503, 'cont3', 'm', 	oils_i18n_gettext('848', 'Theses', 'ccvm', 'value'), FALSE),
+    (1504, 'cont3', 'n', 	oils_i18n_gettext('849', 'Surveys of the literature in a subject area', 'ccvm', 'value'), FALSE),
+    (1505, 'cont3', 'o', 	oils_i18n_gettext('850', 'Reviews', 'ccvm', 'value'), FALSE),
+    (1506, 'cont3', 'p', 	oils_i18n_gettext('851', 'Programmed texts', 'ccvm', 'value'), FALSE),
+    (1507, 'cont3', 'q', 	oils_i18n_gettext('852', 'Filmographies', 'ccvm', 'value'), FALSE),
+    (1508, 'cont3', 'r', 	oils_i18n_gettext('853', 'Directories', 'ccvm', 'value'), FALSE),
+    (1509, 'cont3', 's', 	oils_i18n_gettext('854', 'Statistics', 'ccvm', 'value'), FALSE),
+    (1510, 'cont3', 't', 	oils_i18n_gettext('855', 'Technical reports', 'ccvm', 'value'), FALSE),
+    (1511, 'cont3', 'u', 	oils_i18n_gettext('856', 'Standards/specifications', 'ccvm', 'value'), FALSE),
+    (1512, 'cont3', 'v', 	oils_i18n_gettext('857', 'Legal cases and case notes', 'ccvm', 'value'), FALSE),
+    (1513, 'cont3', 'w', 	oils_i18n_gettext('858', 'Law reports and digests', 'ccvm', 'value'), FALSE),
+    (1514, 'cont3', 'x', 	oils_i18n_gettext('859', 'Other reports', 'ccvm', 'value'), FALSE),
+    (1515, 'cont3', 'y', 	oils_i18n_gettext('860', 'Yearbooks', 'ccvm', 'value'), FALSE),
+    (1516, 'cont3', 'z', 	oils_i18n_gettext('861', 'Treaties', 'ccvm', 'value'), FALSE),
+    (1517, 'cont3', '2', 	oils_i18n_gettext('862', 'Offprints', 'ccvm', 'value'), FALSE),
+    (1518, 'cont3', '5', 	oils_i18n_gettext('863', 'Calendars', 'ccvm', 'value'), FALSE),
+    (1519, 'cont3', '6', 	oils_i18n_gettext('864', 'Comics/graphic novels', 'ccvm', 'value'), FALSE),
+	
+    (1520, 'cont4', 'a', 	oils_i18n_gettext('836', 'Abstracts/summaries', 'ccvm', 'value'), FALSE),
+    (1521, 'cont4', 'b', 	oils_i18n_gettext('837', 'Bibliographies', 'ccvm', 'value'), FALSE),
+    (1522, 'cont4', 'c', 	oils_i18n_gettext('838', 'Catalogs', 'ccvm', 'value'), FALSE),
+    (1523, 'cont4', 'd', 	oils_i18n_gettext('839', 'Dictionaries', 'ccvm', 'value'), FALSE),
+    (1524, 'cont4', 'e', 	oils_i18n_gettext('840', 'Encyclopedias', 'ccvm', 'value'), FALSE),
+    (1525, 'cont4', 'f', 	oils_i18n_gettext('841', 'Handbooks', 'ccvm', 'value'), FALSE),
+    (1526, 'cont4', 'g', 	oils_i18n_gettext('842', 'Legal articles', 'ccvm', 'value'), FALSE),
+    (1527, 'cont4', 'h', 	oils_i18n_gettext('843', 'Biography', 'ccvm', 'value'), FALSE),
+    (1528, 'cont4', 'i', 	oils_i18n_gettext('844', 'Indexes', 'ccvm', 'value'), FALSE),
+    (1529, 'cont4', 'j', 	oils_i18n_gettext('845', 'Patent document', 'ccvm', 'value'), FALSE),
+    (1530, 'cont4', 'k', 	oils_i18n_gettext('846', 'Discographies', 'ccvm', 'value'), FALSE),
+    (1531, 'cont4', 'l', 	oils_i18n_gettext('847', 'Legislation', 'ccvm', 'value'), FALSE),
+    (1532, 'cont4', 'm', 	oils_i18n_gettext('848', 'Theses', 'ccvm', 'value'), FALSE),
+    (1533, 'cont4', 'n', 	oils_i18n_gettext('849', 'Surveys of the literature in a subject area', 'ccvm', 'value'), FALSE),
+    (1534, 'cont4', 'o', 	oils_i18n_gettext('850', 'Reviews', 'ccvm', 'value'), FALSE),
+    (1535, 'cont4', 'p', 	oils_i18n_gettext('851', 'Programmed texts', 'ccvm', 'value'), FALSE),
+    (1536, 'cont4', 'q', 	oils_i18n_gettext('852', 'Filmographies', 'ccvm', 'value'), FALSE),
+    (1537, 'cont4', 'r', 	oils_i18n_gettext('853', 'Directories', 'ccvm', 'value'), FALSE),
+    (1538, 'cont4', 's', 	oils_i18n_gettext('854', 'Statistics', 'ccvm', 'value'), FALSE),
+    (1539, 'cont4', 't', 	oils_i18n_gettext('855', 'Technical reports', 'ccvm', 'value'), FALSE),
+    (1540, 'cont4', 'u', 	oils_i18n_gettext('856', 'Standards/specifications', 'ccvm', 'value'), FALSE),
+    (1541, 'cont4', 'v', 	oils_i18n_gettext('857', 'Legal cases and case notes', 'ccvm', 'value'), FALSE),
+    (1542, 'cont4', 'w', 	oils_i18n_gettext('858', 'Law reports and digests', 'ccvm', 'value'), FALSE),
+    (1543, 'cont4', 'x', 	oils_i18n_gettext('859', 'Other reports', 'ccvm', 'value'), FALSE),
+    (1544, 'cont4', 'y', 	oils_i18n_gettext('860', 'Yearbooks', 'ccvm', 'value'), FALSE),
+    (1545, 'cont4', 'z', 	oils_i18n_gettext('861', 'Treaties', 'ccvm', 'value'), FALSE),
+    (1546, 'cont4', '2', 	oils_i18n_gettext('862', 'Offprints', 'ccvm', 'value'), FALSE),
+    (1547, 'cont4', '5', 	oils_i18n_gettext('863', 'Calendars', 'ccvm', 'value'), FALSE),
+    (1548, 'cont4', '6', 	oils_i18n_gettext('864', 'Comics/graphic novels', 'ccvm', 'value'), FALSE),
+	
+    (1549, 'ltxt1', ' ', 	oils_i18n_gettext('881', 'Item is a music sound recording', 'ccvm', 'value'), FALSE),
+    (1550, 'ltxt1', 'a', 	oils_i18n_gettext('882', 'Autobiography', 'ccvm', 'value'), FALSE),
+    (1551, 'ltxt1', 'b', 	oils_i18n_gettext('883', 'Biography', 'ccvm', 'value'), FALSE),
+    (1552, 'ltxt1', 'c', 	oils_i18n_gettext('884', 'Conference proceedings', 'ccvm', 'value'), FALSE),
+    (1553, 'ltxt1', 'd', 	oils_i18n_gettext('885', 'Drama', 'ccvm', 'value'), FALSE),
+    (1554, 'ltxt1', 'e', 	oils_i18n_gettext('886', 'Essays', 'ccvm', 'value'), FALSE),
+    (1555, 'ltxt1', 'f', 	oils_i18n_gettext('887', 'Fiction', 'ccvm', 'value'), FALSE),
+    (1556, 'ltxt1', 'g', 	oils_i18n_gettext('888', 'Reporting', 'ccvm', 'value'), FALSE),
+    (1557, 'ltxt1', 'h', 	oils_i18n_gettext('889', 'History', 'ccvm', 'value'), FALSE),
+    (1558, 'ltxt1', 'i', 	oils_i18n_gettext('890', 'Instruction', 'ccvm', 'value'), FALSE),
+    (1559, 'ltxt1', 'j', 	oils_i18n_gettext('891', 'Language instruction', 'ccvm', 'value'), FALSE),
+    (1560, 'ltxt1', 'k', 	oils_i18n_gettext('892', 'Comedy', 'ccvm', 'value'), FALSE),
+    (1561, 'ltxt1', 'l', 	oils_i18n_gettext('893', 'Lectures, speeches', 'ccvm', 'value'), FALSE),
+    (1562, 'ltxt1', 'm', 	oils_i18n_gettext('894', 'Memoirs', 'ccvm', 'value'), FALSE),
+    (1563, 'ltxt1', 'n', 	oils_i18n_gettext('895', 'Not applicable', 'ccvm', 'value'), FALSE),
+    (1564, 'ltxt1', 'o', 	oils_i18n_gettext('896', 'Folktales', 'ccvm', 'value'), FALSE),
+    (1565, 'ltxt1', 'p', 	oils_i18n_gettext('897', 'Poetry', 'ccvm', 'value'), FALSE),
+    (1566, 'ltxt1', 'r', 	oils_i18n_gettext('898', 'Rehearsals', 'ccvm', 'value'), FALSE),
+    (1567, 'ltxt1', 's', 	oils_i18n_gettext('899', 'Sounds', 'ccvm', 'value'), FALSE),
+    (1568, 'ltxt1', 't', 	oils_i18n_gettext('900', 'Interviews', 'ccvm', 'value'), FALSE),
+    (1569, 'ltxt1', 'z', 	oils_i18n_gettext('901', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1570, 'ltxt2', 'a', 	oils_i18n_gettext('882', 'Autobiography', 'ccvm', 'value'), FALSE),
+    (1571, 'ltxt2', 'b', 	oils_i18n_gettext('883', 'Biography', 'ccvm', 'value'), FALSE),
+    (1572, 'ltxt2', 'c', 	oils_i18n_gettext('884', 'Conference proceedings', 'ccvm', 'value'), FALSE),
+    (1573, 'ltxt2', 'd', 	oils_i18n_gettext('885', 'Drama', 'ccvm', 'value'), FALSE),
+    (1574, 'ltxt2', 'e', 	oils_i18n_gettext('886', 'Essays', 'ccvm', 'value'), FALSE),
+    (1575, 'ltxt2', 'f', 	oils_i18n_gettext('887', 'Fiction', 'ccvm', 'value'), FALSE),
+    (1576, 'ltxt2', 'g', 	oils_i18n_gettext('888', 'Reporting', 'ccvm', 'value'), FALSE),
+    (1577, 'ltxt2', 'h', 	oils_i18n_gettext('889', 'History', 'ccvm', 'value'), FALSE),
+    (1578, 'ltxt2', 'i', 	oils_i18n_gettext('890', 'Instruction', 'ccvm', 'value'), FALSE),
+    (1579, 'ltxt2', 'j', 	oils_i18n_gettext('891', 'Language instruction', 'ccvm', 'value'), FALSE),
+    (1580, 'ltxt2', 'k', 	oils_i18n_gettext('892', 'Comedy', 'ccvm', 'value'), FALSE),
+    (1581, 'ltxt2', 'l', 	oils_i18n_gettext('893', 'Lectures, speeches', 'ccvm', 'value'), FALSE),
+    (1582, 'ltxt2', 'm', 	oils_i18n_gettext('894', 'Memoirs', 'ccvm', 'value'), FALSE),
+    (1583, 'ltxt2', 'n', 	oils_i18n_gettext('895', 'Not applicable', 'ccvm', 'value'), FALSE),
+    (1584, 'ltxt2', 'o', 	oils_i18n_gettext('896', 'Folktales', 'ccvm', 'value'), FALSE),
+    (1585, 'ltxt2', 'p', 	oils_i18n_gettext('897', 'Poetry', 'ccvm', 'value'), FALSE),
+    (1586, 'ltxt2', 'r', 	oils_i18n_gettext('898', 'Rehearsals', 'ccvm', 'value'), FALSE),
+    (1587, 'ltxt2', 's', 	oils_i18n_gettext('899', 'Sounds', 'ccvm', 'value'), FALSE),
+    (1588, 'ltxt2', 't', 	oils_i18n_gettext('900', 'Interviews', 'ccvm', 'value'), FALSE),
+    (1589, 'ltxt2', 'z', 	oils_i18n_gettext('901', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1590, 'relf1', ' ', 	oils_i18n_gettext('965', 'No relief shown', 'ccvm', 'value'), FALSE),
+    (1591, 'relf1', 'a', 	oils_i18n_gettext('966', 'Contours', 'ccvm', 'value'), FALSE),
+    (1592, 'relf1', 'b', 	oils_i18n_gettext('967', 'Shading', 'ccvm', 'value'), FALSE),
+    (1593, 'relf1', 'c', 	oils_i18n_gettext('968', 'Gradient and bathymetric tints', 'ccvm', 'value'), FALSE),
+    (1594, 'relf1', 'd', 	oils_i18n_gettext('969', 'Hachures', 'ccvm', 'value'), FALSE),
+    (1595, 'relf1', 'e', 	oils_i18n_gettext('970', 'Bathymetry, soundings', 'ccvm', 'value'), FALSE),
+    (1596, 'relf1', 'f', 	oils_i18n_gettext('971', 'Form lines', 'ccvm', 'value'), FALSE),
+    (1597, 'relf1', 'g', 	oils_i18n_gettext('972', 'Spot heights', 'ccvm', 'value'), FALSE),
+    (1598, 'relf1', 'i', 	oils_i18n_gettext('973', 'Pictorially', 'ccvm', 'value'), FALSE),
+    (1599, 'relf1', 'j', 	oils_i18n_gettext('974', 'Land forms', 'ccvm', 'value'), FALSE),
+    (1600, 'relf1', 'k', 	oils_i18n_gettext('975', 'Bathymetry, isolines', 'ccvm', 'value'), FALSE),
+    (1601, 'relf1', 'm', 	oils_i18n_gettext('976', 'Rock drawings', 'ccvm', 'value'), FALSE),
+    (1602, 'relf1', 'z', 	oils_i18n_gettext('977', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1603, 'relf2', 'a', 	oils_i18n_gettext('966', 'Contours', 'ccvm', 'value'), FALSE),
+    (1604, 'relf2', 'b', 	oils_i18n_gettext('967', 'Shading', 'ccvm', 'value'), FALSE),
+    (1605, 'relf2', 'c', 	oils_i18n_gettext('968', 'Gradient and bathymetric tints', 'ccvm', 'value'), FALSE),
+    (1606, 'relf2', 'd', 	oils_i18n_gettext('969', 'Hachures', 'ccvm', 'value'), FALSE),
+    (1607, 'relf2', 'e', 	oils_i18n_gettext('970', 'Bathymetry, soundings', 'ccvm', 'value'), FALSE),
+    (1608, 'relf2', 'f', 	oils_i18n_gettext('971', 'Form lines', 'ccvm', 'value'), FALSE),
+    (1609, 'relf2', 'g', 	oils_i18n_gettext('972', 'Spot heights', 'ccvm', 'value'), FALSE),
+    (1610, 'relf2', 'i', 	oils_i18n_gettext('973', 'Pictorially', 'ccvm', 'value'), FALSE),
+    (1611, 'relf2', 'j', 	oils_i18n_gettext('974', 'Land forms', 'ccvm', 'value'), FALSE),
+    (1612, 'relf2', 'k', 	oils_i18n_gettext('975', 'Bathymetry, isolines', 'ccvm', 'value'), FALSE),
+    (1613, 'relf2', 'm', 	oils_i18n_gettext('976', 'Rock drawings', 'ccvm', 'value'), FALSE),
+    (1614, 'relf2', 'z', 	oils_i18n_gettext('977', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1615, 'relf3', 'a', 	oils_i18n_gettext('966', 'Contours', 'ccvm', 'value'), FALSE),
+    (1616, 'relf3', 'b', 	oils_i18n_gettext('967', 'Shading', 'ccvm', 'value'), FALSE),
+    (1617, 'relf3', 'c', 	oils_i18n_gettext('968', 'Gradient and bathymetric tints', 'ccvm', 'value'), FALSE),
+    (1618, 'relf3', 'd', 	oils_i18n_gettext('969', 'Hachures', 'ccvm', 'value'), FALSE),
+    (1619, 'relf3', 'e', 	oils_i18n_gettext('970', 'Bathymetry, soundings', 'ccvm', 'value'), FALSE),
+    (1620, 'relf3', 'f', 	oils_i18n_gettext('971', 'Form lines', 'ccvm', 'value'), FALSE),
+    (1621, 'relf3', 'g', 	oils_i18n_gettext('972', 'Spot heights', 'ccvm', 'value'), FALSE),
+    (1622, 'relf3', 'i', 	oils_i18n_gettext('973', 'Pictorially', 'ccvm', 'value'), FALSE),
+    (1623, 'relf3', 'j', 	oils_i18n_gettext('974', 'Land forms', 'ccvm', 'value'), FALSE),
+    (1624, 'relf3', 'k', 	oils_i18n_gettext('975', 'Bathymetry, isolines', 'ccvm', 'value'), FALSE),
+    (1625, 'relf3', 'm', 	oils_i18n_gettext('976', 'Rock drawings', 'ccvm', 'value'), FALSE),
+    (1626, 'relf3', 'z', 	oils_i18n_gettext('977', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1627, 'relf4', 'a', 	oils_i18n_gettext('966', 'Contours', 'ccvm', 'value'), FALSE),
+    (1628, 'relf4', 'b', 	oils_i18n_gettext('967', 'Shading', 'ccvm', 'value'), FALSE),
+    (1629, 'relf4', 'c', 	oils_i18n_gettext('968', 'Gradient and bathymetric tints', 'ccvm', 'value'), FALSE),
+    (1630, 'relf4', 'd', 	oils_i18n_gettext('969', 'Hachures', 'ccvm', 'value'), FALSE),
+    (1631, 'relf4', 'e', 	oils_i18n_gettext('970', 'Bathymetry, soundings', 'ccvm', 'value'), FALSE),
+    (1632, 'relf4', 'f', 	oils_i18n_gettext('971', 'Form lines', 'ccvm', 'value'), FALSE),
+    (1633, 'relf4', 'g', 	oils_i18n_gettext('972', 'Spot heights', 'ccvm', 'value'), FALSE),
+    (1634, 'relf4', 'i', 	oils_i18n_gettext('973', 'Pictorially', 'ccvm', 'value'), FALSE),
+    (1635, 'relf4', 'j', 	oils_i18n_gettext('974', 'Land forms', 'ccvm', 'value'), FALSE),
+    (1636, 'relf4', 'k', 	oils_i18n_gettext('975', 'Bathymetry, isolines', 'ccvm', 'value'), FALSE),
+    (1637, 'relf4', 'm', 	oils_i18n_gettext('976', 'Rock drawings', 'ccvm', 'value'), FALSE),
+    (1638, 'relf4', 'z', 	oils_i18n_gettext('977', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1639, 'spfm1', ' ', 	oils_i18n_gettext('978', 'No specified special format characteristics', 'ccvm', 'value'), FALSE),
+    (1640, 'spfm1', 'e', 	oils_i18n_gettext('979', 'Manuscript', 'ccvm', 'value'), FALSE),
+    (1641, 'spfm1', 'j', 	oils_i18n_gettext('980', 'Picture card, post card', 'ccvm', 'value'), FALSE),
+    (1642, 'spfm1', 'k', 	oils_i18n_gettext('981', 'Calendar', 'ccvm', 'value'), FALSE),
+    (1643, 'spfm1', 'l', 	oils_i18n_gettext('982', 'Puzzle', 'ccvm', 'value'), FALSE),
+    (1644, 'spfm1', 'n', 	oils_i18n_gettext('983', 'Game', 'ccvm', 'value'), FALSE),
+    (1645, 'spfm1', 'o', 	oils_i18n_gettext('984', 'Wall map', 'ccvm', 'value'), FALSE),
+    (1646, 'spfm1', 'p', 	oils_i18n_gettext('985', 'Playing cards', 'ccvm', 'value'), FALSE),
+    (1647, 'spfm1', 'r', 	oils_i18n_gettext('986', 'Loose-leaf', 'ccvm', 'value'), FALSE),
+    (1648, 'spfm1', 'z', 	oils_i18n_gettext('987', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1649, 'spfm2', 'e', 	oils_i18n_gettext('979', 'Manuscript', 'ccvm', 'value'), FALSE),
+    (1650, 'spfm2', 'j', 	oils_i18n_gettext('980', 'Picture card, post card', 'ccvm', 'value'), FALSE),
+    (1651, 'spfm2', 'k', 	oils_i18n_gettext('981', 'Calendar', 'ccvm', 'value'), FALSE),
+    (1652, 'spfm2', 'l', 	oils_i18n_gettext('982', 'Puzzle', 'ccvm', 'value'), FALSE),
+    (1653, 'spfm2', 'n', 	oils_i18n_gettext('983', 'Game', 'ccvm', 'value'), FALSE),
+    (1654, 'spfm2', 'o', 	oils_i18n_gettext('984', 'Wall map', 'ccvm', 'value'), FALSE),
+    (1655, 'spfm2', 'p', 	oils_i18n_gettext('985', 'Playing cards', 'ccvm', 'value'), FALSE),
+    (1656, 'spfm2', 'r', 	oils_i18n_gettext('986', 'Loose-leaf', 'ccvm', 'value'), FALSE),
+    (1657, 'spfm2', 'z', 	oils_i18n_gettext('987', 'Other', 'ccvm', 'value'), FALSE),
+	
+    (1658, 'ills', ' ', 	oils_i18n_gettext('1658', 'No Illustrations', 'ccvm', 'value'), FALSE),
+    (1659, 'ills', 'a', 	oils_i18n_gettext('1659', 'Illustrations', 'ccvm', 'value'), FALSE),
+    (1660, 'ills', 'b', 	oils_i18n_gettext('1660', 'Maps', 'ccvm', 'value'), FALSE),
+    (1661, 'ills', 'c', 	oils_i18n_gettext('1661', 'Portraits', 'ccvm', 'value'), FALSE),
+    (1662, 'ills', 'd', 	oils_i18n_gettext('1662', 'Charts', 'ccvm', 'value'), FALSE),
+    (1663, 'ills', 'e', 	oils_i18n_gettext('1663', 'Plans', 'ccvm', 'value'), FALSE),
+    (1664, 'ills', 'f', 	oils_i18n_gettext('1664', 'Plates', 'ccvm', 'value'), FALSE),
+    (1665, 'ills', 'g', 	oils_i18n_gettext('1665', 'Music', 'ccvm', 'value'), FALSE),
+    (1666, 'ills', 'h', 	oils_i18n_gettext('1666', 'Facsimiles', 'ccvm', 'value'), FALSE),
+    (1667, 'ills', 'i', 	oils_i18n_gettext('1667', 'Coats of arms', 'ccvm', 'value'), FALSE),
+    (1668, 'ills', 'j', 	oils_i18n_gettext('1668', 'Genealogical tables', 'ccvm', 'value'), FALSE),
+    (1669, 'ills', 'k', 	oils_i18n_gettext('1669', 'Forms', 'ccvm', 'value'), FALSE),
+    (1670, 'ills', 'l', 	oils_i18n_gettext('1670', 'Samples', 'ccvm', 'value'), FALSE),
+    (1671, 'ills', 'm', 	oils_i18n_gettext('1671', 'Phonodisc, phonowire, etc.', 'ccvm', 'value'), FALSE),
+    (1672, 'ills', 'o', 	oils_i18n_gettext('1672', 'Photographs', 'ccvm', 'value'), FALSE),
+    (1673, 'ills', 'p', 	oils_i18n_gettext('1673', 'Illuminations', 'ccvm', 'value'), FALSE),
+	
+    (1674, 'ills1', ' ', 	oils_i18n_gettext('1658', 'No Illustrations', 'ccvm', 'value'), FALSE),
+    (1675, 'ills1', 'a', 	oils_i18n_gettext('1659', 'Illustrations', 'ccvm', 'value'), FALSE),
+    (1676, 'ills1', 'b', 	oils_i18n_gettext('1660', 'Maps', 'ccvm', 'value'), FALSE),
+    (1677, 'ills1', 'c', 	oils_i18n_gettext('1661', 'Portraits', 'ccvm', 'value'), FALSE),
+    (1678, 'ills1', 'd', 	oils_i18n_gettext('1662', 'Charts', 'ccvm', 'value'), FALSE),
+    (1679, 'ills1', 'e', 	oils_i18n_gettext('1663', 'Plans', 'ccvm', 'value'), FALSE),
+    (1680, 'ills1', 'f', 	oils_i18n_gettext('1664', 'Plates', 'ccvm', 'value'), FALSE),
+    (1681, 'ills1', 'g', 	oils_i18n_gettext('1665', 'Music', 'ccvm', 'value'), FALSE),
+    (1682, 'ills1', 'h', 	oils_i18n_gettext('1666', 'Facsimiles', 'ccvm', 'value'), FALSE),
+    (1683, 'ills1', 'i', 	oils_i18n_gettext('1667', 'Coats of arms', 'ccvm', 'value'), FALSE),
+    (1684, 'ills1', 'j', 	oils_i18n_gettext('1668', 'Genealogical tables', 'ccvm', 'value'), FALSE),
+    (1685, 'ills1', 'k', 	oils_i18n_gettext('1669', 'Forms', 'ccvm', 'value'), FALSE),
+    (1686, 'ills1', 'l', 	oils_i18n_gettext('1670', 'Samples', 'ccvm', 'value'), FALSE),
+    (1687, 'ills1', 'm', 	oils_i18n_gettext('1671', 'Phonodisc, phonowire, etc.', 'ccvm', 'value'), FALSE),
+    (1688, 'ills1', 'o', 	oils_i18n_gettext('1672', 'Photographs', 'ccvm', 'value'), FALSE),
+    (1689, 'ills1', 'p', 	oils_i18n_gettext('1673', 'Illuminations', 'ccvm', 'value'), FALSE),
+	
+    (1690, 'ills2', 'a', 	oils_i18n_gettext('1659', 'Illustrations', 'ccvm', 'value'), FALSE),
+    (1691, 'ills2', 'b', 	oils_i18n_gettext('1660', 'Maps', 'ccvm', 'value'), FALSE),
+    (1692, 'ills2', 'c', 	oils_i18n_gettext('1661', 'Portraits', 'ccvm', 'value'), FALSE),
+    (1693, 'ills2', 'd', 	oils_i18n_gettext('1662', 'Charts', 'ccvm', 'value'), FALSE),
+    (1694, 'ills2', 'e', 	oils_i18n_gettext('1663', 'Plans', 'ccvm', 'value'), FALSE),
+    (1695, 'ills2', 'f', 	oils_i18n_gettext('1664', 'Plates', 'ccvm', 'value'), FALSE),
+    (1696, 'ills2', 'g', 	oils_i18n_gettext('1665', 'Music', 'ccvm', 'value'), FALSE),
+    (1697, 'ills2', 'h', 	oils_i18n_gettext('1666', 'Facsimiles', 'ccvm', 'value'), FALSE),
+    (1698, 'ills2', 'i', 	oils_i18n_gettext('1667', 'Coats of arms', 'ccvm', 'value'), FALSE),
+    (1699, 'ills2', 'j', 	oils_i18n_gettext('1668', 'Genealogical tables', 'ccvm', 'value'), FALSE),
+    (1700, 'ills2', 'k', 	oils_i18n_gettext('1669', 'Forms', 'ccvm', 'value'), FALSE),
+    (1701, 'ills2', 'l', 	oils_i18n_gettext('1670', 'Samples', 'ccvm', 'value'), FALSE),
+    (1702, 'ills2', 'm', 	oils_i18n_gettext('1671', 'Phonodisc, phonowire, etc.', 'ccvm', 'value'), FALSE),
+    (1703, 'ills2', 'o', 	oils_i18n_gettext('1672', 'Photographs', 'ccvm', 'value'), FALSE),
+    (1704, 'ills2', 'p', 	oils_i18n_gettext('1673', 'Illuminations', 'ccvm', 'value'), FALSE),
+	
+    (1705, 'ills3', 'a', 	oils_i18n_gettext('1659', 'Illustrations', 'ccvm', 'value'), FALSE),
+    (1706, 'ills3', 'b', 	oils_i18n_gettext('1660', 'Maps', 'ccvm', 'value'), FALSE),
+    (1707, 'ills3', 'c', 	oils_i18n_gettext('1661', 'Portraits', 'ccvm', 'value'), FALSE),
+    (1708, 'ills3', 'd', 	oils_i18n_gettext('1662', 'Charts', 'ccvm', 'value'), FALSE),
+    (1709, 'ills3', 'e', 	oils_i18n_gettext('1663', 'Plans', 'ccvm', 'value'), FALSE),
+    (1710, 'ills3', 'f', 	oils_i18n_gettext('1664', 'Plates', 'ccvm', 'value'), FALSE),
+    (1711, 'ills3', 'g', 	oils_i18n_gettext('1665', 'Music', 'ccvm', 'value'), FALSE),
+    (1712, 'ills3', 'h', 	oils_i18n_gettext('1666', 'Facsimiles', 'ccvm', 'value'), FALSE),
+    (1713, 'ills3', 'i', 	oils_i18n_gettext('1667', 'Coats of arms', 'ccvm', 'value'), FALSE),
+    (1714, 'ills3', 'j', 	oils_i18n_gettext('1668', 'Genealogical tables', 'ccvm', 'value'), FALSE),
+    (1715, 'ills3', 'k', 	oils_i18n_gettext('1669', 'Forms', 'ccvm', 'value'), FALSE),
+    (1716, 'ills3', 'l', 	oils_i18n_gettext('1670', 'Samples', 'ccvm', 'value'), FALSE),
+    (1717, 'ills3', 'm', 	oils_i18n_gettext('1671', 'Phonodisc, phonowire, etc.', 'ccvm', 'value'), FALSE),
+    (1718, 'ills3', 'o', 	oils_i18n_gettext('1672', 'Photographs', 'ccvm', 'value'), FALSE),
+    (1719, 'ills3', 'p', 	oils_i18n_gettext('1673', 'Illuminations', 'ccvm', 'value'), FALSE),
+	
+    (1720, 'ills4', 'a', 	oils_i18n_gettext('1659', 'Illustrations', 'ccvm', 'value'), FALSE),
+    (1721, 'ills4', 'b', 	oils_i18n_gettext('1660', 'Maps', 'ccvm', 'value'), FALSE),
+    (1722, 'ills4', 'c', 	oils_i18n_gettext('1661', 'Portraits', 'ccvm', 'value'), FALSE),
+    (1723, 'ills4', 'd', 	oils_i18n_gettext('1662', 'Charts', 'ccvm', 'value'), FALSE),
+    (1724, 'ills4', 'e', 	oils_i18n_gettext('1663', 'Plans', 'ccvm', 'value'), FALSE),
+    (1725, 'ills4', 'f', 	oils_i18n_gettext('1664', 'Plates', 'ccvm', 'value'), FALSE),
+    (1726, 'ills4', 'g', 	oils_i18n_gettext('1665', 'Music', 'ccvm', 'value'), FALSE),
+    (1727, 'ills4', 'h', 	oils_i18n_gettext('1666', 'Facsimiles', 'ccvm', 'value'), FALSE),
+    (1728, 'ills4', 'i', 	oils_i18n_gettext('1667', 'Coats of arms', 'ccvm', 'value'), FALSE),
+    (1729, 'ills4', 'j', 	oils_i18n_gettext('1668', 'Genealogical tables', 'ccvm', 'value'), FALSE),
+    (1730, 'ills4', 'k', 	oils_i18n_gettext('1669', 'Forms', 'ccvm', 'value'), FALSE),
+    (1731, 'ills4', 'l', 	oils_i18n_gettext('1670', 'Samples', 'ccvm', 'value'), FALSE),
+    (1732, 'ills4', 'm', 	oils_i18n_gettext('1671', 'Phonodisc, phonowire, etc.', 'ccvm', 'value'), FALSE),
+    (1733, 'ills4', 'o', 	oils_i18n_gettext('1672', 'Photographs', 'ccvm', 'value'), FALSE),
+    (1734, 'ills4', 'p', 	oils_i18n_gettext('1673', 'Illuminations', 'ccvm', 'value'), FALSE);
+	
+
+-- Composite coded value maps, this way the "primary" fixed field can be used in advanced searches without a ton of ORs and extra work.
+-- Space is used as a filler for any position other than the first, so for something to actually have "No accompanying matter," for example, specifically accm1 must = ' '.
+-- Any other value has the same meaning in any position.
+INSERT INTO config.composite_attr_entry_definition (coded_value, definition) VALUES
+    (1735, '{"_attr":"accm1","_val":" "}'),
+    (713, '[{"_attr":"accm6","_val":"a"},{"_attr":"accm5","_val":"a"},{"_attr":"accm4","_val":"a"},{"_attr":"accm3","_val":"a"},{"_attr":"accm2","_val":"a"},{"_attr":"accm1","_val":"a"}]'),
+    (714, '[{"_attr":"accm6","_val":"b"},{"_attr":"accm5","_val":"b"},{"_attr":"accm4","_val":"b"},{"_attr":"accm3","_val":"b"},{"_attr":"accm2","_val":"b"},{"_attr":"accm1","_val":"b"}]'),
+    (715, '[{"_attr":"accm6","_val":"c"},{"_attr":"accm5","_val":"c"},{"_attr":"accm4","_val":"c"},{"_attr":"accm3","_val":"c"},{"_attr":"accm2","_val":"c"},{"_attr":"accm1","_val":"c"}]'),
+    (716, '[{"_attr":"accm6","_val":"d"},{"_attr":"accm5","_val":"d"},{"_attr":"accm4","_val":"d"},{"_attr":"accm3","_val":"d"},{"_attr":"accm2","_val":"d"},{"_attr":"accm1","_val":"d"}]'),
+    (717, '[{"_attr":"accm6","_val":"e"},{"_attr":"accm5","_val":"e"},{"_attr":"accm4","_val":"e"},{"_attr":"accm3","_val":"e"},{"_attr":"accm2","_val":"e"},{"_attr":"accm1","_val":"e"}]'),
+    (718, '[{"_attr":"accm6","_val":"f"},{"_attr":"accm5","_val":"f"},{"_attr":"accm4","_val":"f"},{"_attr":"accm3","_val":"f"},{"_attr":"accm2","_val":"f"},{"_attr":"accm1","_val":"f"}]'),
+    (719, '[{"_attr":"accm6","_val":"g"},{"_attr":"accm5","_val":"g"},{"_attr":"accm4","_val":"g"},{"_attr":"accm3","_val":"g"},{"_attr":"accm2","_val":"g"},{"_attr":"accm1","_val":"g"}]'),
+    (720, '[{"_attr":"accm6","_val":"h"},{"_attr":"accm5","_val":"h"},{"_attr":"accm4","_val":"h"},{"_attr":"accm3","_val":"h"},{"_attr":"accm2","_val":"h"},{"_attr":"accm1","_val":"h"}]'),
+    (721, '[{"_attr":"accm6","_val":"i"},{"_attr":"accm5","_val":"i"},{"_attr":"accm4","_val":"i"},{"_attr":"accm3","_val":"i"},{"_attr":"accm2","_val":"i"},{"_attr":"accm1","_val":"i"}]'),
+    (722, '[{"_attr":"accm6","_val":"k"},{"_attr":"accm5","_val":"k"},{"_attr":"accm4","_val":"k"},{"_attr":"accm3","_val":"k"},{"_attr":"accm2","_val":"k"},{"_attr":"accm1","_val":"k"}]'),
+    (723, '[{"_attr":"accm6","_val":"r"},{"_attr":"accm5","_val":"r"},{"_attr":"accm4","_val":"r"},{"_attr":"accm3","_val":"r"},{"_attr":"accm2","_val":"r"},{"_attr":"accm1","_val":"r"}]'),
+    (724, '[{"_attr":"accm6","_val":"s"},{"_attr":"accm5","_val":"s"},{"_attr":"accm4","_val":"s"},{"_attr":"accm3","_val":"s"},{"_attr":"accm2","_val":"s"},{"_attr":"accm1","_val":"s"}]'),
+    (725, '[{"_attr":"accm6","_val":"z"},{"_attr":"accm5","_val":"z"},{"_attr":"accm4","_val":"z"},{"_attr":"accm3","_val":"z"},{"_attr":"accm2","_val":"z"},{"_attr":"accm1","_val":"z"}]'),
+
+    (835, '{"_attr":"cont1","_val":" "}'),
+    (836, '[{"_attr":"cont4","_val":"a"},{"_attr":"cont3","_val":"a"},{"_attr":"cont2","_val":"a"},{"_attr":"cont1","_val":"a"}]'),
+    (837, '[{"_attr":"cont4","_val":"b"},{"_attr":"cont3","_val":"b"},{"_attr":"cont2","_val":"b"},{"_attr":"cont1","_val":"b"}]'),
+    (838, '[{"_attr":"cont4","_val":"c"},{"_attr":"cont3","_val":"c"},{"_attr":"cont2","_val":"c"},{"_attr":"cont1","_val":"c"}]'),
+    (839, '[{"_attr":"cont4","_val":"d"},{"_attr":"cont3","_val":"d"},{"_attr":"cont2","_val":"d"},{"_attr":"cont1","_val":"d"}]'),
+    (840, '[{"_attr":"cont4","_val":"e"},{"_attr":"cont3","_val":"e"},{"_attr":"cont2","_val":"e"},{"_attr":"cont1","_val":"e"}]'),
+    (841, '[{"_attr":"cont4","_val":"f"},{"_attr":"cont3","_val":"f"},{"_attr":"cont2","_val":"f"},{"_attr":"cont1","_val":"f"}]'),
+    (842, '[{"_attr":"cont4","_val":"g"},{"_attr":"cont3","_val":"g"},{"_attr":"cont2","_val":"g"},{"_attr":"cont1","_val":"g"}]'),
+    (843, '[{"_attr":"cont4","_val":"h"},{"_attr":"cont3","_val":"h"},{"_attr":"cont2","_val":"h"},{"_attr":"cont1","_val":"h"}]'),
+    (844, '[{"_attr":"cont4","_val":"i"},{"_attr":"cont3","_val":"i"},{"_attr":"cont2","_val":"i"},{"_attr":"cont1","_val":"i"}]'),
+    (845, '[{"_attr":"cont4","_val":"j"},{"_attr":"cont3","_val":"j"},{"_attr":"cont2","_val":"j"},{"_attr":"cont1","_val":"j"}]'),
+    (846, '[{"_attr":"cont4","_val":"k"},{"_attr":"cont3","_val":"k"},{"_attr":"cont2","_val":"k"},{"_attr":"cont1","_val":"k"}]'),
+    (847, '[{"_attr":"cont4","_val":"l"},{"_attr":"cont3","_val":"l"},{"_attr":"cont2","_val":"l"},{"_attr":"cont1","_val":"l"}]'),
+    (848, '[{"_attr":"cont4","_val":"m"},{"_attr":"cont3","_val":"m"},{"_attr":"cont2","_val":"m"},{"_attr":"cont1","_val":"m"}]'),
+    (849, '[{"_attr":"cont4","_val":"n"},{"_attr":"cont3","_val":"n"},{"_attr":"cont2","_val":"n"},{"_attr":"cont1","_val":"n"}]'),
+    (850, '[{"_attr":"cont4","_val":"o"},{"_attr":"cont3","_val":"o"},{"_attr":"cont2","_val":"o"},{"_attr":"cont1","_val":"o"}]'),
+    (851, '[{"_attr":"cont4","_val":"p"},{"_attr":"cont3","_val":"p"},{"_attr":"cont2","_val":"p"},{"_attr":"cont1","_val":"p"}]'),
+    (852, '[{"_attr":"cont4","_val":"q"},{"_attr":"cont3","_val":"q"},{"_attr":"cont2","_val":"q"},{"_attr":"cont1","_val":"q"}]'),
+    (853, '[{"_attr":"cont4","_val":"r"},{"_attr":"cont3","_val":"r"},{"_attr":"cont2","_val":"r"},{"_attr":"cont1","_val":"r"}]'),
+    (854, '[{"_attr":"cont4","_val":"s"},{"_attr":"cont3","_val":"s"},{"_attr":"cont2","_val":"s"},{"_attr":"cont1","_val":"s"}]'),
+    (855, '[{"_attr":"cont4","_val":"t"},{"_attr":"cont3","_val":"t"},{"_attr":"cont2","_val":"t"},{"_attr":"cont1","_val":"t"}]'),
+    (856, '[{"_attr":"cont4","_val":"u"},{"_attr":"cont3","_val":"u"},{"_attr":"cont2","_val":"u"},{"_attr":"cont1","_val":"u"}]'),
+    (857, '[{"_attr":"cont4","_val":"v"},{"_attr":"cont3","_val":"v"},{"_attr":"cont2","_val":"v"},{"_attr":"cont1","_val":"v"}]'),
+    (858, '[{"_attr":"cont4","_val":"w"},{"_attr":"cont3","_val":"w"},{"_attr":"cont2","_val":"w"},{"_attr":"cont1","_val":"w"}]'),
+    (859, '[{"_attr":"cont4","_val":"x"},{"_attr":"cont3","_val":"x"},{"_attr":"cont2","_val":"x"},{"_attr":"cont1","_val":"x"}]'),
+    (860, '[{"_attr":"cont4","_val":"y"},{"_attr":"cont3","_val":"y"},{"_attr":"cont2","_val":"y"},{"_attr":"cont1","_val":"y"}]'),
+    (861, '[{"_attr":"cont4","_val":"z"},{"_attr":"cont3","_val":"z"},{"_attr":"cont2","_val":"z"},{"_attr":"cont1","_val":"z"}]'),
+    (862, '[{"_attr":"cont4","_val":"2"},{"_attr":"cont3","_val":"2"},{"_attr":"cont2","_val":"2"},{"_attr":"cont1","_val":"2"}]'),
+    (863, '[{"_attr":"cont4","_val":"5"},{"_attr":"cont3","_val":"5"},{"_attr":"cont2","_val":"5"},{"_attr":"cont1","_val":"5"}]'),
+    (864, '[{"_attr":"cont4","_val":"6"},{"_attr":"cont3","_val":"6"},{"_attr":"cont2","_val":"6"},{"_attr":"cont1","_val":"6"}]'),
+
+    (881, '{"_attr":"ltxt1","_val":" "}'),
+    (882, '[{"_attr":"ltxt2","_val":"a"},{"_attr":"ltxt1","_val":"a"}]'),
+    (883, '[{"_attr":"ltxt2","_val":"b"},{"_attr":"ltxt1","_val":"b"}]'),
+    (884, '[{"_attr":"ltxt2","_val":"c"},{"_attr":"ltxt1","_val":"c"}]'),
+    (885, '[{"_attr":"ltxt2","_val":"d"},{"_attr":"ltxt1","_val":"d"}]'),
+    (886, '[{"_attr":"ltxt2","_val":"e"},{"_attr":"ltxt1","_val":"e"}]'),
+    (887, '[{"_attr":"ltxt2","_val":"f"},{"_attr":"ltxt1","_val":"f"}]'),
+    (888, '[{"_attr":"ltxt2","_val":"g"},{"_attr":"ltxt1","_val":"g"}]'),
+    (889, '[{"_attr":"ltxt2","_val":"h"},{"_attr":"ltxt1","_val":"h"}]'),
+    (890, '[{"_attr":"ltxt2","_val":"i"},{"_attr":"ltxt1","_val":"i"}]'),
+    (891, '[{"_attr":"ltxt2","_val":"j"},{"_attr":"ltxt1","_val":"j"}]'),
+    (892, '[{"_attr":"ltxt2","_val":"k"},{"_attr":"ltxt1","_val":"k"}]'),
+    (893, '[{"_attr":"ltxt2","_val":"l"},{"_attr":"ltxt1","_val":"l"}]'),
+    (894, '[{"_attr":"ltxt2","_val":"m"},{"_attr":"ltxt1","_val":"m"}]'),
+    (895, '[{"_attr":"ltxt2","_val":"n"},{"_attr":"ltxt1","_val":"n"}]'),
+    (896, '[{"_attr":"ltxt2","_val":"o"},{"_attr":"ltxt1","_val":"o"}]'),
+    (897, '[{"_attr":"ltxt2","_val":"p"},{"_attr":"ltxt1","_val":"p"}]'),
+    (898, '[{"_attr":"ltxt2","_val":"r"},{"_attr":"ltxt1","_val":"r"}]'),
+    (899, '[{"_attr":"ltxt2","_val":"s"},{"_attr":"ltxt1","_val":"s"}]'),
+    (900, '[{"_attr":"ltxt2","_val":"t"},{"_attr":"ltxt1","_val":"t"}]'),
+    (901, '[{"_attr":"ltxt2","_val":"z"},{"_attr":"ltxt1","_val":"z"}]'),
+
+    (965, '{"_attr":"relf1","_val":" "}'),
+    (966, '[{"_attr":"relf4","_val":"a"},{"_attr":"relf3","_val":"a"},{"_attr":"relf2","_val":"a"},{"_attr":"relf1","_val":"a"}]'),
+    (967, '[{"_attr":"relf4","_val":"b"},{"_attr":"relf3","_val":"b"},{"_attr":"relf2","_val":"b"},{"_attr":"relf1","_val":"b"}]'),
+    (968, '[{"_attr":"relf4","_val":"c"},{"_attr":"relf3","_val":"c"},{"_attr":"relf2","_val":"c"},{"_attr":"relf1","_val":"c"}]'),
+    (969, '[{"_attr":"relf4","_val":"d"},{"_attr":"relf3","_val":"d"},{"_attr":"relf2","_val":"d"},{"_attr":"relf1","_val":"d"}]'),
+    (970, '[{"_attr":"relf4","_val":"e"},{"_attr":"relf3","_val":"e"},{"_attr":"relf2","_val":"e"},{"_attr":"relf1","_val":"e"}]'),
+    (971, '[{"_attr":"relf4","_val":"f"},{"_attr":"relf3","_val":"f"},{"_attr":"relf2","_val":"f"},{"_attr":"relf1","_val":"f"}]'),
+    (972, '[{"_attr":"relf4","_val":"g"},{"_attr":"relf3","_val":"g"},{"_attr":"relf2","_val":"g"},{"_attr":"relf1","_val":"g"}]'),
+    (973, '[{"_attr":"relf4","_val":"i"},{"_attr":"relf3","_val":"i"},{"_attr":"relf2","_val":"i"},{"_attr":"relf1","_val":"i"}]'),
+    (974, '[{"_attr":"relf4","_val":"j"},{"_attr":"relf3","_val":"j"},{"_attr":"relf2","_val":"j"},{"_attr":"relf1","_val":"j"}]'),
+    (975, '[{"_attr":"relf4","_val":"k"},{"_attr":"relf3","_val":"k"},{"_attr":"relf2","_val":"k"},{"_attr":"relf1","_val":"k"}]'),
+    (976, '[{"_attr":"relf4","_val":"m"},{"_attr":"relf3","_val":"m"},{"_attr":"relf2","_val":"m"},{"_attr":"relf1","_val":"m"}]'),
+    (977, '[{"_attr":"relf4","_val":"z"},{"_attr":"relf3","_val":"z"},{"_attr":"relf2","_val":"z"},{"_attr":"relf1","_val":"z"}]'),
+
+    (978, '{"_attr":"spfm1","_val":" "}'),
+    (979, '[{"_attr":"spfm2","_val":"e"},{"_attr":"spfm1","_val":"e"}]'),
+    (980, '[{"_attr":"spfm2","_val":"j"},{"_attr":"spfm1","_val":"j"}]'),
+    (981, '[{"_attr":"spfm2","_val":"k"},{"_attr":"spfm1","_val":"k"}]'),
+    (982, '[{"_attr":"spfm2","_val":"l"},{"_attr":"spfm1","_val":"l"}]'),
+    (983, '[{"_attr":"spfm2","_val":"n"},{"_attr":"spfm1","_val":"n"}]'),
+    (984, '[{"_attr":"spfm2","_val":"o"},{"_attr":"spfm1","_val":"o"}]'),
+    (985, '[{"_attr":"spfm2","_val":"p"},{"_attr":"spfm1","_val":"p"}]'),
+    (986, '[{"_attr":"spfm2","_val":"r"},{"_attr":"spfm1","_val":"r"}]'),
+    (987, '[{"_attr":"spfm2","_val":"z"},{"_attr":"spfm1","_val":"z"}]'),
+	
+    (1658, '{"_attr":"ills1","_val":" "}'),
+    (1659, '[{"_attr":"ills4","_val":"a"},{"_attr":"ills3","_val":"a"},{"_attr":"ills2","_val":"a"},{"_attr":"ills1","_val":"a"}]'),
+    (1660, '[{"_attr":"ills4","_val":"b"},{"_attr":"ills3","_val":"b"},{"_attr":"ills2","_val":"b"},{"_attr":"ills1","_val":"b"}]'),
+    (1661, '[{"_attr":"ills4","_val":"c"},{"_attr":"ills3","_val":"c"},{"_attr":"ills2","_val":"c"},{"_attr":"ills1","_val":"c"}]'),
+    (1662, '[{"_attr":"ills4","_val":"d"},{"_attr":"ills3","_val":"d"},{"_attr":"ills2","_val":"d"},{"_attr":"ills1","_val":"d"}]'),
+    (1663, '[{"_attr":"ills4","_val":"e"},{"_attr":"ills3","_val":"e"},{"_attr":"ills2","_val":"e"},{"_attr":"ills1","_val":"e"}]'),
+    (1664, '[{"_attr":"ills4","_val":"f"},{"_attr":"ills3","_val":"f"},{"_attr":"ills2","_val":"f"},{"_attr":"ills1","_val":"f"}]'),
+    (1665, '[{"_attr":"ills4","_val":"g"},{"_attr":"ills3","_val":"g"},{"_attr":"ills2","_val":"g"},{"_attr":"ills1","_val":"g"}]'),
+    (1666, '[{"_attr":"ills4","_val":"h"},{"_attr":"ills3","_val":"h"},{"_attr":"ills2","_val":"h"},{"_attr":"ills1","_val":"h"}]'),
+    (1667, '[{"_attr":"ills4","_val":"i"},{"_attr":"ills3","_val":"i"},{"_attr":"ills2","_val":"i"},{"_attr":"ills1","_val":"i"}]'),
+    (1668, '[{"_attr":"ills4","_val":"j"},{"_attr":"ills3","_val":"j"},{"_attr":"ills2","_val":"j"},{"_attr":"ills1","_val":"j"}]'),
+    (1669, '[{"_attr":"ills4","_val":"k"},{"_attr":"ills3","_val":"k"},{"_attr":"ills2","_val":"k"},{"_attr":"ills1","_val":"k"}]'),
+    (1670, '[{"_attr":"ills4","_val":"l"},{"_attr":"ills3","_val":"l"},{"_attr":"ills2","_val":"l"},{"_attr":"ills1","_val":"l"}]'),
+    (1671, '[{"_attr":"ills4","_val":"m"},{"_attr":"ills3","_val":"m"},{"_attr":"ills2","_val":"m"},{"_attr":"ills1","_val":"m"}]'),
+    (1672, '[{"_attr":"ills4","_val":"o"},{"_attr":"ills3","_val":"o"},{"_attr":"ills2","_val":"o"},{"_attr":"ills1","_val":"o"}]'),
+    (1673, '[{"_attr":"ills4","_val":"p"},{"_attr":"ills3","_val":"p"},{"_attr":"ills2","_val":"p"},{"_attr":"ills1","_val":"p"}]');
+
+SELECT evergreen.upgrade_deps_block_check('0968', :eg_version); -- jstompro/gmcharlt
+
+--create hook for actor.usr.create_date
+INSERT INTO action_trigger.hook (key, core_type, description, passive)
+    VALUES ('au.created', 'au', 'A user was created', 't');
+	
+--SQL to create event definition for new account creation notice
+--Inactive, owned by top of org tree by default.  Modify to suit needs.
+
+INSERT INTO action_trigger.event_definition (
+    active, owner, name, hook, 
+    validator, reactor, delay, delay_field,
+    max_delay, template
+)  VALUES (
+    'f', '1', 'New User Created Welcome Notice', 'au.created',
+    'NOOP_True', 'SendEmail', '10 seconds', 'create_date',
+    '1 day',
+$$
+[%- USE date -%]
+[%- user = target -%]
+[%- lib = target.home_ou -%]
+To: [%- params.recipient_email || user.email %]
+From: [%- helpers.get_org_setting(target.home_ou.id, 'org.bounced_emails') || lib.email || params.sender_email || default_sender %]
+Reply-To: [%- helpers.get_org_setting(target.home_ou.id, 'org.bounced_emails') || lib.email || params.sender_email || default_sender %]
+Subject: New Library Account Sign-up - Welcome!
+Auto-Submitted: auto-generated
+
+Dear [% user.first_given_name %] [% user.family_name %],
+
+Thank you for signing up for an account with the [% lib.name %] on [% user.create_date.substr(0, 10) %].
+
+This email is your confirmation that your account is set up and ready as well as testing to see that we have your correct email address.
+
+If you did not sign up for an account at the library and have received this email in error, please reply and let us know.
+
+You can access your account online at http://catalog/eg/opac/login. From that site you can search the catalog, request materials, renew materials, leave comments, leave suggestions for titles you would like the library to purchase and update your account information.
+
+Sincerely,
+[% lib.name %]
+
+Contact your library for more information:
+
+[% lib.name %]
+[%- SET addr = lib.mailing_address -%]
+[%- IF !addr -%] [%- SET addr = lib.billing_address -%] [%- END %]
+[% addr.street1 %] [% addr.street2 %]
+[% addr.city %], [% addr.state %]
+[% addr.post_code %]
+[% lib.phone %]
+[% lib.email %]
+
+$$);
+	
+--insert environment values
+INSERT INTO action_trigger.environment (event_def, path) VALUES
+    (CURRVAL('action_trigger.event_definition_id_seq'), 'home_ou.mailing_address'),
+    (CURRVAL('action_trigger.event_definition_id_seq'), 'home_ou.billing_address');
+	
+SELECT evergreen.upgrade_deps_block_check('0969', :eg_version); -- jeffdavis/stompro
+
+INSERT INTO config.org_unit_setting_type
+    (name, grp, label, description, datatype)
+    VALUES
+        ('org.restrict_opt_to_depth',
+         'sec',
+         oils_i18n_gettext('org.restrict_opt_to_depth',
+            'Restrict patron opt-in to home library and related orgs at specified depth',
+            'coust', 'label'),
+         oils_i18n_gettext('org.restrict_opt_to_depth',
+            'Patrons at this library can only be opted-in at org units which are within the '||
+            'library''s section of the org tree, at or below the depth specified by this setting. '||
+            'They cannot be opted in at any other libraries.',
+            'coust', 'description'),
+        'integer');
+
+SELECT evergreen.upgrade_deps_block_check('0970', :eg_version); -- Dyrcona/gmcharlt
+
+CREATE OR REPLACE FUNCTION search.facets_for_record_set(ignore_facet_classes TEXT[], hits BIGINT[]) RETURNS TABLE (id INT, value TEXT, count BIGINT) AS $$
+    SELECT id, value, count FROM (
+        SELECT mfae.field AS id,
+               mfae.value,
+               COUNT(DISTINCT mmrsm.source),
+               row_number() OVER (
+                PARTITION BY mfae.field ORDER BY COUNT(distinct mmrsm.source) DESC
+               ) AS rownum
+        FROM metabib.facet_entry mfae
+        JOIN metabib.metarecord_source_map mmrsm ON (mfae.source = mmrsm.source)
+        JOIN config.metabib_field cmf ON (cmf.id = mfae.field)
+        WHERE mmrsm.source IN (SELECT * FROM unnest($2))
+        AND cmf.facet_field
+        AND cmf.field_class NOT IN (SELECT * FROM unnest($1))
+        GROUP by 1, 2
+    ) all_facets
+    WHERE rownum <= (SELECT COALESCE((SELECT value::INT FROM config.global_flag WHERE name = 'search.max_facets_per_field' AND enabled), 1000));
+$$ LANGUAGE SQL;
+
+CREATE OR REPLACE FUNCTION search.facets_for_metarecord_set(ignore_facet_classes TEXT[], hits BIGINT[]) RETURNS TABLE (id INT, value TEXT, count BIGINT) AS $$
+    SELECT id, value, count FROM (
+        SELECT mfae.field AS id,
+               mfae.value,
+               COUNT(DISTINCT mmrsm.metarecord),
+               row_number() OVER (
+                PARTITION BY mfae.field ORDER BY COUNT(distinct mmrsm.metarecord) DESC
+               ) AS rownum
+        FROM metabib.facet_entry mfae
+        JOIN metabib.metarecord_source_map mmrsm ON (mfae.source = mmrsm.source)
+        JOIN config.metabib_field cmf ON (cmf.id = mfae.field)
+        WHERE mmrsm.metarecord IN (SELECT * FROM unnest($2))
+        AND cmf.facet_field
+        AND cmf.field_class NOT IN (SELECT * FROM unnest($1))
+        GROUP by 1, 2
+    ) all_facets
+    WHERE rownum <= (SELECT COALESCE((SELECT value::INT FROM config.global_flag WHERE name = 'search.max_facets_per_field' AND enabled), 1000));
+$$ LANGUAGE SQL;
+
+COMMIT;
+
+-- The following updates/inserts are allowed to fail
+
+INSERT INTO config.index_normalizer (name, description, func, param_count) VALUES (
+        'Number or NULL Normalize',
+        'Normalize the value to NULL if it is not a number',
+        'integer_or_null',
+        0
+);
+
+INSERT INTO config.index_normalizer (name, description, func, param_count) VALUES (
+        'Approximate Low Date Normalize',
+        'Normalize the value to the nearest date-ish value, rounding down',
+        'approximate_low_date',
+        0
+);
+
+INSERT INTO config.index_normalizer (name, description, func, param_count) VALUES (
+        'Approximate High Date Normalize',
+        'Normalize the value to the nearest date-ish value, rounding up',
+        'approximate_high_date',
+        0
+);
+
+INSERT INTO config.record_attr_index_norm_map (attr,norm,pos)
+    SELECT  m.name, i.id, 0
+      FROM  config.record_attr_definition m,
+            config.index_normalizer i
+      WHERE i.func IN ('integer_or_null')
+            AND m.name IN ('date2', 'pubdate');
+
+INSERT INTO config.record_attr_index_norm_map (attr,norm,pos)
+    SELECT  m.name, i.id, 0
+      FROM  config.record_attr_definition m,
+            config.index_normalizer i
+      WHERE i.func IN ('approximate_low_date')
+            AND m.name IN ('date1');
+
+INSERT INTO config.record_attr_index_norm_map (attr,norm,pos)
+    SELECT  m.name, i.id, 0
+      FROM  config.record_attr_definition m,
+            config.index_normalizer i
+      WHERE i.func IN ('approximate_high_date')
+            AND m.name IN ('date2');
+
+-- Get rid of bad date1 sorter values so we can avoid a reingest
+DELETE FROM metabib.record_sorter WHERE attr = 'pubdate' AND value !~ '^\d+$';
+
+-- and these are reingests that are allowed be interrupted
+\qecho
+\qecho To use the new identifier|genre index, it is necessary to do
+\qecho a partial reingest of records that have a 655 tag. You can
+\qecho cancel out of this if you wish and run this and the following
+\qecho attribute reingest later.
+\qecho
+SELECT metabib.reingest_metabib_field_entries(record, FALSE, TRUE, FALSE)
+FROM metabib.real_full_rec
+WHERE tag IN ('655')
+GROUP BY record;
+
+\qecho
+\qecho This is a record attribute reingest of your bib records.
+\qecho It will take a while.
+\qecho You may cancel now without losing the effect of the rest of the
+\qecho upgrade script, and arrange the reingest later.
+SELECT COUNT(metabib.reingest_record_attributes(id))
+    FROM biblio.record_entry WHERE deleted IS FALSE;

commit 39b1b170039353aa9f9aca472114bc3c7f51139e
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Thu Mar 17 18:50:40 2016 -0400

    forward-port the 2.10.0 upgrade instructions
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>

diff --git a/docs/installation/server_upgrade.txt b/docs/installation/server_upgrade.txt
index abf9063..0a30406 100644
--- a/docs/installation/server_upgrade.txt
+++ b/docs/installation/server_upgrade.txt
@@ -8,7 +8,7 @@ Software Prerequisites
 
  * **PostgreSQL**: Version 9.3 is recommended. The minimum supported version
     is 9.1.
-  * **Linux**: Evergreen 2.9 has been tested on Debian Jessie (8.0),
+  * **Linux**: Evergreen 2.10.0 has been tested on Debian Jessie (8.0),
     Debian Wheezy (7.0), Debian Squeeze(6.0), Ubuntu Trusty Tahr (14.04),
     Ubuntu Precise Pangolin (12.04), and Fedora.
     If you are running an older version of these distributions, you may want
@@ -43,23 +43,23 @@ osrf_control --localhost --stop-all
 +
  .. Back up the /openils directory.
 . Upgrade OpenSRF. Download and install the latest version of OpenSRF from
-the http://evergreen-ils.org/opensrf-downloads/[OpenSRF download page].
-. As the *opensrf* user, download and extract Evergreen 2.9:
+the https://evergreen-ils.org/opensrf-downloads/[OpenSRF download page].
+. As the *opensrf* user, download and extract Evergreen 2.10.0:
 +
 [source, bash]
 -----------------------------------------------
-wget http://evergreen-ils.org/downloads/Evergreen-ILS-2.9.2.tar.gz
-tar xzf Evergreen-ILS-2.9.2.tar.gz
+wget https://evergreen-ils.org/downloads/Evergreen-ILS-2.10.0.tar.gz
+tar xzf Evergreen-ILS-2.10.0.tar.gz
 -----------------------------------------------
 +
 [NOTE]
-For the latest edition of Evergreen, check the http://evergreen-ils.org/egdownloads/[Evergreen download page] and adjust upgrading instructions accordingly.
+For the latest edition of Evergreen, check the https://evergreen-ils.org/egdownloads/[Evergreen download page] and adjust upgrading instructions accordingly.
 
 . As the *root* user, install the prerequisites:
 +
 [source, bash]
 ---------------------------------------------
-cd /home/opensrf/Evergreen-ILS-2.9.2
+cd /home/opensrf/Evergreen-ILS-2.10.0
 ---------------------------------------------
 +
 On the next command, replace `[distribution]` with one of these values for your
@@ -85,7 +85,7 @@ make -f Open-ILS/src/extras/Makefile.install [distribution]
 +
 [source, bash]
 ------------------------------------------------------------
-cd /home/opensrf/Evergreen-ILS-2.9.2
+cd /home/opensrf/Evergreen-ILS-2.10.0
 PATH=/openils/bin:$PATH ./configure --prefix=/openils --sysconfdir=/openils/conf
 make
 ------------------------------------------------------------
@@ -96,8 +96,8 @@ These instructions assume that you have also installed OpenSRF under /openils/.
 +
 [source, bash]
 ------------------------------------------------------------
-cd /home/opensrf/Evergreen-ILS-2.9.2
-make STAFF_CLIENT_STAMP_ID=rel_2_9_2 install
+cd /home/opensrf/Evergreen-ILS-2.10.0
+make STAFF_CLIENT_STAMP_ID=rel_2_10_0 install
 ------------------------------------------------------------
 +
 . As the *root* user, change all files to be owned by the opensrf user and group:
@@ -113,7 +113,7 @@ chown -R opensrf:opensrf /openils
 -----------------------------------------------------------
 cd /openils/var/web/xul/
 rm server
-ln -sf rel_2_9_2/server server
+ln -sf rel_2_10_0/server server
 ----------------------------------------------------------
 +
 . As the *opensrf* user, update opensrf_core.xml and opensrf.xml by copying the
@@ -133,7 +133,7 @@ Copying these configuration files will remove any customizations you have made t
 +
 [source, bash]
 -------------------------------------------------------------------------
-cd /home/opensrf/Evergreen-ILS-2.9.2
+cd /home/opensrf/Evergreen-ILS-2.10.0
 perl Open-ILS/src/support-scripts/eg_db_config --update-config --service all \
 --create-offline --database evergreen --host localhost --user evergreen --password evergreen
 -------------------------------------------------------------------------
@@ -157,21 +157,21 @@ The diff command can be used to show the differences between the distribution ve
 +
 [source, bash]
 ----------------------------------------------------------
-cp /home/opensrf/Evergreen-ILS-2.9.2/Open-ILS/examples/apache/eg_startup /etc/apache2/eg_startup
+cp /home/opensrf/Evergreen-ILS-2.10.0/Open-ILS/examples/apache/eg_startup /etc/apache2/eg_startup
 ----------------------------------------------------------
 +
 .. Update /etc/apache2/eg_vhost.conf by copying the example from Open-ILS/examples/apache/eg_vhost.conf.
 +
 [source, bash]
 ----------------------------------------------------------
-cp /home/opensrf/Evergreen-ILS-2.9.2/Open-ILS/examples/apache/eg_vhost.conf /etc/apache2/eg_vhost.conf
+cp /home/opensrf/Evergreen-ILS-2.10.0/Open-ILS/examples/apache/eg_vhost.conf /etc/apache2/eg_vhost.conf
 ----------------------------------------------------------
 +
 .. Update /etc/apache2/sites-available/eg.conf by copying the example from Open-ILS/examples/apache/eg.conf.
 +
 [source, bash]
 ----------------------------------------------------------
-cp /home/opensrf/Evergreen-ILS-2.9.2/Open-ILS/examples/apache/eg.conf /etc/apache2/sites-available/eg.conf
+cp /home/opensrf/Evergreen-ILS-2.10.0/Open-ILS/examples/apache/eg.conf /etc/apache2/sites-available/eg.conf
 ----------------------------------------------------------
 
 Upgrade the Evergreen database schema
@@ -194,7 +194,7 @@ anything goes wrong during the upgrade.
 =============
 Evergreen provides incremental upgrade scripts that allow you to upgrade
 from one minor version to the next until you have the current version of
-the schema. For example, if you want to upgrade from 2.5.1 to 2.9.2, you
+the schema. For example, if you want to upgrade from 2.5.1 to 2.10.0, you
 would run the following upgrade scripts:
 
 - 2.5.1-2.5.2-upgrade-db.sql
@@ -214,13 +214,15 @@ would run the following upgrade scripts:
 - 2.8.4-2.9.0-upgrade-db.sql (this is a major version upgrade)
 - 2.9.0-2.9.1-upgrade-db.sql
 - 2.9.1-2.9.2-upgrade-db.sql
+- 2.9.2-2.9.3-upgrade-db.sql
+- 2.9.3-2.10.0-upgrade-db.sql
 
 Note that you do *not* want to run additional 2.5 scripts to upgrade to the
 newest version of 2.5, since currently there is no automated way to upgrade
 from 2.5.4+ to 2.6. Only upgrade as far as necessary to reach the major
 version upgrade script (in this example, as far as 2.5.3).
 
-To upgrade across multiple major versions (e.g. from 2.3.0 to 2.9.2), use
+To upgrade across multiple major versions (e.g. from 2.3.0 to 2.10.0), use
 the same logic to utilize the provided major version upgrade scripts. For
 example:
 
@@ -236,13 +238,14 @@ example:
 - 2.7.4-2.8.0-upgrade-db.sql
 - (run all incremental scripts from 2.8.0 to 2.8.4)
 - 2.8.4-2.9.0-upgrade-db.sql
-- (run all incremental scripts from 2.9.0 to 2.9.2)
+- (run all incremental scripts from 2.9.0 to 2.9.3)
+- 2.9.3-2.10.0-upgrade-db.sql
 =============
 
 [CAUTION]
 Pay attention to error output as you run the upgrade scripts. If you encounter errors
 that you cannot resolve yourself through additional troubleshooting, please
-report the errors to the http://evergreen-ils.org/communicate/mailing-lists/[Evergreen
+report the errors to the https://evergreen-ils.org/communicate/mailing-lists/[Evergreen
 Technical Discussion List].
 
 Run the following steps (including other upgrade scripts, as noted above)
@@ -250,8 +253,8 @@ as a user with the ability to connect to the database server.
 
 [source, bash]
 ----------------------------------------------------------
-cd /home/opensrf/Evergreen-ILS-2.9.2/Open-ILS/src/sql/Pg
-psql -U evergreen -h localhost -f version-upgrade/2.8.4-2.9.0-upgrade-db.sql evergreen
+cd /home/opensrf/Evergreen-ILS-2.10.0/Open-ILS/src/sql/Pg
+psql -U evergreen -h localhost -f version-upgrade/2.9.3-2.10.0-upgrade-db.sql evergreen
 ----------------------------------------------------------
 
 [TIP]
@@ -332,6 +335,6 @@ from the Evergreen community.
 Review Release Notes
 ~~~~~~~~~~~~~~~~~~~~
 
-Review the <<_evergreen_2_9_release_notes,2.9 release notes>> for other tasks
+Review the <<_evergreen_2_10_release_notes,2.10 release notes>> for other tasks
 that need to be done after upgrading.  If you have upgraded over several 
 major versions, you will need to review the release notes for each version also.

-----------------------------------------------------------------------

Summary of changes:
 .../Pg/version-upgrade/2.9.3-2.10.0-upgrade-db.sql | 4645 ++++++++++++++++++++
 docs/installation/server_upgrade.txt               |   47 +-
 2 files changed, 4670 insertions(+), 22 deletions(-)
 create mode 100644 Open-ILS/src/sql/Pg/version-upgrade/2.9.3-2.10.0-upgrade-db.sql


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list