diff --git a/_prototypes/your-household-lms/assets/household.js b/_prototypes/your-household-lms/assets/household.js
new file mode 100644
index 0000000000..9e8a5935b8
--- /dev/null
+++ b/_prototypes/your-household-lms/assets/household.js
@@ -0,0 +1,121 @@
+import {autoIncrementId} from './utils';
+
+export const HOUSEHOLD_MEMBERS_STORAGE_KEY = 'household-members';
+export const USER_HOUSEHOLD_MEMBER_ID = 'person_me';
+export const HOUSEHOLD_MEMBER_TYPE = 'household-member';
+export const VISITOR_TYPE = 'visitor';
+
+/**
+ * Types
+ */
+export function person(opts) {
+ if (opts.firstName === '' || opts.lastName === '') {
+ console.log('Unable to create person with data: ',
+ opts.firstName,
+ !opts.middleName,
+ !opts.lastName);
+ }
+
+ let middleName = opts.middleName || '';
+
+ return {
+ fullName: opts.firstName + ' ' + middleName + ' ' + opts.lastName,
+ firstName: opts.firstName,
+ middleName,
+ lastName: opts.lastName,
+ gender: opts.gender
+ };
+}
+
+/**
+ * Storage
+ */
+export function getUserAsHouseholdMember() {
+ return getAllHouseholdMembers().find((member) => {
+ return member['@person'].id === USER_HOUSEHOLD_MEMBER_ID;
+ });
+}
+
+export function deleteUserAsHouseholdMember() {
+ deleteHouseholdMember(USER_HOUSEHOLD_MEMBER_ID);
+}
+
+export function deleteHouseholdMember(personId) {
+ let members = getAllHouseholdMembers().filter((member) => {
+ return member['@person'].id !== personId;
+ });
+
+ sessionStorage.setItem(HOUSEHOLD_MEMBERS_STORAGE_KEY,
+ JSON.stringify(members));
+}
+
+export function updateUserAsHouseholdMember(person, memberData) {
+ let userAsHouseholdMember = getUserAsHouseholdMember();
+
+ userAsHouseholdMember
+ ? updateHouseholdMember(userAsHouseholdMember['@person'], memberData)
+ : addHouseholdMember(person, memberData, USER_HOUSEHOLD_MEMBER_ID);
+}
+
+export function updateHouseholdMember(person, memberData) {
+ let membersUpdated = getAllHouseholdMembers().map((member) => {
+ return member['@person'].id === person.id
+ ? {...member, ...memberData, '@person': {...member['@person'], ...person}}
+ : member;
+ });
+
+ sessionStorage.setItem(HOUSEHOLD_MEMBERS_STORAGE_KEY,
+ JSON.stringify(membersUpdated));
+}
+
+export function addHouseholdMember(person, memberData, id) {
+ let people = getAllHouseholdMembers() || [];
+ memberData = memberData || {};
+
+ people.push({
+ ...memberData,
+ type: memberData.type || HOUSEHOLD_MEMBER_TYPE,
+ '@person': {
+ ...person,
+ id: id || 'person' + autoIncrementId('household-members')
+ }
+ });
+
+ sessionStorage.setItem(HOUSEHOLD_MEMBERS_STORAGE_KEY, JSON.stringify(people));
+}
+
+export function getAllHouseholdMembers() {
+ return JSON.parse(sessionStorage.getItem(HOUSEHOLD_MEMBERS_STORAGE_KEY)) || [];
+}
+
+export function getHouseholdMemberByPersonId(id) {
+ return getAllHouseholdMembers().find(function(member) {
+ return member['@person'].id === id;
+ });
+}
+
+export function getMemberPersonId(member) {
+ return member['@person'].id;
+}
+
+/**
+ * Comparators
+ */
+export function isVisitor(member) {
+ return member.type === window.ONS.storage.KEYS.VISITOR_TYPE;
+}
+
+export function isHouseholdMember(member) {
+ return member.type === window.ONS.storage.KEYS.HOUSEHOLD_MEMBER_TYPE;
+}
+
+export function isOtherHouseholdMember(member) {
+ return member.type === window.ONS.storage.KEYS.HOUSEHOLD_MEMBER_TYPE &&
+ member['@person'].id !== window.ONS.storage.IDS.USER_HOUSEHOLD_MEMBER_ID;
+}
+
+export const tempAwayQuestionSentenceMap = {
+ 'studying-away': 'who is working or studying away from home',
+ 'armed-forces': 'who is a member of the armed forces',
+ 'outside-uk': 'who is staying outside the UK for 12 months'
+};
diff --git a/_prototypes/your-household-lms/assets/numbers-to-words.js b/_prototypes/your-household-lms/assets/numbers-to-words.js
new file mode 100644
index 0000000000..f59219fca8
--- /dev/null
+++ b/_prototypes/your-household-lms/assets/numbers-to-words.js
@@ -0,0 +1,146 @@
+/**
+ * Copied from:
+ * https://codereview.stackexchange.com/questions/90349/changing-number-to-words-in-javascript
+ * ===============
+ */
+var ONE_TO_NINETEEN = [
+ 'one', 'two', 'three', 'four', 'five',
+ 'six', 'seven', 'eight', 'nine', 'ten',
+ 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen',
+ 'sixteen', 'seventeen', 'eighteen', 'nineteen'
+];
+
+var TENS = [
+ 'ten', 'twenty', 'thirty', 'forty', 'fifty',
+ 'sixty', 'seventy', 'eighty', 'ninety'
+];
+
+var SCALES = ['thousand', 'million', 'billion', 'trillion'];
+
+// helper function for use with Array.filter
+function isTruthy(item) {
+ return !!item;
+}
+
+// convert a number into 'chunks' of 0-999
+function chunk(number) {
+ var thousands = [];
+
+ while(number > 0) {
+ thousands.push(number % 1000);
+ number = Math.floor(number / 1000);
+ }
+
+ return thousands;
+}
+
+// translate a number from 1-999 into English
+function inEnglish(number) {
+ var thousands, hundreds, tens, ones, words = [];
+
+ if(number < 20) {
+ return ONE_TO_NINETEEN[number - 1]; // may be undefined
+ }
+
+ if(number < 100) {
+ ones = number % 10;
+ tens = number / 10 | 0; // equivalent to Math.floor(number / 10)
+
+ words.push(TENS[tens - 1]);
+ words.push(inEnglish(ones));
+
+ return words.filter(isTruthy).join('-');
+ }
+
+ hundreds = number / 100 | 0;
+ words.push(inEnglish(hundreds));
+ words.push('hundred');
+ words.push(inEnglish(number % 100));
+
+ return words.filter(isTruthy).join(' ');
+}
+
+// append the word for a scale. Made for use with Array.map
+function appendScale(chunk, exp) {
+ var scale;
+ if (!chunk) {
+ return null;
+ }
+ scale = SCALES[exp - 1];
+ return [chunk, scale].filter(isTruthy).join(' ');
+}
+
+/**
+ * ===============
+ * End copy
+ */
+
+/**
+ * Modification - decorator
+ */
+var NUMBER_TO_POSITION_TEXT_MAP = {
+ 'one': 'first',
+ 'two': 'second',
+ 'three': 'third',
+ 'four': 'fourth',
+ 'five': 'fifth',
+ 'six': 'sixth',
+ 'seven': 'seventh',
+ 'eight': 'eighth',
+ 'nine': 'nineth',
+ 'ten': 'tenth',
+ 'eleven': 'eleventh',
+ 'twelve': 'twelveth',
+ 'thirteen': 'thirteenth',
+ 'fourteen': 'fourteenth',
+ 'fifteen': 'fifteenth',
+ 'sixteen': 'sixteenth',
+ 'seventeen': 'seventeenth',
+ 'eighteen': 'eighteenth',
+ 'nineteen': 'nineteenth',
+
+ 'twenty': 'twentieth',
+ 'thirty': 'thirtieth',
+ 'forty': 'fortieth',
+ 'fifty': 'fiftieth',
+ 'sixty': 'sixtieth',
+ 'seventy': 'seventieth',
+ 'eighty': 'eightieth',
+ 'ninety': 'ninetieth',
+ 'hundred': 'hundredth',
+
+ 'thousand': 'thousandth',
+ 'million': 'millionth',
+ 'billion': 'billionth',
+ 'trillion': 'trillionth'
+};
+
+export function numberToPositionWord(num) {
+ const str = chunk(num)
+ .map(inEnglish)
+ .map(appendScale)
+ .filter(isTruthy)
+ .reverse()
+ .join(' ');
+
+ const sub = str.split(' '),
+ lastWordDashSplitArr = sub[sub.length - 1].split('-'),
+ lastWord = lastWordDashSplitArr[lastWordDashSplitArr.length - 1],
+
+ newLastWord = (lastWordDashSplitArr.length > 1? lastWordDashSplitArr[0] + '-' : '') +
+ NUMBER_TO_POSITION_TEXT_MAP[lastWord];
+
+ /*console.log('str:', str);
+ console.log('sub:', sub);
+ console.log('lastWordDashSplitArr:', lastWordDashSplitArr);
+ console.log('lastWord:', lastWord);
+ console.log('newLastWord:', newLastWord);*/
+
+ const subCopy = [].concat(sub);
+ subCopy.pop();
+ const prefix = subCopy.join(' ');
+ const result = (prefix ? prefix + ' ' : '') + newLastWord;
+
+ // console.log('result', (prefix ? prefix + ' ' : '') + newLastWord);
+ return result;
+}
diff --git a/_prototypes/your-household-lms/assets/personal-details.js b/_prototypes/your-household-lms/assets/personal-details.js
new file mode 100644
index 0000000000..d9c9f4f5a4
--- /dev/null
+++ b/_prototypes/your-household-lms/assets/personal-details.js
@@ -0,0 +1,185 @@
+export const PERSONAL_DETAILS_KEY = 'individual-details';
+export const PERSONAL_PINS_KEY = 'individual-pins';
+
+export const personalDetailsMaritalStatusMap = {
+ 'never': {
+ description: 'Never married and never registered a same-sex civil' +
+ ' partnership'
+ },
+ 'married': {
+ description: 'Married'
+ },
+ 'registered': {
+ description: 'In a registered same-sex civil partnership'
+ },
+ 'separated-married': {
+ description: 'Separated, but still legally married'
+ },
+ 'divorced': {
+ description: 'Divorced'
+ },
+ 'former-partnership': {
+ description: 'Formerly in a same-sex civil partnership which is now' +
+ ' legally dissolved'
+ },
+ 'widowed': {
+ description: 'Widowed'
+ },
+ 'surviving-partner': {
+ description: 'Surviving partner from a same-sex civil partnership'
+ },
+ 'separated-partnership': {
+ description: 'Separated, but still legally in a same-sex civil partnership'
+ }
+};
+
+export const personalDetailsCountryMap = {
+ 'england': {
+ description: 'England'
+ },
+ 'wales': {
+ description: 'Wales'
+ },
+ 'scotland': {
+ description: 'Scotland'
+ },
+ 'northern-ireland': {
+ description: 'Northern Ireland'
+ },
+ 'republic-ireland': {
+ description: 'Republic of Ireland'
+ },
+ 'elsewhere': {
+ description: 'Elsewhere'
+ }
+};
+
+export const personalDetailsOrientationMap = {
+ 'straight': {
+ description: 'Straight or Heterosexual'
+ },
+ 'gay': {
+ description: 'Gay or Lesbian'
+ },
+ 'bisexual': {
+ description: 'Bisexual'
+ },
+ 'other': {
+ description: 'Other'
+ },
+ 'no-say': {
+ description: 'Prefer not to say'
+ }
+};
+
+export function addUpdatePersonalDetailsDOB(personId, day, month, year) {
+ let allDetails = getAllPersonalDetails(),
+ details = allDetails[personId] || {};
+
+ details['dob'] = {
+ day,
+ month,
+ year
+ };
+
+ updatePersonalDetails(personId, details);
+
+ return details;
+}
+
+export function addUpdateMaritalStatus(personId, val) {
+ let allDetails = getAllPersonalDetails(),
+ details = allDetails[personId] || {};
+
+ details['maritalStatus'] = val;
+
+ updatePersonalDetails(personId, details);
+
+ return details;
+}
+
+export function addUpdateCountry(personId, val) {
+ let allDetails = getAllPersonalDetails(),
+ details = allDetails[personId] || {};
+
+ details['country'] = val;
+
+ updatePersonalDetails(personId, details);
+
+ return details;
+}
+
+export function addUpdateOrientation(personId, val) {
+ let allDetails = getAllPersonalDetails(),
+ details = allDetails[personId] || {};
+
+ details['orientation'] = val;
+
+ updatePersonalDetails(personId, details);
+
+ return details;
+}
+
+export function addUpdateSalary(personId, val) {
+ let allDetails = getAllPersonalDetails(),
+ details = allDetails[personId] || {};
+
+ details['salary'] = val;
+
+ updatePersonalDetails(personId, details);
+
+ return details;
+}
+
+export function getPins() {
+ return JSON.parse(sessionStorage.getItem(PERSONAL_PINS_KEY)) || {};
+}
+
+export function createPinFor(personId, opts = {}) {
+ let pins = getPins();
+
+ pins[personId] = {
+ pin: _.random(10000, 99999),
+ exported: !!opts.exported
+ };
+
+ sessionStorage.setItem(PERSONAL_PINS_KEY, JSON.stringify(pins));
+
+ return pins[personId];
+}
+
+export function getPinFor(personId) {
+ return getPins()[personId];
+}
+
+export function unsetPinFor(personId) {
+ let pins = getPins();
+
+ delete pins[personId];
+
+ sessionStorage.setItem(PERSONAL_PINS_KEY, JSON.stringify(pins));
+}
+
+export function updatePersonalDetails(personId, details) {
+ sessionStorage.setItem(PERSONAL_DETAILS_KEY, JSON.stringify({
+ ...getAllPersonalDetails(),
+ [personId]: details
+ }));
+
+ return details;
+}
+
+export function getAllPersonalDetails() {
+ return JSON.parse(sessionStorage.getItem(PERSONAL_DETAILS_KEY)) || {};
+}
+
+export function getPersonalDetailsFor(personId) {
+ const storageObj = JSON.parse(sessionStorage.getItem(PERSONAL_DETAILS_KEY)) || {},
+ personObj = storageObj[personId];
+
+ if (!personObj) {
+ console.log('Personal details for ' + personId + ' not found');
+ }
+
+ return personObj;
+}
diff --git a/_prototypes/your-household-lms/assets/prototype-tools.js b/_prototypes/your-household-lms/assets/prototype-tools.js
new file mode 100644
index 0000000000..665feee9df
--- /dev/null
+++ b/_prototypes/your-household-lms/assets/prototype-tools.js
@@ -0,0 +1,143 @@
+export function tools () {
+
+ const $listLinks = $('.test-data-links'),
+
+ $createFamilyHousehold = $('
' +
+ 'Create family household '),
+
+ $createFamilyRelationships = $('' +
+ 'Create family relationships '),
+
+ familyHouseholdMembersData = [{
+ 'type': 'household-member',
+ '@person': {
+ 'fullName': 'Dave Jones',
+ 'firstName': 'Dave',
+ 'middleName': '',
+ 'lastName': 'Jones',
+ 'id': 'person_me',
+ 'gender': 'male'
+ }
+ }, {
+ 'type':
+ 'household-member',
+ '@person': {
+ 'fullName': 'Sally Jones',
+ 'firstName': 'Sally',
+ 'middleName': '',
+ 'lastName': 'Jones',
+ 'id': 'person1',
+ 'gender': 'female'
+ }
+ }, {
+ 'type': 'household-member',
+ '@person': {
+ 'fullName': 'Rebecca Jones',
+ 'firstName': 'Rebecca',
+ 'middleName': '',
+ 'lastName': 'Jones',
+ 'id': 'person2',
+ 'gender': 'female'
+ }
+ }, {
+ 'type': 'household-member',
+ '@person': {
+ 'fullName': 'Amy Jones',
+ 'firstName': 'Amy',
+ 'middleName': '',
+ 'lastName': 'Jones',
+ 'id': 'person3',
+ 'gender': 'female'
+ }
+ }],
+
+ familyHouseholdRelationshipsData = [{
+ 'personIsDescription': 'husband-wife',
+ 'personIsId': 'person1',
+ 'personToId': 'person_me',
+ 'inferred': false,
+ 'id': 1
+ }, {
+ 'personIsDescription': 'son-daughter',
+ 'personIsId': 'person2',
+ 'personToId': 'person_me',
+ 'inferred': false,
+ 'id': 2
+ }, {
+ 'personIsDescription': 'mother-father',
+ 'personIsId': 'person_me',
+ 'personToId': 'person3',
+ 'inferred': false,
+ 'id': 3
+ }, {
+ 'personIsDescription': 'son-daughter',
+ 'personIsId': 'person2',
+ 'personToId': 'person1',
+ 'inferred': false,
+ 'id': 4
+ }, {
+ 'personIsDescription': 'mother-father',
+ 'personIsId': 'person1',
+ 'personToId': 'person3',
+ 'inferred': false,
+ 'id': 5
+ }, {
+ 'personIsDescription': 'brother-sister',
+ 'personIsId': 'person3',
+ 'personToId': 'person2',
+ 'inferred': true,
+ 'id': 6
+ }],
+
+ userData = {
+ 'fullName': 'Dave Jones',
+ 'firstName': 'Dave',
+ 'middleName': '',
+ 'lastName': 'Jones'
+ };
+
+ $createFamilyHousehold.on('click', function(e) {
+ e.preventDefault();
+ clearStorage();
+ createFamilyHousehold();
+ window.location.href = '../summary?survey=lms';
+ });
+
+ $createFamilyRelationships.on('click', function(e) {
+ e.preventDefault();
+ clearStorage();
+ createFamilyHousehold();
+ createFamilyRelationships();
+ window.location.href = '../relationships-summary?survey=lms';
+ });
+
+ function prerequisites() {
+ sessionStorage.setItem('address', '12 Somewhere Close, Newport, CF12 3AB');
+ sessionStorage.setItem('address-line-1', '12');
+ sessionStorage.setItem('address-line-2', 'Somewhere close');
+ sessionStorage.setItem('county', 'Newport');
+ sessionStorage.setItem('lives-here', 'yes');
+ sessionStorage.setItem('postcode', 'CF12 3AB');
+ sessionStorage.setItem('town-city', 'Newport');
+ }
+
+ function createFamilyHousehold() {
+ prerequisites();
+ sessionStorage.setItem('user-details', JSON.stringify(userData));
+ sessionStorage.setItem(window.ONS.storage.KEYS.HOUSEHOLD_MEMBERS_STORAGE_KEY, JSON.stringify(familyHouseholdMembersData));
+ sessionStorage.setItem('household-members-increment', JSON.stringify(4));
+ }
+
+ function createFamilyRelationships() {
+ sessionStorage.setItem(window.ONS.storage.KEYS.RELATIONSHIPS_STORAGE_KEY, JSON.stringify(familyHouseholdRelationshipsData));
+ sessionStorage.setItem('relationships-increment', JSON.stringify(6));
+ }
+
+ function clearStorage() {
+ sessionStorage.clear();
+ }
+
+ $listLinks.append($createFamilyHousehold);
+ $listLinks.append($createFamilyRelationships);
+}
diff --git a/_prototypes/your-household-lms/assets/relationships.js b/_prototypes/your-household-lms/assets/relationships.js
new file mode 100644
index 0000000000..06535aed92
--- /dev/null
+++ b/_prototypes/your-household-lms/assets/relationships.js
@@ -0,0 +1,627 @@
+import {autoIncrementId, removeFromList, trailingNameS} from './utils';
+import {
+ isHouseholdMember,
+ getAllHouseholdMembers,
+ getHouseholdMemberByPersonId
+} from './household';
+
+/**
+ * Augment Underscore library
+ */
+const _ = window._ || {};
+
+export const RELATIONSHIPS_STORAGE_KEY = 'relationships';
+
+export const relationshipTypes = {
+ 'spouse': {id: 'spouse'},
+ 'child-parent': {id: 'child-parent'},
+ 'step-child-parent': {id: 'step-child-parent'},
+ 'grandchild-grandparent': {id: 'grandchild-grandparent'},
+ 'half-sibling': {id: 'half-sibling'},
+ 'sibling': {id: 'sibling'},
+ 'step-brother-sister': {id: 'step-brother-sister'},
+ 'partner': {id: 'partner'},
+ 'unrelated': {id: 'unrelated'},
+ 'other-relation': {id: 'other-relation'},
+ 'parent-in-law': {id: 'parent-in-law'},
+ 'son-daughter-in-law': {id: 'son-daughter-in-law'}
+};
+
+export const relationshipDescriptionMap = {
+ // covered
+ 'husband-wife': {
+ sentanceLabel: 'husband, wife or same sex civil partner',
+ summaryAdjective: 'husband, wife or same sex civil partner',
+ type: relationshipTypes['spouse']
+ },
+ // covered
+ 'mother-father': {
+ sentanceLabel: 'parent',
+ summaryAdjective: 'parent',
+ type: relationshipTypes['child-parent']
+ },
+ // covered
+ 'step-mother-father': {
+ sentanceLabel: 'step parent',
+ summaryAdjective: 'step parent',
+ type: relationshipTypes['step-child-parent']
+ },
+ // covered
+ 'son-daughter': {
+ sentanceLabel: 'son or daughter',
+ summaryAdjective: 'son or daughter',
+ type: relationshipTypes['child-parent']
+ },
+ // covered
+ 'half-brother-sister': {
+ sentanceLabel: 'half-brother or half-sister',
+ summaryAdjective: 'half-brother or half-sister',
+ type: relationshipTypes['half-sibling']
+ },
+ // covered
+ 'step-child': {
+ sentanceLabel: 'Stepson or stepdaughter',
+ summaryAdjective: 'stepchild',
+ type: relationshipTypes['step-child-parent']
+ },
+ // covered
+ 'grandparent': {
+ sentanceLabel: 'grandparent',
+ summaryAdjective: 'grandparent',
+ type: relationshipTypes['grandchild-grandparent']
+ },
+ // covered
+ 'grandchild': {
+ sentanceLabel: 'grandchild',
+ summaryAdjective: 'grandchild',
+ type: relationshipTypes['grandchild-grandparent']
+ },
+ // covered
+ 'brother-sister': {
+ sentanceLabel: 'brother or sister',
+ summaryAdjective: 'brother or sister',
+ type: relationshipTypes['sibling']
+ },
+ // covered
+ 'step-brother-sister': {
+ sentanceLabel: 'stepbrother or stepsister',
+ summaryAdjective: 'stepbrother or stepsister',
+ type: relationshipTypes['step-brother-sister']
+ },
+ // covered
+ 'other-relation': {
+ sentanceLabel: 'other relative',
+ summaryAdjective: 'other relative',
+ type: relationshipTypes['other-relation']
+ },
+ // covered
+ 'partner': {
+ sentanceLabel: 'partner',
+ summaryAdjective: 'partner',
+ type: relationshipTypes['partner']
+ },
+ 'same-sex-partner': {
+ sentanceLabel: 'legally registered civil partner',
+ summaryAdjective: 'legally registered civil partner',
+ type: relationshipTypes['partner']
+ },
+ 'parent-in-law': {
+ sentanceLabel: 'parent-in-law',
+ summaryAdjective: 'parent-in-law',
+ type: relationshipTypes['parent-in-law']
+ },
+ 'son-daughter-in-law': {
+ sentanceLabel: 'son-in-law or daughter-in-law',
+ summaryAdjective: 'son-in-law or daughter-in-law',
+ type: relationshipTypes['son-daughter-in-law']
+ },
+ // covered
+ 'unrelated': {
+ sentanceLabel: 'other non-relative',
+ summaryAdjective: 'other non-relative',
+ type: relationshipTypes['unrelated']
+ }
+};
+
+export const femaleAltGenderDescriptions = {
+ 'husband-wife': {
+ description: 'Wife, husband or same sex civil partner',
+ sentanceLabel: 'wife, husband or same sex civil partner',
+ summaryAdjective: 'wife, husband or same sex civil partner'
+ },
+ 'son-daughter': {
+ description: 'Daughter or son' +
+ 'Including adopted daughter or adopted son ',
+ sentanceLabel: 'daughter or son',
+ summaryAdjective: 'Daughter or son'
+ },
+ 'step-child': {
+ description: 'Stepdaughter or stepson',
+ sentanceLabel: 'stepdaughter or stepson',
+ summaryAdjective: 'stepdaughter or stepson'
+ },
+ 'son-daughter-in-law': {
+ description: 'Daughter-in-law or son-in-law',
+ sentanceLabel: 'daughter-in-law or son-in-law',
+ summaryAdjective: 'daughter-in-law or son-in-law'
+ },
+ 'brother-sister': {
+ description: 'Sister or brother',
+ sentanceLabel: 'sister or brother',
+ summaryAdjective: 'sister or brother'
+ },
+ 'step-brother-sister': {
+ description: 'Stepsister or stepbrother',
+ sentanceLabel: 'stepsister or stepbrother',
+ summaryAdjective: 'stepsister or stepbrother'
+ }
+};
+
+function nameElement(name) {
+ return '' + name + ' ';
+}
+
+function personListStr(peopleArr) {
+ if (peopleArr.length < 1) {
+ console.log(peopleArr, 'not enough people to create a list string');
+ return;
+ }
+
+ if (peopleArr.length === 1) {
+ return nameElement(peopleArr[0]);
+ }
+
+ let peopleCopy = [...peopleArr],
+ lastPerson = peopleCopy.pop();
+
+ return peopleCopy
+ .map(nameElement).join(', ') + ' and ' + nameElement(lastPerson)
+}
+
+export const relationshipSummaryTemplates = {
+ 'partnership': (person1, person2, description) => {
+ return `${nameElement(person1)} is ${nameElement(person2 + trailingNameS(person2))} ${description}`;
+ },
+ 'twoFamilyMembersToMany': (parent1, parent2, childrenArr, description) => {
+ return `${nameElement(parent1)} and ${nameElement(parent2)} are ${personListStr(childrenArr.map(name => name + trailingNameS(name)))} ${description}`;
+ },
+ 'oneFamilyMemberToMany': (parent, childrenArr, description) => {
+ return `${nameElement(parent)} is ${personListStr(childrenArr.map(name => name + trailingNameS(name)))} ${description}`;
+ },
+ 'manyToMany': (peopleArr1, peopleArr2, description) => {
+ return `${personListStr(peopleArr1)} ${peopleArr1.length > 1 ? 'are' : 'is'} ${description} to ${personListStr(peopleArr2)}`;
+ },
+ 'allMutual': (peopleArr, description) => {
+ return `${personListStr(peopleArr)} are ${description}`;
+ }
+};
+
+/**
+ * Types
+ */
+export function relationship(description, personIsId, personToId, opts = {}) {
+ return {
+ personIsDescription: description,
+ personIsId: personIsId,
+ personToId: personToId,
+ inferred: !!opts.inferred
+ };
+}
+
+/**
+ * Storage
+ */
+export function addRelationship(relationshipObj) {
+ let householdRelationships = getAllRelationships() || [],
+ item = {
+ ...relationshipObj,
+ id: autoIncrementId(RELATIONSHIPS_STORAGE_KEY)
+ };
+
+ householdRelationships.push(item);
+
+ sessionStorage.setItem(RELATIONSHIPS_STORAGE_KEY,
+ JSON.stringify(householdRelationships));
+
+ return item;
+}
+
+export function editRelationship(relationshipId, valueObject) {
+ let householdRelationships = (getAllRelationships() || []).map(function(relationship) {
+ return (relationship.id + '') === (relationshipId + '') ? {
+ ...valueObject,
+ id: relationshipId
+ } : relationship;
+ });
+
+ sessionStorage.setItem(RELATIONSHIPS_STORAGE_KEY,
+ JSON.stringify(householdRelationships));
+}
+
+export function getAllRelationships() {
+ return JSON.parse(sessionStorage.getItem(RELATIONSHIPS_STORAGE_KEY)) || [];
+}
+
+export function getAllManualRelationships() {
+ return getAllRelationships().filter((relationship) => {
+ return !relationship.inferred;
+ });
+}
+
+export function deleteAllRelationshipsForMember(personId) {
+ const householdRelationships = getAllRelationships()
+ .filter((relationship) => {
+ return !(personId === relationship.personIsId || personId === relationship.personToId);
+ });
+
+ sessionStorage.setItem(RELATIONSHIPS_STORAGE_KEY,
+ JSON.stringify(householdRelationships));
+}
+
+/**
+ * Comparators
+ */
+export function isInRelationship(personId, relationship) {
+ return relationship.personToId === personId || relationship.personIsId === personId;
+}
+
+export function isAChildInRelationship(personId, relationship) {
+ /**
+ * Guard
+ */
+ if (!isInRelationship(personId, relationship)) {
+ return false;
+ }
+
+ return (
+ relationship.personIsDescription === 'mother-father' &&
+ relationship.personToId === personId
+ ) || (
+ relationship.personIsDescription === 'son-daughter' &&
+ relationship.personIsId === personId
+ );
+}
+
+export function isASiblingInRelationship(personId, relationship) {
+ return isInRelationship(personId, relationship) &&
+ relationshipDescriptionMap[relationship.personIsDescription].type.id === 'sibling';
+}
+
+export function isAParentInRelationship(personId, relationship) {
+ /**
+ * Guard
+ */
+ if (!isInRelationship(personId, relationship)) {
+ return false;
+ }
+
+ return (
+ relationship.personIsDescription === 'mother-father' &&
+ relationship.personIsId === personId
+ ) || (
+ relationship.personIsDescription === 'son-daughter' &&
+ relationship.personToId === personId
+ );
+}
+
+export function areAnyChildrenInRelationshipNotParent(childrenIds, notParentId, relationship) {
+ /**
+ * Guard
+ * If relationship type is not child-parent
+ */
+ if (relationshipDescriptionMap[relationship.personIsDescription]
+ .type.id !== 'child-parent') {
+
+ return false;
+ }
+
+ let childIndexAsPersonIs = childrenIds.indexOf(relationship.personIsId),
+ childIndexAsPersonTo = childrenIds.indexOf(relationship.personToId);
+
+ /**
+ * Find parents with the same children
+ *
+ * If a personIs-child is not in relationship
+ * or 2 children are found in relationship
+ */
+ if (
+ (childIndexAsPersonIs === -1 && childIndexAsPersonTo === -1) ||
+ (childIndexAsPersonIs !== -1 && childIndexAsPersonTo !== -1)
+ ) {
+ return false;
+ }
+
+ /**
+ * Child must be in relationship, get child index
+ */
+ let childIndex = childIndexAsPersonIs !== -1
+ ? childIndexAsPersonIs
+ : childIndexAsPersonTo;
+
+ /**
+ * If personIs is not in relationship
+ * and child from previous relationship is a child in this relationship
+ */
+ return !isInRelationship(notParentId, relationship) &&
+ isAChildInRelationship(childrenIds[childIndex], relationship);
+}
+
+export function isRelationshipType(relationshipType, relationship) {
+ const typeOfRelationship = relationshipDescriptionMap[relationship.personIsDescription]
+ .type.id;
+
+ /**
+ * relationshipType can be an array of types
+ */
+ return _.isArray(relationshipType)
+ ? !!_.find(relationshipType, function(rType) {
+ return rType === typeOfRelationship;
+ })
+ : typeOfRelationship === relationshipType;
+}
+
+/**
+ * Retrieve people by role in relationships
+ */
+export function getParentIdFromRelationship(relationship) {
+ let parentId;
+
+ if (relationship.personIsDescription === 'mother-father') {
+ parentId = relationship.personIsId;
+ }
+
+ if (relationship.personIsDescription === 'son-daughter') {
+ parentId = relationship.personToId;
+ }
+
+ if (!parentId) {
+ console.log('Parent not found in relationship: ', relationship);
+ return false;
+ }
+
+ return parentId;
+}
+
+export function getChildIdFromRelationship(relationship) {
+ let childId;
+
+ if (relationship.personIsDescription === 'mother-father') {
+ childId = relationship.personToId;
+ }
+
+ if (relationship.personIsDescription === 'son-daughter') {
+ childId = relationship.personIsId;
+ }
+
+ if (!childId) {
+ console.log('Child not found in relationship: ', relationship);
+ return false;
+ }
+
+ return childId;
+}
+
+export function getSiblingIdFromRelationship(personId, relationship) {
+ if (!isInRelationship(personId, relationship)) {
+ console.log('Person ' + personId + ' not found in relationship: ', relationship);
+ return false;
+ }
+
+ return relationship[relationship.personIsId === personId ? 'personToId' : 'personIsId'];
+}
+
+export function getOtherPersonIdFromRelationship(personId, relationship) {
+ return relationship.personIsId === personId
+ ? relationship.personToId : relationship.personIsId;
+}
+
+export function getAllParentsOf(personId) {
+ return getAllRelationships()
+ .filter(isAChildInRelationship.bind(null, personId))
+ .map(relationship => getPersonFromMember(getHouseholdMemberByPersonId(getParentIdFromRelationship(relationship))));
+}
+
+export function getAllChildrenOf(personId) {
+ return getAllRelationships()
+ .filter(isAParentInRelationship.bind(null, personId))
+ .map(relationship => getHouseholdMemberByPersonId(getChildIdFromRelationship(relationship))['@person']);
+}
+
+export function getPersonIdFromPerson(person) {
+ return person.id;
+}
+
+export function getPersonFromMember(member) {
+ return member['@person'];
+}
+
+/**
+ * Missing relationship inference
+ */
+export const missingRelationshipInference = {
+ siblingsOf(subjectMember) {
+
+ const missingRelationships = [],
+ allRelationships = getAllRelationships(),
+ person = getPersonFromMember(subjectMember),
+ personId = person.id,
+
+ parents = getAllParentsOf(personId),
+
+ siblingIds = allRelationships
+ .filter(isASiblingInRelationship.bind(null, personId))
+ .map(getSiblingIdFromRelationship.bind(null, personId));
+
+ /**
+ * If 2 parent relationships of 'person' are found we can attempt to infer
+ * sibling relationships
+ */
+ if (parents.length === 2) {
+
+ getAllHouseholdMembers()
+ .filter(isHouseholdMember)
+ .forEach((member) => {
+
+ const memberPersonId = member['@person'].id;
+
+ /**
+ * Guard
+ * If member is the subject member
+ * or member is a parent
+ * or member already has a sibling relationship with 'person'
+ * skip member
+ */
+ if (memberPersonId === personId ||
+ memberPersonId === parents[0].id || memberPersonId === parents[1].id ||
+ siblingIds.indexOf(memberPersonId) > -1) {
+ return;
+ }
+
+ const memberParents = getAllParentsOf(memberPersonId);
+
+ /**
+ * If 2 parents of 'member' are found
+ * and they are the same parents of 'person'
+ * we have identified a missing inferred relationship
+ */
+ if (memberParents.length === 2 &&
+ _.difference(
+ parents.map(getPersonIdFromPerson),
+ memberParents.map(getPersonIdFromPerson)
+ ).length === 0) {
+
+ /**
+ * Add to missingRelationships
+ */
+ missingRelationships.push(relationship(
+ 'brother-sister',
+ person.id,
+ memberPersonId,
+ {inferred: true}
+ ));
+ }
+ });
+ }
+
+ return missingRelationships;
+ }
+};
+
+/*export function inferRelationships(relationship, personIs, personTo) {
+ var missingRelationships = [];
+
+ if (relationship.personIsDescription === 'mother-father') {
+ missingRelationships = missingRelationships.concat(
+ missingRelationshipInference.siblingsOf(personTo)
+ );
+ }
+
+ if (relationship.personIsDescription === 'son-daughter') {
+ missingRelationships = missingRelationships.concat(
+ missingRelationshipInference.siblingsOf(personIs)
+ );
+ }
+
+ $.each(missingRelationships, function(i, relationship) {
+ addRelationship(relationship);
+ });
+}*/
+
+export function findNextMissingRelationship() {
+ let householdMembers = getAllHouseholdMembers().filter(isHouseholdMember),
+ relationships = getAllRelationships(),
+ missingRelationshipMembers = [],
+ personIs = null;
+
+ /**
+ * Find the next missing relationship
+ */
+ $.each(householdMembers, function(i, member) {
+ const personId = member['@person'].id;
+
+ /**
+ * Get all relationships for this member
+ */
+ const memberRelationships = relationships.filter(function(relationship) {
+ return relationship.personIsId === personId || relationship.personToId === personId;
+ }),
+
+ memberRelationshipToIds = memberRelationships.map(function(relationship) {
+ return relationship.personIsId === personId ? relationship.personToId : relationship.personIsId;
+ }) || [];
+
+ /**
+ * If total relationships related to this member isn't equal to
+ * total household members -1, indicates missing relationship
+ */
+ if (memberRelationships.length < householdMembers.length - 1) {
+
+ /**
+ * All missing relationship members
+ */
+ missingRelationshipMembers = householdMembers.filter(function(m) {
+ return memberRelationshipToIds.indexOf(m['@person'].id) === -1 &&
+ m['@person'].id !== personId;
+ });
+
+ personIs = member;
+
+ return false;
+ }
+ });
+
+ return personIs ? {
+ personIs: personIs,
+ personTo: missingRelationshipMembers[0]
+ } : null;
+}
+
+export function getPeopleIdsMissingRelationshipsWithPerson(personId) {
+ const remainingPersonIds = getAllHouseholdMembers()
+ .filter(isHouseholdMember)
+ .map(function(member) {
+ return member['@person'].id;
+ });
+
+ /**
+ * Remove this person from the list
+ */
+ removeFromList(remainingPersonIds, personId);
+
+ $.each(getAllRelationships(), function(i, relationship) {
+ if (!isInRelationship(personId, relationship)) {
+ return;
+ }
+
+ /**
+ * Remove the other person from the remainingPersonIds list
+ */
+ removeFromList(
+ remainingPersonIds,
+ getOtherPersonIdFromRelationship(personId, relationship)
+ );
+ });
+
+ return remainingPersonIds;
+}
+
+export function getRelationshipType(relationship) {
+ return relationshipDescriptionMap[relationship.personIsDescription].type;
+}
+
+/**
+ * Retrieve from relationship group
+ */
+export function getRelationshipsWithPersonIds(relationships, idArr) {
+ return relationships.filter(function(childRelationship) {
+ return idArr.indexOf(childRelationship.personIsId) !== -1 ||
+ idArr.indexOf(childRelationship.personToId) !== -1;
+ });
+}
+
+export function getRelationshipOf(person1, person2) {
+ return getAllRelationships().find(function(relationship) {
+ return isInRelationship(person1, relationship) &&
+ isInRelationship(person2, relationship);
+ });
+}
diff --git a/_prototypes/your-household-lms/assets/utils.js b/_prototypes/your-household-lms/assets/utils.js
new file mode 100644
index 0000000000..c0898a3d80
--- /dev/null
+++ b/_prototypes/your-household-lms/assets/utils.js
@@ -0,0 +1,39 @@
+export function autoIncrementId(collection) {
+ let k = collection + '-increment',
+ id = parseInt(sessionStorage.getItem(k)) || 0;
+
+ id++;
+
+ sessionStorage.setItem(k, JSON.stringify(id));
+
+ return id;
+}
+
+export function removeFromList(list, val) {
+
+ function doRemove(item) {
+ var foundId = list.indexOf(item);
+
+ /**
+ * Guard
+ */
+ if (foundId === -1) {
+ console.log('Attempt to remove from list failed: ', list, val);
+ return;
+ }
+
+ list.splice(foundId, 1);
+ }
+
+ if (_.isArray(val)) {
+ $.each(val, function(i, item) {
+ doRemove(item);
+ });
+ } else {
+ doRemove(val);
+ }
+}
+
+export function trailingNameS(name) {
+ return name[name.length - 1] === 's' ? '\’' : '\’s';
+}
diff --git a/_prototypes/your-household-lms/bundle.js b/_prototypes/your-household-lms/bundle.js
new file mode 100644
index 0000000000..3d762a21be
--- /dev/null
+++ b/_prototypes/your-household-lms/bundle.js
@@ -0,0 +1,387 @@
+import {
+ RELATIONSHIPS_STORAGE_KEY,
+ relationshipDescriptionMap,
+ femaleAltGenderDescriptions,
+ addRelationship,
+ editRelationship,
+ getAllRelationships,
+ getAllManualRelationships,
+ deleteAllRelationshipsForMember,
+ relationshipSummaryTemplates,
+ missingRelationshipInference,
+ //inferRelationships,
+ getAllParentsOf,
+ getAllChildrenOf,
+ getParentIdFromRelationship,
+ getChildIdFromRelationship,
+ getOtherPersonIdFromRelationship,
+ isAChildInRelationship,
+ isAParentInRelationship,
+ isInRelationship,
+ areAnyChildrenInRelationshipNotParent,
+ isRelationshipType,
+ getRelationshipOf,
+ getRelationshipsWithPersonIds,
+ getPeopleIdsMissingRelationshipsWithPerson,
+ getRelationshipType,
+ findNextMissingRelationship,
+ relationship
+} from './assets/relationships';
+import {
+ HOUSEHOLD_MEMBER_TYPE,
+ VISITOR_TYPE,
+ USER_HOUSEHOLD_MEMBER_ID,
+ HOUSEHOLD_MEMBERS_STORAGE_KEY,
+ addHouseholdMember,
+ updateHouseholdMember,
+ deleteHouseholdMember,
+ getAllHouseholdMembers,
+ getUserAsHouseholdMember,
+ getHouseholdMemberByPersonId,
+ getMemberPersonId,
+ updateUserAsHouseholdMember,
+ deleteUserAsHouseholdMember,
+ isVisitor,
+ isOtherHouseholdMember,
+ isHouseholdMember,
+ person,
+ tempAwayQuestionSentenceMap
+} from './assets/household';
+import {
+ addUpdatePersonalDetailsDOB,
+ getPersonalDetailsFor,
+ addUpdateMaritalStatus,
+ addUpdateCountry,
+ addUpdateOrientation,
+ addUpdateSalary,
+
+ personalDetailsMaritalStatusMap,
+ personalDetailsCountryMap,
+ personalDetailsOrientationMap,
+
+ createPinFor,
+ getPinFor,
+ unsetPinFor
+} from './assets/personal-details';
+import {removeFromList, trailingNameS} from './assets/utils';
+
+import { numberToPositionWord } from './assets/numbers-to-words';
+
+import { tools } from './assets/prototype-tools';
+
+export const USER_STORAGE_KEY = 'user-details';
+export const INDIVIDUAL_PROXY_STORAGE_KEY = 'proxy-person';
+
+export function getAddress() {
+ let addressLines = sessionStorage.getItem('address').split(',');
+
+ return {
+ addressLine1: addressLines[0],
+ addressLine2: addressLines[1],
+ addressLine3: addressLines[2],
+ addressCounty: addressLines[4],
+ addressTownCity: addressLines[3],
+ addressPostcode: addressLines[5]
+ }
+}
+
+/**
+ * User
+ */
+export function addUserPerson(person) {
+ sessionStorage.setItem(USER_STORAGE_KEY, JSON.stringify(person));
+}
+
+export function getUserPerson() {
+ return JSON.parse(sessionStorage.getItem(USER_STORAGE_KEY));
+}
+
+/**
+ * Helpers
+ */
+function createNavItem(member) {
+ let $nodeEl = $('' +
+ ' ' +
+ ' '),
+ $linkEl = $nodeEl.find('.js-template-nav-item-label');
+
+ $linkEl.html(member['@person'].fullName);
+
+ if (member['@person'].id === USER_HOUSEHOLD_MEMBER_ID) {
+ $linkEl.attr('href', '../what-is-your-name');
+ } else {
+ $linkEl.attr('href', '../who-else-to-add?edit=' + member['@person'].id);
+ }
+
+ return $nodeEl;
+}
+
+function updateHouseholdVisitorsNavigationItems() {
+ let allHouseholdMembers = window.ONS.storage.getAllHouseholdMembers(),
+ householdMembers = allHouseholdMembers.filter(window.ONS.storage.isHouseholdMember),
+ visitors = allHouseholdMembers.filter(window.ONS.storage.isVisitor);
+
+ const $navigationHouseholdMembersEl = $('#navigation-household-members'),
+ $navigationVisitorsEl = $('#navigation-visitors');
+
+ if (householdMembers.length) {
+ $.each(householdMembers, function(i, member) {
+ $navigationHouseholdMembersEl.append(createNavItem(member));
+ });
+ } else {
+ $navigationHouseholdMembersEl.parent().hide();
+ }
+
+ if (visitors.length) {
+ $.each(visitors, function(i, member) {
+ $navigationVisitorsEl.append(createNavItem(member));
+ });
+ } else {
+ $navigationVisitorsEl.parent().hide();
+ }
+}
+
+function createListItemPerson(member) {
+ return $('').addClass('mars').html(
+ '' + member['@person'].fullName + ' '
+ );
+}
+
+function populateList($el, memberType) {
+ if (!$el.length) {
+ return;
+ }
+
+ let members = getAllHouseholdMembers() || [];
+
+ $el.empty().append(members.filter((member) => {
+ return member.type === memberType;
+ }).map(createListItemPerson));
+
+ $el.addClass('list list--people-plain');
+}
+
+function populateHouseholdList() {
+ populateList($('#household-members'), HOUSEHOLD_MEMBER_TYPE);
+}
+
+function populateVisitorList() {
+ populateList($('#visitors-list'), VISITOR_TYPE);
+}
+
+function updateAddresses() {
+ let addressLines = (sessionStorage.getItem('address') || '').split(','),
+ addressLine1 = addressLines[0],
+ addressLine2 = addressLines[1];
+
+ $('#section-address').html(addressLine1 || 'Address not' +
+ ' found ');
+ $('.address-text').html(
+ addressLine1 && addressLine2
+ ? (
+ addressLine1 + (addressLine2 ? ', ' + addressLine2 : '')
+ )
+ : 'Address not found '
+ );
+
+ $('.address-text-line1').html(addressLine1);
+
+ let personId = new URLSearchParams(window.location.search).get('person'),
+ person;
+
+ if (personId) {
+ person = getHouseholdMemberByPersonId(personId)['@person'];
+ $('#section-individual').html(person.fullName);
+
+ $('.js-person-fullname-from-url-id').html(person.fullName);
+ }
+}
+
+const secureLinkTextMap = {
+ 'question-you': {
+ description: 'Want to keep your answers secure from other people at this' +
+ ' address?',
+ linkText: 'Get a separate access code to submit an individual response',
+ link: '../individual-decision-secure'
+ },
+ 'pin-you': {
+ description: 'You\'ve chosen to keep your answers secure',
+ linkText: 'Cancel this and make answers available to the rest of the' +
+ ' household',
+ link: '../individual-decision-secure'
+ },
+ 'question-proxy': {
+ description: 'Not happy to continue answering for $[NAME]?',
+ linkText: 'Request an individual access code to be sent to them',
+ link: '../individual-decision-other-secure'
+ }
+};
+
+function updateAllPreviousLinks() {
+ $('.js-previous-link').attr('href', document.referrer);
+}
+
+function updatePersonLink() {
+ const personId = new URLSearchParams(window.location.search).get('person');
+
+ if (personId) {
+ let urlParam = new URLSearchParams(window.location.search),
+ person = getHouseholdMemberByPersonId(personId)['@person'],
+ pinObj = getPinFor(personId),
+ secureLinkTextConfig = secureLinkTextMap[
+ (getAnsweringIndividualByProxy() ? 'question-proxy' : (pinObj && pinObj.pin ? 'pin-you' : 'question-you'))
+ ],
+ linkHref = secureLinkTextConfig.link + '?person=' + personId +
+ '&returnurl=' + window.location.pathname,
+ surveyType = urlParam.get('survey');
+
+ linkHref += (surveyType ? '&survey=' + surveyType : '');
+
+ let $secureLink = $('.js-link-secure');
+ $secureLink.attr('href', linkHref);
+
+ $secureLink.html(secureLinkTextConfig.linkText);
+ $('.js-link-secure-label').html(secureLinkTextConfig.description.replace('$[NAME]', person.fullName));
+
+ let personLink = $('.js-link-person');
+ personLink.attr('href', personLink.attr('href') + '?person=' + personId +
+ (surveyType ? '&survey=' + surveyType : ''));
+ }
+}
+
+function updateBySurveyType() {
+ const urlParams = new URLSearchParams(window.location.search),
+ surveyType = urlParams.get('survey');
+
+ if (surveyType) {
+ $('.js-header-title').html(surveyTypeConfig[surveyType].title);
+ $('#people-living-here').html(surveyTypeConfig[surveyType].householdSectionTitle);
+ $('#people-living-here').attr('href', surveyTypeConfig[surveyType].householdSectionLink);
+ $('#relationships-section').attr('href', surveyTypeConfig[surveyType].relationshipsSection);
+ $('title').html(surveyTypeConfig[surveyType].title);
+ }
+}
+
+function setAnsweringIndividualByProxy(bool) {
+ sessionStorage.setItem(INDIVIDUAL_PROXY_STORAGE_KEY, JSON.stringify(bool));
+}
+
+function getAnsweringIndividualByProxy() {
+ return JSON.parse(sessionStorage.getItem(INDIVIDUAL_PROXY_STORAGE_KEY));
+}
+
+const surveyTypeConfig = {
+ lms: {
+ title: 'Online Household Study v2',
+ householdSectionTitle: 'About your household',
+ householdSectionLink: '../summary/?survey=lms',
+ relationshipsSection: '../relationships/?survey=lms'
+ }
+};
+
+window.ONS = window.ONS || {};
+window.ONS.storage = {
+ getAddress,
+ addHouseholdMember,
+ updateHouseholdMember,
+ deleteHouseholdMember,
+ getAllHouseholdMembers,
+ addUserPerson,
+ getUserPerson,
+ getUserAsHouseholdMember,
+ getHouseholdMemberByPersonId,
+ getMemberPersonId,
+ updateUserAsHouseholdMember,
+ deleteUserAsHouseholdMember,
+ tempAwayQuestionSentenceMap,
+
+ isVisitor,
+ isOtherHouseholdMember,
+ isHouseholdMember,
+
+ addRelationship,
+ editRelationship,
+ getAllRelationships,
+ getAllManualRelationships,
+ deleteAllRelationshipsForMember,
+
+ getAllParentsOf,
+ getAllChildrenOf,
+ getParentIdFromRelationship,
+ getChildIdFromRelationship,
+ getOtherPersonIdFromRelationship,
+ isAParentInRelationship,
+ isAChildInRelationship,
+ isInRelationship,
+ areAnyChildrenInRelationshipNotParent,
+ isRelationshipType,
+ getRelationshipOf,
+
+ femaleAltGenderDescriptions,
+ relationshipDescriptionMap,
+ relationshipSummaryTemplates,
+ missingRelationshipInference,
+ //inferRelationships,
+ getRelationshipsWithPersonIds,
+ getPeopleIdsMissingRelationshipsWithPerson,
+ getRelationshipType,
+ findNextMissingRelationship,
+
+ addUpdatePersonalDetailsDOB,
+ getPersonalDetailsFor,
+ addUpdateMaritalStatus,
+ addUpdateCountry,
+ addUpdateOrientation,
+ addUpdateSalary,
+
+ personalDetailsMaritalStatusMap,
+ personalDetailsCountryMap,
+ personalDetailsOrientationMap,
+
+ createPinFor,
+ getPinFor,
+ unsetPinFor,
+
+ setAnsweringIndividualByProxy,
+ getAnsweringIndividualByProxy,
+
+ KEYS: {
+ HOUSEHOLD_MEMBERS_STORAGE_KEY,
+ USER_STORAGE_KEY,
+ INDIVIDUAL_PROXY_STORAGE_KEY,
+ HOUSEHOLD_MEMBER_TYPE,
+ VISITOR_TYPE,
+ RELATIONSHIPS_STORAGE_KEY
+ },
+
+ IDS: {
+ USER_HOUSEHOLD_MEMBER_ID
+ },
+
+ TYPES: {
+ person,
+ relationship
+ }
+};
+
+window.ONS.helpers = {
+ populateHouseholdList,
+ populateVisitorList
+};
+
+window.ONS.utils = {
+ removeFromList,
+ trailingNameS,
+ numberToPositionWord
+};
+
+$(populateHouseholdList);
+$(populateVisitorList);
+$(updateHouseholdVisitorsNavigationItems);
+$(updateAddresses);
+$(updatePersonLink);
+$(tools);
+$(updateAllPreviousLinks);
+$(updateBySurveyType);
+
diff --git a/_prototypes/your-household-lms/confirm-address.html b/_prototypes/your-household-lms/confirm-address.html
new file mode 100644
index 0000000000..8877f3574e
--- /dev/null
+++ b/_prototypes/your-household-lms/confirm-address.html
@@ -0,0 +1,95 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/do-you-live-here.html b/_prototypes/your-household-lms/do-you-live-here.html
new file mode 100644
index 0000000000..4b74988c2f
--- /dev/null
+++ b/_prototypes/your-household-lms/do-you-live-here.html
@@ -0,0 +1,132 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/does-anyone-else-live-here.html b/_prototypes/your-household-lms/does-anyone-else-live-here.html
new file mode 100644
index 0000000000..972037fc18
--- /dev/null
+++ b/_prototypes/your-household-lms/does-anyone-else-live-here.html
@@ -0,0 +1,141 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/hub.html b/_prototypes/your-household-lms/hub.html
new file mode 100644
index 0000000000..9f7fdeb64a
--- /dev/null
+++ b/_prototypes/your-household-lms/hub.html
@@ -0,0 +1,247 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/i-dont-live-here.html b/_prototypes/your-household-lms/i-dont-live-here.html
new file mode 100644
index 0000000000..7232cd5be4
--- /dev/null
+++ b/_prototypes/your-household-lms/i-dont-live-here.html
@@ -0,0 +1,116 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/index.html b/_prototypes/your-household-lms/index.html
new file mode 100644
index 0000000000..d23be0bfba
--- /dev/null
+++ b/_prototypes/your-household-lms/index.html
@@ -0,0 +1,122 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome to the household prototype
+
+
+
+
+
+
+
+ Enter the unique access code
+
+
+
+
+
+
+
The unique access code
+ is printed on your invitation
+ letter or form
+
+
+
+
Your personal information is protected by law and will be kept confidential
+
+
+
+
+
+ Submit code
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-decision-other-pin.html b/_prototypes/your-household-lms/individual-decision-other-pin.html
new file mode 100644
index 0000000000..09512df581
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-decision-other-pin.html
@@ -0,0 +1,126 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-decision-other-secure.html b/_prototypes/your-household-lms/individual-decision-other-secure.html
new file mode 100644
index 0000000000..e1d7dd9dbf
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-decision-other-secure.html
@@ -0,0 +1,140 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-decision-pin.html b/_prototypes/your-household-lms/individual-decision-pin.html
new file mode 100644
index 0000000000..a4e0b10787
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-decision-pin.html
@@ -0,0 +1,112 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-decision-secure.html b/_prototypes/your-household-lms/individual-decision-secure.html
new file mode 100644
index 0000000000..f168763a01
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-decision-secure.html
@@ -0,0 +1,148 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-decision.html b/_prototypes/your-household-lms/individual-decision.html
new file mode 100644
index 0000000000..4e4d0562cc
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-decision.html
@@ -0,0 +1,122 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-details-country.html b/_prototypes/your-household-lms/individual-details-country.html
new file mode 100644
index 0000000000..3892885fe4
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-details-country.html
@@ -0,0 +1,191 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-details-dob.html b/_prototypes/your-household-lms/individual-details-dob.html
new file mode 100644
index 0000000000..0e28c58bdb
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-details-dob.html
@@ -0,0 +1,167 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-details-orientation.html b/_prototypes/your-household-lms/individual-details-orientation.html
new file mode 100644
index 0000000000..c062cfaac0
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-details-orientation.html
@@ -0,0 +1,186 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-details-relationship.html b/_prototypes/your-household-lms/individual-details-relationship.html
new file mode 100644
index 0000000000..e25e0445e1
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-details-relationship.html
@@ -0,0 +1,243 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-details-salary.html b/_prototypes/your-household-lms/individual-details-salary.html
new file mode 100644
index 0000000000..37e571a9f4
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-details-salary.html
@@ -0,0 +1,134 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-details-summary.html b/_prototypes/your-household-lms/individual-details-summary.html
new file mode 100644
index 0000000000..6a9a2f2fd1
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-details-summary.html
@@ -0,0 +1,246 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-intro.html b/_prototypes/your-household-lms/individual-intro.html
new file mode 100644
index 0000000000..2e9f8ee91d
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-intro.html
@@ -0,0 +1,83 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.yourHouseholdV4_navigationItemsPersonalDetails
+ nav-title-id="section-individual" %}
+
+
+
+
+
+
+
+
+ In this sub section, we’re going to
+ ask you questions about .
+
+
+ Information you will need:
+
+ Personal details such as date of birth, country of birth, sexual orientation and religion etc.
+ Education and qualifications
+ Employment, income and travel to work
+ Second or holiday homes
+ Unpaid care, health and well-being
+
+
+ Submitting an individual response
+ When completing this section, we will ask you if you would like to submit an
+ individual response. Choose this option if you don't want other people at this address to view
+ your answers
+
+
+
+
+ Continue
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/individual-pin-security.html b/_prototypes/your-household-lms/individual-pin-security.html
new file mode 100644
index 0000000000..f728077148
--- /dev/null
+++ b/_prototypes/your-household-lms/individual-pin-security.html
@@ -0,0 +1,121 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/do-they-share-cooking-facilities.html b/_prototypes/your-household-lms/lms/do-they-share-cooking-facilities.html
new file mode 100644
index 0000000000..5b498311ad
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/do-they-share-cooking-facilities.html
@@ -0,0 +1,88 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/do-they-share-dining-living-room.html b/_prototypes/your-household-lms/lms/do-they-share-dining-living-room.html
new file mode 100644
index 0000000000..8c7408c2ea
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/do-they-share-dining-living-room.html
@@ -0,0 +1,88 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/do-you-live-here.html b/_prototypes/your-household-lms/lms/do-you-live-here.html
new file mode 100644
index 0000000000..c86ee8cc49
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/do-you-live-here.html
@@ -0,0 +1,141 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/does-anyone-else-live-here.html b/_prototypes/your-household-lms/lms/does-anyone-else-live-here.html
new file mode 100644
index 0000000000..ec5286d9d9
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/does-anyone-else-live-here.html
@@ -0,0 +1,110 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/does-anyone-live-student-halls.html b/_prototypes/your-household-lms/lms/does-anyone-live-student-halls.html
new file mode 100644
index 0000000000..4803793c7f
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/does-anyone-live-student-halls.html
@@ -0,0 +1,127 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/i-dont-live-here.html b/_prototypes/your-household-lms/lms/i-dont-live-here.html
new file mode 100644
index 0000000000..f56574ad22
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/i-dont-live-here.html
@@ -0,0 +1,176 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/index.html b/_prototypes/your-household-lms/lms/index.html
new file mode 100644
index 0000000000..ac6b8246c9
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/index.html
@@ -0,0 +1,125 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome to the Online Household Study
+
+
+
+
+
+
+
+ Enter the unique access code
+
+
+
+
+
+
+
The unique access code
+ is printed on your invitation
+ letter or form
+
+
+
+
Your personal
+ information is protected by law and will be
+ kept confidential. Responses are saved at
+ the end of each age and may be used even if
+ you have not fully completed the study.
+
+
+
+
+ Submit code
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/is-there-does-anyone-else-student-halls.html b/_prototypes/your-household-lms/lms/is-there-does-anyone-else-student-halls.html
new file mode 100644
index 0000000000..bb66dd3489
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/is-there-does-anyone-else-student-halls.html
@@ -0,0 +1,103 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/what-is-your-name.html b/_prototypes/your-household-lms/lms/what-is-your-name.html
new file mode 100644
index 0000000000..996da74ead
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/what-is-your-name.html
@@ -0,0 +1,139 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Enter your details
+
+
+
+ Enter your details
+
+
+
+
+
+ My first or given name
+
+
+
+
+
+
+
+
+ My surname or family name
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save and continue
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/who-else-to-add.html b/_prototypes/your-household-lms/lms/who-else-to-add.html
new file mode 100644
index 0000000000..b31bedf4cf
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/who-else-to-add.html
@@ -0,0 +1,187 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Please enter the details of the other people
+ who live at
+
+
+
+
Include all
+ adults, children and babies who class this
+ as their main residence, even if they
+ are currently away for a continuous
+ period of up to 6 months
+
+
+
+
+
+
+
+ What is your name?
+
+
+
+
+
+ First or given name
+
+
+
+
+
+
+
+
+ Surname or family name
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save and continue
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/lms/who-owns-rents-accommodation.html b/_prototypes/your-household-lms/lms/who-owns-rents-accommodation.html
new file mode 100644
index 0000000000..5897135a3a
--- /dev/null
+++ b/_prototypes/your-household-lms/lms/who-owns-rents-accommodation.html
@@ -0,0 +1,120 @@
+---
+title: Online Household Study v2
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/relationships-person-select.html b/_prototypes/your-household-lms/relationships-person-select.html
new file mode 100644
index 0000000000..ecf54a8c1f
--- /dev/null
+++ b/_prototypes/your-household-lms/relationships-person-select.html
@@ -0,0 +1,290 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+householdMembers:
+visitors:
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.navigationItemsRelationships
+ nav-title-id="section-address" %}
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/relationships-summary.html b/_prototypes/your-household-lms/relationships-summary.html
new file mode 100644
index 0000000000..f43e3a797b
--- /dev/null
+++ b/_prototypes/your-household-lms/relationships-summary.html
@@ -0,0 +1,997 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+householdMembers:
+visitors:
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.navigationItemsRelationships
+ nav-title-id="section-address" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/relationships.html b/_prototypes/your-household-lms/relationships.html
new file mode 100644
index 0000000000..09c60250e2
--- /dev/null
+++ b/_prototypes/your-household-lms/relationships.html
@@ -0,0 +1,507 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+householdMembers:
+visitors:
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.navigationItemsRelationships
+ nav-title-id="section-address" %}
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/section-intro.html b/_prototypes/your-household-lms/section-intro.html
new file mode 100644
index 0000000000..b7866b2b82
--- /dev/null
+++ b/_prototypes/your-household-lms/section-intro.html
@@ -0,0 +1,74 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ People who live here
+
+ In this sub section, we’re going to
+ ask you about all the people that live at or
+ are visiting .
+
+
+ Information you will need:
+
+ Names of the people living at this
+ address
+ Names of the visitors staying in the
+ household on 20 July 2018
+
+
+
+
+
+
+ Continue
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/style.css b/_prototypes/your-household-lms/style.css
new file mode 100644
index 0000000000..c561320991
--- /dev/null
+++ b/_prototypes/your-household-lms/style.css
@@ -0,0 +1,36 @@
+.list.list--people-plain {
+ margin-bottom : 1rem;
+ list-style-type : none;
+}
+
+.list.list--people-plain .list__item {
+ background: url(/img/icons/person.svg) 0 .2rem no-repeat;
+}
+
+.list.list--people-plain .list__item-name {
+ padding-left: 1.5rem;
+}
+
+.list.list--people-plain .list__item-actions {
+ margin-top: -4px;
+}
+
+.list.list--people-plain .list__item-action + .list__item-action {
+ margin-left : .5rem;
+}
+
+/**
+ * Pattern library fix
+ */
+.header {
+ margin-bottom : 0;
+}
+
+.lock {
+ padding-left : 1.5rem;
+ background : url('../img/icons/lockicon.svg') no-repeat left top;
+}
+
+.footer {
+ margin-top : 7rem;
+}
diff --git a/_prototypes/your-household-lms/summary.html b/_prototypes/your-household-lms/summary.html
new file mode 100644
index 0000000000..0175be0621
--- /dev/null
+++ b/_prototypes/your-household-lms/summary.html
@@ -0,0 +1,293 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+ {% include navigation.html
+ items=site.data.your-household-v4.navigationItemsHousehold
+ nav-title-id="section-address" %}
+
+
+
+
+
+
+
+
Are you sure you want to remove ?
+
All of the data associated with this person will be
+ deleted
+
+
+ Cancel
+
+
+ Confirm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/temp-away-from-home.html b/_prototypes/your-household-lms/temp-away-from-home.html
new file mode 100644
index 0000000000..2df225834f
--- /dev/null
+++ b/_prototypes/your-household-lms/temp-away-from-home.html
@@ -0,0 +1,101 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/temp-living-here-feedback.html b/_prototypes/your-household-lms/temp-living-here-feedback.html
new file mode 100644
index 0000000000..6a2f7283b6
--- /dev/null
+++ b/_prototypes/your-household-lms/temp-living-here-feedback.html
@@ -0,0 +1,97 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/temp-living-here.html b/_prototypes/your-household-lms/temp-living-here.html
new file mode 100644
index 0000000000..27042ab4eb
--- /dev/null
+++ b/_prototypes/your-household-lms/temp-living-here.html
@@ -0,0 +1,111 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/temp-types-feedback.html b/_prototypes/your-household-lms/temp-types-feedback.html
new file mode 100644
index 0000000000..0b00592bc1
--- /dev/null
+++ b/_prototypes/your-household-lms/temp-types-feedback.html
@@ -0,0 +1,115 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/temp-types-living-away.html b/_prototypes/your-household-lms/temp-types-living-away.html
new file mode 100644
index 0000000000..05b87e6fdf
--- /dev/null
+++ b/_prototypes/your-household-lms/temp-types-living-away.html
@@ -0,0 +1,150 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/temp-types-question.html b/_prototypes/your-household-lms/temp-types-question.html
new file mode 100644
index 0000000000..18c769bbf7
--- /dev/null
+++ b/_prototypes/your-household-lms/temp-types-question.html
@@ -0,0 +1,134 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/test-address.html b/_prototypes/your-household-lms/test-address.html
new file mode 100644
index 0000000000..9821d7e3e8
--- /dev/null
+++ b/_prototypes/your-household-lms/test-address.html
@@ -0,0 +1,227 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ What is your address?
+
+
+
+
+ What is your address?
+
+
+
+
+
+
+
+
+
+
+
+ Town or City
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ County (optional)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Postcode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Continue
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/test-data.html b/_prototypes/your-household-lms/test-data.html
new file mode 100644
index 0000000000..627703a9d7
--- /dev/null
+++ b/_prototypes/your-household-lms/test-data.html
@@ -0,0 +1,42 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/visitors.html b/_prototypes/your-household-lms/visitors.html
new file mode 100644
index 0000000000..f3f6d31ea6
--- /dev/null
+++ b/_prototypes/your-household-lms/visitors.html
@@ -0,0 +1,148 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/what-is-your-name.html b/_prototypes/your-household-lms/what-is-your-name.html
new file mode 100644
index 0000000000..135c70b587
--- /dev/null
+++ b/_prototypes/your-household-lms/what-is-your-name.html
@@ -0,0 +1,118 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ What is your name?
+
+
+
+ What is your name?
+
+
+
+
+
+
+
+
+ Save and continue
+
+
+
+
+
+
+
+
+
+
diff --git a/_prototypes/your-household-lms/who-else-to-add.html b/_prototypes/your-household-lms/who-else-to-add.html
new file mode 100644
index 0000000000..e8e5094c95
--- /dev/null
+++ b/_prototypes/your-household-lms/who-else-to-add.html
@@ -0,0 +1,177 @@
+---
+title: Household prototype v4
+project: your-household
+globalcss: false
+layout: eq-default-extras
+cdn: v1.5.0
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Who do you need to add to
+
+
+
+
+
+ What is your name?
+
+
+
+
+
+
+
+
+ Save and continue
+
+
+
+
+
+
+
+
+
+