xref: /webtrees/app/Module/CensusAssistantModule.php (revision 3d7a8a4ca809135634f38216b734b15acff479f7)
1<?php
2namespace Fisharebest\Webtrees\Module;
3
4/**
5 * webtrees: online genealogy
6 * Copyright (C) 2015 webtrees development team
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18use Fisharebest\Webtrees\Controller\SimpleController;
19use Fisharebest\Webtrees\Family;
20use Fisharebest\Webtrees\Filter;
21use Fisharebest\Webtrees\Functions\FunctionsDb;
22use Fisharebest\Webtrees\GedcomRecord;
23use Fisharebest\Webtrees\GedcomTag;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Individual;
26use Fisharebest\Webtrees\Note;
27
28/**
29 * Class CensusAssistantModule
30 */
31class CensusAssistantModule extends AbstractModule {
32	/** {@inheritdoc} */
33	public function getTitle() {
34		return /* I18N: Name of a module */ I18N::translate('Census assistant');
35	}
36
37	/** {@inheritdoc} */
38	public function getDescription() {
39		return /* I18N: Description of the “Census assistant” module */ I18N::translate('An alternative way to enter census transcripts and link them to individuals.');
40	}
41
42	/** {@inheritdoc} */
43	public function modAction($mod_action) {
44		switch ($mod_action) {
45		case 'census_find':
46			self::censusFind();
47			break;
48		case 'media_find':
49			self::mediaFind();
50			break;
51		case 'media_query_3a':
52			self::mediaQuery();
53			break;
54		default:
55			http_response_code(404);
56		}
57	}
58
59	/**
60	 * ...
61	 */
62	private static function censusFind() {
63		global $WT_TREE;
64
65		$controller = new SimpleController;
66
67		$filter   = Filter::get('filter');
68		$action   = Filter::get('action');
69		$callback = Filter::get('callback');
70		$multiple = Filter::getBool('multiple');
71
72		$controller
73			->setPageTitle(I18N::translate('Find an individual'))
74			->pageHeader();
75
76		?>
77		<script>
78			function pasterow(id, nam, mnam, label, gend, cond, dom, dob, dod, occu, age, birthpl, fbirthpl, mbirthpl, chilBLD) {
79				window.opener.insertRowToTable(id, nam, mnam, label, gend, cond, dom, dob, dod, occu, age, birthpl, fbirthpl, mbirthpl, chilBLD);
80				<?php if (!$multiple) echo "window.close();"; ?>
81			}
82
83			function pasteid(id, name, thumb) {
84				if (thumb) {
85					window.opener.<?php echo $callback; ?>(id, name, thumb);
86					<?php if (!$multiple) echo "window.close();"; ?>
87				} else {
88					// GEDFact_assistant ========================
89					if (window.opener.document.getElementById('addlinkQueue')) {
90						window.opener.insertRowToTable(id, name);
91					}
92					window.opener.<?php echo $callback; ?>(id);
93					if (window.opener.pastename) {
94						window.opener.pastename(name);
95					}
96					<?php if (!$multiple) echo "window.close();"; ?>
97				}
98			}
99		</script>
100		<?php
101
102		echo "<div align=\"center\">";
103		echo "<table class=\"list_table width90\" border=\"0\">";
104		echo "<tr><td style=\"padding: 10px;\" valign=\"top\" class=\"facts_label03 width90\">";
105		echo I18N::translate('Find an individual');
106		echo "</td>";
107		echo "</table>";
108		echo "<br>";
109
110		if ($action == "filter") {
111			$filter       = trim($filter);
112			$filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter));
113
114			// Output Individual for GEDFact Assistant ======================
115			echo "<table class=\"tabs_table width90\">";
116			$myindilist = FunctionsDb::searchIndividualNames($filter_array, array($WT_TREE));
117			if ($myindilist) {
118				echo "<tr><td class=\"list_value_wrap\"><ul>";
119				usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare');
120				foreach ($myindilist as $indi) {
121					$nam       = $indi->getAllNames();
122					$wholename = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
123					$fulln     = rtrim($nam[0]['givn'], '*') . "&nbsp;" . $nam[0]['surname'];
124					$fulln     = str_replace('"', '\'', $fulln); // Replace double quotes
125					$fulln     = str_replace("@N.N.", "(" . I18N::translate('unknown') . ")", $fulln);
126					$fulln     = str_replace("@P.N.", "(" . I18N::translate('unknown') . ")", $fulln);
127					$givn      = rtrim($nam[0]['givn'], '*');
128					$surn      = $nam[0]['surname'];
129					if (isset($nam[1])) {
130						$fulmn = rtrim($nam[1]['givn'], '*') . "&nbsp;" . $nam[1]['surname'];
131						$fulmn = str_replace('"', '\'', $fulmn); // Replace double quotes
132						$fulmn = str_replace("@N.N.", "(" . I18N::translate('unknown') . ")", $fulmn);
133						$fulmn = str_replace("@P.N.", "(" . I18N::translate('unknown') . ")", $fulmn);
134						$marn  = $nam[1]['surname'];
135					} else {
136						$fulmn = $fulln;
137					}
138
139					//-- Build Indi Parents Family to get FBP and MBP  -----------
140					foreach ($indi->getChildFamilies() as $family) {
141						$father = $family->getHusband();
142						$mother = $family->getWife();
143						if (!is_null($father)) {
144							$FBP = $father->getBirthPlace();
145						}
146						if (!is_null($mother)) {
147							$MBP = $mother->getBirthPlace();
148						}
149					}
150					if (!isset($FBP)) { $FBP = "UNK, UNK, UNK, UNK"; }
151					if (!isset($MBP)) { $MBP = "UNK, UNK, UNK, UNK"; }
152
153					//-- Build Indi Spouse Family to get marriage Date ----------
154					foreach ($indi->getSpouseFamilies() as $family) {
155						$marrdate = $family->getMarriageDate();
156						$marrdate = ($marrdate->minimumJulianDay() + $marrdate->maximumJulianDay()) / 2; // Julian
157						$children = $family->getChildren();
158					}
159					if (!isset($marrdate)) { $marrdate = ""; }
160
161					//-- Get Children’s Name, DOB, DOD --------------------------
162					$chBLDarray = array();
163					if (isset($children)) {
164						foreach ($children as $key => $child) {
165							$chnam                       = $child->getAllNames();
166							$chfulln                     = rtrim($chnam[0]['givn'], '*') . " " . $chnam[0]['surname'];
167							$chfulln                     = str_replace('"', "", $chfulln); // Must remove quotes completely here
168							$chfulln                     = str_replace("@N.N.", "(" . I18N::translate('unknown') . ")", $chfulln);
169							$chfulln                     = str_replace("@P.N.", "(" . I18N::translate('unknown') . ")", $chfulln); // Child’s Full Name
170							$chdob                       = ($child->getBirthDate()->minimumJulianDay() + $child->getBirthDate()->maximumJulianDay()) / 2; // Child’s Date of Birth (Julian)
171							if (!isset($chdob)) { $chdob = ""; }
172							$chdod                       = ($child->getDeathDate()->minimumJulianDay() + $child->getDeathDate()->maximumJulianDay()) / 2; // Child’s Date of Death (Julian)
173							if (!isset($chdod)) { $chdod = ""; }
174							$chBLD                       = ($chfulln . ", " . $chdob . ", " . $chdod);
175							array_push($chBLDarray, $chBLD);
176						}
177					}
178					if ($chBLDarray && $indi->getSex() == "F") {
179						$chBLDarray = implode("::", $chBLDarray);
180					} else {
181						$chBLDarray = '';
182					}
183
184					echo "<li>";
185					// ==============================================================================================================================
186					// NOTES = is equivalent to= function pasterow(id, nam, mnam, label, gend, cond, dom, dob, age, dod, occu, birthpl, fbirthpl, mbirthpl, chilBLD) {
187					// ==============================================================================================================================
188					echo "<a href=\"#\" onclick=\"window.opener.insertRowToTable(";
189					echo "'" . $indi->getXref() . "', "; // id        - Indi Id
190					echo "'" . addslashes(strip_tags($fulln)) . "', "; // nam       - Name
191					echo "'" . addslashes(strip_tags($fulmn)) . "', "; // mnam      - Married Name
192					echo "'-', "; // label     - Relation to Head of Household
193					echo "'" . $indi->getSex() . "', "; // gend      - Sex
194					echo "'S', "; // cond      - Marital Condition
195					echo "'" . $marrdate . "', "; // dom       - Date of Marriage
196					echo "'" . (($indi->getBirthDate()->minimumJulianDay() + $indi->getBirthDate()->maximumJulianDay()) / 2) . "' ,"; // dob       - Date of Birth
197					echo "'" . (1901 - $indi->getbirthyear()) . "' ,"; // ~age~     - Census Date minus YOB (Preliminary)
198					echo "'" . (($indi->getDeathDate()->minimumJulianDay() + $indi->getDeathDate()->maximumJulianDay()) / 2) . "' ,"; // dod       - Date of Death
199					echo "'', "; // occu      - Occupation
200					echo "'" . Filter::escapeHtml($indi->getbirthplace()) . "', "; // birthpl   - Birthplace
201					echo "'" . $FBP . "', "; // fbirthpl  - Father’s Birthplace
202					echo "'" . $MBP . "', "; // mbirthpl  - Mother’s Birthplace
203					echo "'" . $chBLDarray . "'"; // chilBLD   - Array of Children (name, birthdate, deathdate)
204					echo ");";
205					echo "return false;\">";
206					echo "<b>" . $indi->getFullName() . "</b>&nbsp;&nbsp;&nbsp;"; // Name Link
207					echo "</span><br><span class=\"list_item\">", GedcomTag::getLabel('BIRT', $indi), " ", $indi->getbirthyear(), "&nbsp;&nbsp;&nbsp;", $indi->getbirthplace(), "</span>";
208					echo "</a>";
209					echo "</li>";
210					echo "<hr>";
211				}
212				echo '</ul></td></tr>';
213			} else {
214				echo "<tr><td class=\"list_value_wrap\">";
215				echo I18N::translate('No results found.');
216				echo "</td></tr>";
217			}
218			echo "</table>";
219		}
220		echo '<button onclick="window.close();">', I18N::translate('close'), '</button>';
221		echo "</div>"; // Close div that centers table
222	}
223
224	/**
225	 * ...
226	 */
227	private static function mediaFind() {
228		global $WT_TREE;
229
230		$controller = new SimpleController;
231		$filter     = Filter::get('filter');
232		$multiple   = Filter::getBool('multiple');
233
234		$controller
235			->setPageTitle(I18N::translate('Find an individual'))
236			->pageHeader();
237
238		echo '<script>';
239		?>
240
241			function pasterow(id, name, gend, yob, age, bpl) {
242				window.opener.opener.insertRowToTable(id, name, '', gend, '', yob, age, 'Y', '', bpl);
243			}
244
245			function pasteid(id, name, thumb) {
246				if (thumb) {
247					window.opener.paste_id(id, name, thumb);
248					<?php if (!$multiple) echo "window.close();"; ?>
249				} else {
250					// GEDFact_assistant ========================
251					if (window.opener.document.getElementById('addlinkQueue')) {
252						window.opener.insertRowToTable(id, name);
253					}
254					window.opener.paste_id(id);
255					if (window.opener.pastename) {
256						window.opener.pastename(name);
257					}
258					<?php if (!$multiple) echo "window.close();"; ?>
259				}
260			}
261			function checknames(frm) {
262				if (document.forms[0].subclick) {
263					button = document.forms[0].subclick.value;
264				} else {
265					button = "";
266				}
267				if (frm.filter.value.length<2&button!="all") {
268					alert("<?php echo I18N::translate('Please enter more than one character.'); ?>");
269					frm.filter.focus();
270					return false;
271				}
272				if (button=="all") {
273					frm.filter.value = "";
274				}
275				return true;
276			}
277		<?php
278		echo '</script>';
279
280		echo "<div align=\"center\">";
281		echo "<table class=\"list_table width90\" border=\"0\">";
282		echo "<tr><td style=\"padding: 10px;\" valign=\"top\" class=\"facts_label03 width90\">"; // start column for find text header
283		echo $controller->getPageTitle();
284		echo "</td>";
285		echo "</tr>";
286		echo "</table>";
287		echo "<br>";
288		echo '<button onclick="window.close();">', I18N::translate('close'), '</button>';
289		echo "<br>";
290
291		$filter       = trim($filter);
292		$filter_array = explode(' ', preg_replace('/ {2,}/', ' ', $filter));
293		echo "<table class=\"tabs_table width90\"><tr>";
294		$myindilist = FunctionsDb::searchIndividualNames($filter_array, array($WT_TREE));
295		if ($myindilist) {
296			echo "<td class=\"list_value_wrap\"><ul>";
297			usort($myindilist, '\Fisharebest\Webtrees\GedcomRecord::compare');
298			foreach ($myindilist as $indi) {
299				$nam = Filter::escapeHtml($indi->getFullName());
300				echo "<li><a href=\"#\" onclick=\"pasterow(
301					'" . $indi->getXref() . "' ,
302					'" . $nam . "' ,
303					'" . $indi->getSex() . "' ,
304					'" . $indi->getbirthyear() . "' ,
305					'" . (1901 - $indi->getbirthyear()) . "' ,
306					'" . $indi->getbirthplace() . "'); return false;\">
307					<b>" . $indi->getFullName() . "</b>&nbsp;&nbsp;&nbsp;";
308
309				$born = GedcomTag::getLabel('BIRT');
310				echo "</span><br><span class=\"list_item\">", $born, " ", $indi->getbirthyear(), "&nbsp;&nbsp;&nbsp;", $indi->getbirthplace(), "</span></a></li>";
311			echo "<hr>";
312			}
313			echo '</ul></td></tr><tr><td class="list_label">', I18N::translate('Total individuals: %s', count($myindilist)), '</tr></td>';
314		} else {
315			echo "<td class=\"list_value_wrap\">";
316			echo I18N::translate('No results found.');
317			echo "</td></tr>";
318		}
319		echo "</table>";
320		echo '</div>';
321	}
322
323	/**
324	 * ...
325	 */
326	private static function mediaQuery() {
327		global $WT_TREE;
328
329		$iid2 = Filter::get('iid', WT_REGEX_XREF);
330
331		$controller = new SimpleController;
332		$controller
333			->setPageTitle(I18N::translate('Link to an existing media object'))
334			->pageHeader();
335
336		$record = GedcomRecord::getInstance($iid2, $WT_TREE);
337		if ($record) {
338			$headjs = '';
339			if ($record instanceof Family) {
340				if ($record->getHusband()) {
341					$headjs = $record->getHusband()->getXref();
342				} elseif ($record->getWife()) {
343					$headjs = $record->getWife()->getXref();
344				}
345			}
346			?>
347			<script>
348			function insertId() {
349				if (window.opener.document.getElementById('addlinkQueue')) {
350					// alert('Please move this alert window and examine the contents of the pop-up window, then click OK')
351					window.opener.insertRowToTable('<?php echo $record->getXref(); ?>', '<?php echo htmlSpecialChars($record->getFullName()); ?>', '<?php echo $headjs; ?>');
352					window.close();
353				}
354			}
355			</script>
356			<?php
357
358		} else {
359			?>
360			<script>
361			function insertId() {
362				window.opener.alert('<?php echo $iid2; ?> - <?php echo I18N::translate('Not a valid individual, family, or source ID'); ?>');
363				window.close();
364			}
365			</script>
366			<?php
367		}
368		?>
369		<script>window.onLoad = insertId();</script>
370		<?php
371	}
372
373	/**
374	 * Convert custom markup into HTML
375	 *
376	 * @param Note $note
377	 *
378	 * @return string
379	 */
380	public static function formatCensusNote(Note $note) {
381		global $WT_TREE;
382
383		$headers = array(
384			'AgM'        => 'Age at first marriage',
385			'Age'        => 'Age at last birthday',
386			'Assets'     => 'Assets = Owned,Rented - Value,Rent - Radio - Farm',
387			'BIC'        => 'Born in County',
388			'BOE'        => 'Born outside England',
389			'BP'         => 'Birthplace - (Chapman format)',
390			'Birthplace' => 'Birthplace (Full format)',
391			'Bmth'       => 'Month of birth - If born within Census year',
392			'ChB'        => 'Children born alive',
393			'ChD'        => 'Children who have died',
394			'ChL'        => 'Children still living',
395			'DOB'        => 'Date of birth',
396			'Edu'        => 'Education - At School, Can Read, Can Write', // or "Cannot Read, Cannot Write" ??
397			'EmD'        => 'Employed?',
398			'EmN'        => 'Unemployed?',
399			'EmR'        => 'Employer?',
400			'Employ'     => 'Employment',
401			'Eng?'       => 'English spoken?',
402			'EngL'       => 'English spoken?, if not, Native Language',
403			'FBP'        => 'Father’s Birthplace - (Chapman format)',
404			'Health'     => 'Health - 1.Blind, 2.Deaf & Dumb, 3.Idiotic, 4.Insane, 5.Disabled etc',
405			'Home'       => 'Home Ownership - Owned/Rented-Free/Mortgaged-Farm/House-Farm Schedule number',
406			'Industry'   => 'Industry',
407			'Infirm'     => 'Infirmities - 1. Deaf & Dumb, 2. Blind, 3. Lunatic, 4. Imbecile/feeble-minded',
408			'Lang'       => 'If Foreign Born - Native Language',
409			'MBP'        => 'Mother’s Birthplace - (Chapman format)',
410			'MC'         => 'Marital Condition - Married, Single, Unmarried, Widowed or Divorced',
411			'Mmth'       => 'Month of marriage - If married during Census Year',
412			'MnsE'       => 'Months employed during Census Year',
413			'MnsU'       => 'Months unemployed during Census Year',
414			'N/A'        => 'If Foreign Born - Naturalized, Alien',
415			'NL'         => 'If Foreign Born - Native Language',
416			'Name'       => 'Full Name or Married name if married',
417			'Occupation' => 'Occupation',
418			'Par'        => 'Parentage - Father if foreign born, Mother if foreign born',
419			'Race'       => 'Race or Color - Black, White, Mulatto, Asian, Indian, Chinese etc',
420			'Relation'   => 'Relationship to Head of Household',
421			'Sex'        => 'Male or Female',
422			'Situ'       => 'Situation - Disease, Infirmity, Convict, Pauper etc',
423			'Ten'        => 'Tenure - Owned/Rented, (if owned)Free/Morgaged',
424			'Vet'        => 'War Veteran?',
425			'WH'         => 'Working at Home?',
426			'War'        => 'War or Expedition',
427			'WksU'       => 'Weeks unemployed during Census Year',
428			'YOI'        => 'If Foreign Born - Year of immigration',
429			'YON'        => 'If Foreign Born - Year of naturalization',
430			'YUS'        => 'If Foreign Born - Years in the USA',
431			'YrsM'       => 'Years Married, or Y if married in Census Year',
432		);
433
434		if (preg_match('/(.*)((?:\n.*)*)\n\.start_formatted_area\.\n(.*)((?:\n.*)*)\n.end_formatted_area\.((?:\n.*)*)/', $note->getNote(), $match)) {
435			// This looks like a census-assistant shared note
436			$title     = Filter::escapeHtml($match[1]);
437			$preamble  = Filter::escapeHtml($match[2]);
438			$header    = Filter::escapeHtml($match[3]);
439			$data      = Filter::escapeHtml($match[4]);
440			$postamble = Filter::escapeHtml($match[5]);
441
442			$fmt_headers = array();
443			foreach ($headers as $key => $value) {
444				$fmt_headers['.b.' . $key] = '<span title="' . Filter::escapeHtml($value) . '">' . $key . '</span>';
445			}
446
447			// Substitue header labels and format as HTML
448			$thead = '<tr><th>' . strtr(str_replace('|', '</th><th>', $header), $fmt_headers) . '</th></tr>';
449
450			// Format data as HTML
451			$tbody = '';
452			foreach (explode("\n", $data) as $row) {
453				$tbody .= '<tr>';
454				foreach (explode('|', $row) as $column) {
455					$tbody .= '<td>' . $column . '</td>';
456				}
457				$tbody .= '</tr>';
458			}
459
460			return
461				$title . "\n" . // The newline allows the framework to expand the details and turn the first line into a link
462				'<p>' . $preamble . '</p>' .
463				'<table class="table-census-assistant">' .
464				'<thead>' . $thead . '</thead>' .
465				'<tbody>' . $tbody . '</tbody>' .
466				'</table>' .
467				'<p>' . $postamble . '</p>';
468		} else {
469			// Not a census-assistant shared note - apply default formatting
470			return Filter::formatText($note->getNote(), $WT_TREE);
471		}
472	}
473
474	/**
475	 * Modify the “add shared note” field, to create a note using the assistant
476	 *
477	 * @param string $element_id
478	 * @param string $xref
479	 * @param string $action
480	 *
481	 * @return string
482	 */
483	public static function addNoteWithAssistantLink($element_id, $xref, $action) {
484		global $controller, $WT_TREE;
485
486		// We do not yet support family records
487		if (!GedcomRecord::getInstance($xref, $WT_TREE) instanceof Individual) {
488			return '';
489		}
490
491		// Only modify “add shared note” links on the add/edit actions.
492		// TODO: does the “edit” action work?
493		if ($action != 'add' && $action != 'edit') {
494			return '';
495		}
496
497		$controller->addInlineJavascript('
498			var pid_array=jQuery("#pid_array");
499			function set_pid_array(pa) {
500				pid_array.val(pa);
501			}
502		');
503
504		return
505			'<br>' .
506			'<input type="hidden" name="pid_array" id="pid_array" value="">' .
507			'<a href="#" onclick="return addnewnote_assisted(document.getElementById(\'' . $element_id . '\'), \'' . $xref . '\');">' .
508			I18N::translate('Create a new shared note using assistant') .
509			'</a>';
510	}
511
512	/**
513	 * Add a selector containing UK/US/FR census dates
514	 *
515	 * @param string $action
516	 * @param string $tag
517	 * @param string $element_id
518	 *
519	 * @return string
520	 */
521	public static function censusDateSelector($action, $tag, $element_id) {
522		global $controller;
523
524		if ($action == 'add' && $tag == 'CENS') {
525			$controller->addInlineJavascript('
526				function addDate(theCensDate) {
527					var ddate = theCensDate.split(", ");
528					document.getElementById("setctry").value = ddate[3];
529					document.getElementById("setyear").value = ddate[0];
530					cal_setDateField("' . $element_id . '", parseInt(ddate[0]), parseInt(ddate[1]), parseInt(ddate[2]));
531					return false;
532				}
533				function pasteAsstDate(setcy, setyr) {
534					document.getElementById(setcy+setyr).selected = true;
535					addDate(document.getElementById("selcensdate").options[document.getElementById(\'selcensdate\').selectedIndex].value);
536					return false;
537				}
538			');
539
540			return '
541				<select id="selcensdate" name="selcensdate" onchange = "if (this.options[this.selectedIndex].value!=\'\') {
542										addDate(this.options[this.selectedIndex].value);
543									}">
544					<option id="defdate" value="" selected>' . I18N::translate('Census date') . '</option>
545					<option value=""></option>
546					<option id="UK1911" class="UK"  value="1911, 3, 02, UK">UK 1911</option>
547					<option id="UK1901" class="UK"  value="1901, 2, 31, UK">UK 1901</option>
548					<option id="UK1891" class="UK"  value="1891, 3, 05, UK">UK 1891</option>
549					<option id="UK1881" class="UK"  value="1881, 3, 03, UK">UK 1881</option>
550					<option id="UK1871" class="UK"  value="1871, 3, 02, UK">UK 1871</option>
551					<option id="UK1861" class="UK"  value="1861, 3, 07, UK">UK 1861</option>
552					<option id="UK1851" class="UK"  value="1851, 2, 30, UK">UK 1851</option>
553					<option id="UK1841" class="UK"  value="1841, 5, 06, UK">UK 1841</option>
554					<option value=""></option>
555					<option id="USA1940" class="USA" value="1940, 3, 01, USA">US 1940</option>
556					<option id="USA1930" class="USA" value="1930, 3, 01, USA">US 1930</option>
557					<option id="USA1920" class="USA" value="1920, 0, 01, USA">US 1920</option>
558					<option id="USA1910" class="USA" value="1910, 3, 15, USA">US 1910</option>
559					<option id="USA1900" class="USA" value="1900, 5, 01, USA">US 1900</option>
560					<option id="USA1890" class="USA" value="1890, 5, 01, USA">US 1890</option>
561					<option id="USA1880" class="USA" value="1880, 5, 01, USA">US 1880</option>
562					<option id="USA1870" class="USA" value="1870, 5, 01, USA">US 1870</option>
563					<option id="USA1860" class="USA" value="1860, 5, 01, USA">US 1860</option>
564					<option id="USA1850" class="USA" value="1850, 5, 01, USA">US 1850</option>
565					<option id="USA1840" class="USA" value="1840, 5, 01, USA">US 1840</option>
566					<option id="USA1830" class="USA" value="1830, 5, 01, USA">US 1830</option>
567					<option id="USA1820" class="USA" value="1820, 7, 07, USA">US 1820</option>
568					<option id="USA1810" class="USA" value="1810, 7, 06, USA">US 1810</option>
569					<option id="USA1800" class="USA" value="1800, 7, 04, USA">US 1800</option>
570					<option id="USA1790" class="USA" value="1790, 7, 02, USA">US 1790</option>
571					<option value=""></option>
572					<option id="FR1951" class="FR" value="1951, 0, 01, FR">FR 1951</option>
573					<option id="FR1946" class="FR" value="1946, 0, 01, FR">FR 1946</option>
574					<option id="FR1941" class="FR" value="1941, 0, 01, FR">FR 1941</option>
575					<option id="FR1936" class="FR" value="1936, 0, 01, FR">FR 1936</option>
576					<option id="FR1931" class="FR" value="1931, 0, 01, FR">FR 1931</option>
577					<option id="FR1926" class="FR" value="1926, 0, 01, FR">FR 1926</option>
578					<option id="FR1921" class="FR" value="1921, 0, 01, FR">FR 1921</option>
579					<option id="FR1916" class="FR" value="1916, 0, 01, FR">FR 1916</option>
580					<option id="FR1911" class="FR" value="1911, 0, 01, FR">FR 1911</option>
581					<option id="FR1906" class="FR" value="1906, 0, 01, FR">FR 1906</option>
582					<option id="FR1901" class="FR" value="1901, 0, 01, FR">FR 1901</option>
583					<option id="FR1896" class="FR" value="1896, 0, 01, FR">FR 1896</option>
584					<option id="FR1891" class="FR" value="1891, 0, 01, FR">FR 1891</option>
585					<option id="FR1886" class="FR" value="1886, 0, 01, FR">FR 1886</option>
586					<option id="FR1881" class="FR" value="1881, 0, 01, FR">FR 1881</option>
587					<option id="FR1876" class="FR" value="1876, 0, 01, FR">FR 1876</option>
588					<option value=""></option>
589				</select>
590
591				<input type="hidden" id="setctry" name="setctry" value="">
592				<input type="hidden" id="setyear" name="setyear" value="">
593			';
594		} else {
595			return '';
596		}
597	}
598}
599