diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2018-09-25 12:07:19 +0200 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2018-09-25 14:53:28 +0200 |
commit | 040992884b416d5c86e3a06731f26a5b1c68d7a8 (patch) | |
tree | cbb88805176c6e7ed040ab87b8797f5e47edd61a /src | |
parent | 6e4c413aef45f681805a587938096c45e049eae2 (diff) |
JSDoc fixes
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/components/ContactDetails.vue | 25 | ||||
-rw-r--r-- | src/components/Properties/PropertyDateTime.vue | 8 | ||||
-rw-r--r-- | src/components/Properties/PropertyGroups.vue | 2 | ||||
-rw-r--r-- | src/components/Settings/SettingsAddressbookShare.vue | 11 | ||||
-rw-r--r-- | src/models/contact.js | 15 | ||||
-rw-r--r-- | src/store/addressbooks.js | 119 | ||||
-rw-r--r-- | src/store/contacts.js | 35 | ||||
-rw-r--r-- | src/store/groups.js | 20 | ||||
-rw-r--r-- | src/store/importState.js | 20 | ||||
-rw-r--r-- | src/views/Contacts.vue | 5 |
10 files changed, 157 insertions, 103 deletions
diff --git a/src/components/ContactDetails.vue b/src/components/ContactDetails.vue index 1a371a7c..a0650380 100644 --- a/src/components/ContactDetails.vue +++ b/src/components/ContactDetails.vue @@ -165,7 +165,9 @@ export default { computed: { /** + * Warning message * + * @returns {string} */ warning() { if (!this.contact.dav) { @@ -175,6 +177,8 @@ export default { /** * Contact color based on uid + * + * @returns {string} */ colorAvatar() { try { @@ -187,6 +191,8 @@ export default { /** * Header actions for the contact + * + * @returns {Array} */ contactActions() { let actions = [ @@ -209,6 +215,8 @@ export default { /** * Contact properties copied and sorted by rfcProps.fieldOrder + * + * @returns {Array} */ sortedProperties() { return this.contact.properties.slice(0).sort((a, b) => { @@ -220,6 +228,8 @@ export default { /** * Fake model to use the propertySelect component + * + * @returns {Object} */ addressbookModel() { return { @@ -229,7 +239,12 @@ export default { } }, - // usable addressbook object linked to the local contact + /** + * Usable addressbook object linked to the local contact + * + * @param {string} [addressbookId] set the addressbook id + * @returns {string} + */ addressbook: { get: function() { return this.contact.addressbook.id @@ -239,7 +254,11 @@ export default { } }, - // store getters filtered and mapped to usable object + /** + * Store getters filtered and mapped to usable object + * + * @returns {Array} + */ addressbooksOptions() { return this.addressbooks .filter(addressbook => addressbook.readOnly) @@ -307,6 +326,8 @@ export default { /** * Select a contac, and update the localContact * Fetch updated data if necessary + * + * @param {string} uid the contact uid */ selectContact(uid) { // local version of the contact diff --git a/src/components/Properties/PropertyDateTime.vue b/src/components/Properties/PropertyDateTime.vue index 264417da..bc903273 100644 --- a/src/components/Properties/PropertyDateTime.vue +++ b/src/components/Properties/PropertyDateTime.vue @@ -63,6 +63,11 @@ import propertyTitle from './PropertyTitle' * Using the Object as hared data since it's the only way * for us to forcefully omit some data (no year, or no time... etc) * and ths only common syntax between js Date, moment and VCardTime + * + * @param {Object} vcardTime ICAL.VCardTime data + * @param {string} type the input type e.g. date-time + * @param {string} locale the user locale + * @returns {string} */ let formatDateTime = function(vcardTime, type, locale) { // this is the only possibility for us to ensure @@ -111,6 +116,8 @@ let formatDateTime = function(vcardTime, type, locale) { * inside a function declaration will represent the * location of the call. So this = DatetimePicker. * Therefore we can use any props we pass through datetime-picker + * + * @returns {string} */ DatetimePicker.methods.stringify = function() { return formatDateTime(this.$parent.localValue, this.type, this.$parent.locale) @@ -154,6 +161,7 @@ export default { default: true } }, + data() { return { localValue: this.value, diff --git a/src/components/Properties/PropertyGroups.vue b/src/components/Properties/PropertyGroups.vue index be871175..2ab97b93 100644 --- a/src/components/Properties/PropertyGroups.vue +++ b/src/components/Properties/PropertyGroups.vue @@ -85,6 +85,8 @@ export default { /** * Format array of groups objects to a string for the popup * Based on the ultiselect limit + * + * @returns {string} the additional groups */ formatGroupsTitle() { return this.localValue.slice(3).join(', ') diff --git a/src/components/Settings/SettingsAddressbookShare.vue b/src/components/Settings/SettingsAddressbookShare.vue index 5faec2bb..c195b6a0 100644 --- a/src/components/Settings/SettingsAddressbookShare.vue +++ b/src/components/Settings/SettingsAddressbookShare.vue @@ -105,7 +105,10 @@ export default { /** * Share addressbook * - * @param {Object} chosenUserOrGroup + * @param {Object} data destructuring object + * @param {string} data.sharee the sharee + * @param {string} data.id id + * @param {Boolean} data.group group */ shareAddressbook({ sharee, id, group }) { let addressbook = this.addressbook @@ -114,9 +117,9 @@ export default { /** * Format responses from axios.all and add them to the option array * - * @param {Array} matches Array of matches returned from the axios request - * @param {String} query - * @param {Boolean} group + * @param {Array} matches array of matches returned from the axios request + * @param {String} query the search query + * @param {Boolean} group Is this a group? */ formatMatchResults(matches, query, group) { if (matches.length < 1) { diff --git a/src/models/contact.js b/src/models/contact.js index 9dc6ced5..de1ba9a7 100644 --- a/src/models/contact.js +++ b/src/models/contact.js @@ -55,7 +55,7 @@ export default class Contact { /** * Update internal data of this contact * - * @param {jCal} jCal + * @param {jCal} jCal jCal object from ICAL.js * @memberof Contact */ updateContact(jCal) { @@ -66,7 +66,7 @@ export default class Contact { /** * Update linked addressbook of this contact * - * @param {Object} addressbook + * @param {Object} addressbook the addressbook * @memberof Contact */ updateAddressbook(addressbook) { @@ -78,8 +78,8 @@ export default class Contact { * into a string by taking the first element * e.g. ORG:ABC\, Inc.; will output an array because of the semi-colon * - * @param {Array|string} data - * @returns string + * @param {Array|string} data the data to normalize + * @returns {string} * @memberof Contact */ firstIfArray(data) { @@ -99,6 +99,7 @@ export default class Contact { /** * Set the uid * + * @param {string} uid the uid to set * @memberof Contact */ set uid(uid) { @@ -133,7 +134,7 @@ export default class Contact { /** * Set the groups * - * @readonly + * @param {Array} groups the groups to set * @memberof Contact */ set groups(groups) { @@ -175,6 +176,7 @@ export default class Contact { /** * Set the org * + * @param {string} org the org data * @memberof Contact */ set org(org) { @@ -194,6 +196,7 @@ export default class Contact { /** * Set the title * + * @param {string} title the title * @memberof Contact */ set title(title) { @@ -213,6 +216,7 @@ export default class Contact { /** * Set the full name * + * @param {string} name the fn data * @memberof Contact */ set fullName(name) { @@ -287,6 +291,7 @@ export default class Contact { /** * Add the contact to the group * + * @param {string} group the group to add the contact to * @memberof Contact */ addToGroup(group) { diff --git a/src/store/addressbooks.js b/src/store/addressbooks.js index 669e6585..b0fb217a 100644 --- a/src/store/addressbooks.js +++ b/src/store/addressbooks.js @@ -45,7 +45,7 @@ const state = { /** * map a dav collection to our addressbook object model * - * @param {Object} addressbook + * @param {Object} addressbook the addressbook object from the cdav library * @returns {Object} */ export function mapDavCollectionToAddressbook(addressbook) { @@ -66,10 +66,10 @@ const mutations = { /** * Add addressbook into state * - * @param {Object} state Default state - * @param {Object} addressbooks Addressbook + * @param {Object} state the store data + * @param {Object} addressbook the addressbook to add */ - addAddressbooks(state, addressbook) { + addAddressbook(state, addressbook) { // extend the addressbook to the default model state.addressbooks.push(Object.assign({}, addressbookModel, addressbook)) }, @@ -77,8 +77,8 @@ const mutations = { /** * Delete addressbook * - * @param {Object} state Default state - * @param {Object} addressbooks Addressbook + * @param {Object} state the store data + * @param {Object} addressbook the addressbook to delete */ deleteAddressbook(state, addressbook) { state.addressbooks.splice(state.addressbooks.indexOf(addressbook), 1) @@ -86,8 +86,8 @@ const mutations = { /** * Toggle whether a Addressbook is Enabled - * @param {Object} context Current context - * @param {Object} addressbook + * @param {Object} context the store mutations + * @param {Object} addressbook the addressbook to toggle */ toggleAddressbookEnabled(context, addressbook) { addressbook = state.addressbooks.find(search => search.id === addressbook.id) @@ -96,9 +96,10 @@ const mutations = { /** * Rename a Addressbook - * @param {Object} context Current context - * @param {Object} data.addressbook - * @param {String} data.newName + * @param {Object} context the store mutations + * @param {Object} data destructuring object + * @param {Object} data.addressbook the addressbook to rename + * @param {String} data.newName the new name of the addressbook */ renameAddressbook(context, { addressbook, newName }) { addressbook = state.addressbooks.find(search => search.id === addressbook.id) @@ -109,9 +110,9 @@ const mutations = { * Append a list of contacts to an addressbook * and remove duplicates * - * @param {Object} state - * @param {Object} data - * @param {Object} data.addressbook the addressbook + * @param {Object} state the store data + * @param {Object} data destructuring object + * @param {Object} data.addressbook the addressbook to add the contacts to * @param {Contact[]} data.contacts array of contacts to append */ appendContactsToAddressbook(state, { addressbook, contacts }) { @@ -130,8 +131,8 @@ const mutations = { /** * Add a contact to an addressbook and overwrite if duplicate uid * - * @param {Object} state - * @param {Contact} contact + * @param {Object} state the store data + * @param {Contact} contact the contact to add */ addContactToAddressbook(state, contact) { let addressbook = state.addressbooks.find(search => search.id === contact.addressbook.id) @@ -141,7 +142,7 @@ const mutations = { /** * Delete a contact in a specified addressbook * - * @param {Object} state + * @param {Object} state the store data * @param {Contact} contact the contact to delete */ deleteContactFromAddressbook(state, contact) { @@ -152,11 +153,11 @@ const mutations = { /** * Share addressbook with a user or group * - * @param {Object} state - * @param {Object} data + * @param {Object} state the store data + * @param {Object} data destructuring object * @param {Object} data.addressbook the addressbook - * @param {String} data.sharee the sharee - * @param {Boolean} data.id id + * @param {string} data.sharee the sharee + * @param {string} data.id id * @param {Boolean} data.group group */ shareAddressbook(state, { addressbook, sharee, id, group }) { @@ -173,7 +174,7 @@ const mutations = { /** * Remove Sharee from addressbook shares list * - * @param {Object} state + * @param {Object} state the store data * @param {Object} sharee the sharee */ removeSharee(state, sharee) { @@ -190,7 +191,7 @@ const mutations = { /** * Toggle sharee's writable permission * - * @param {Object} state + * @param {Object} state the store data * @param {Object} sharee the sharee */ updateShareeWritable(state, sharee) { @@ -216,8 +217,8 @@ const actions = { /** * Retrieve and commit addressbooks * - * @param {Object} context - * @returns {Promise} fetch and commit + * @param {Object} context the store mutations + * @returns {Promise<Array>} the addressbooks */ async getAddressbooks(context) { let addressbooks = await client.addressBookHomes[0].findAllAddressBooks() @@ -228,7 +229,7 @@ const actions = { }) addressbooks.forEach(addressbook => { - context.commit('addAddressbooks', addressbook) + context.commit('addAddressbook', addressbook) }) return addressbooks @@ -237,34 +238,37 @@ const actions = { /** * Append a new address book to array of existing address books * - * @param {Object} context + * @param {Object} context the store mutations * @param {Object} addressbook The address book to append + * @returns {Promise} */ - appendAddressbook(context, addressbook) { + async appendAddressbook(context, addressbook) { return client.addressBookHomes[0].createAddressBookCollection(addressbook.displayName) .then((response) => { addressbook = mapDavCollectionToAddressbook(response) - context.commit('addAddressbooks', addressbook) + context.commit('addAddressbook', addressbook) }) .catch((error) => { throw error }) }, /** * Delete Addressbook - * @param {Object} context Current context - * @param {Object} addressbook + * @param {Object} context the store mutations Current context + * @param {Object} addressbook the addressbool to delete + * @returns {Promise} */ - deleteAddressbook(context, addressbook) { + async deleteAddressbook(context, addressbook) { return addressbook.dav.delete().then((response) => context.commit('deleteAddressbook', addressbook)) .catch((error) => { throw error }) }, /** * Toggle whether a Addressbook is Enabled - * @param {Object} context Current context - * @param {Object} addressbook + * @param {Object} context the store mutations Current context + * @param {Object} addressbook the addressbook to toggle + * @returns {Promise} */ - toggleAddressbookEnabled(context, addressbook) { + async toggleAddressbookEnabled(context, addressbook) { addressbook.dav.enabled = !addressbook.dav.enabled return addressbook.dav.update() .then((response) => context.commit('toggleAddressbookEnabled', addressbook)) @@ -273,11 +277,12 @@ const actions = { /** * Rename a Addressbook - * @param {Object} context Current context - * @param {Object} data.addressbook - * @param {String} data.newName + * @param {Object} context the store mutations Current context + * @param {Object} data.addressbook the addressbook to rename + * @param {String} data.newName the new name of the addressbook + * @returns {Promise} */ - renameAddressbook(context, { addressbook, newName }) { + async renameAddressbook(context, { addressbook, newName }) { addressbook.dav.displayname = newName return addressbook.dav.update() .then((response) => context.commit('renameAddressbook', { addressbook, newName })) @@ -288,10 +293,11 @@ const actions = { * Retrieve the contacts of the specified addressbook * and commit the results * - * @param {Object} context + * @param {Object} context the store mutations * @param {Object} importDetails = { vcf, addressbook } + * @returns {Promise} */ - getContactsFromAddressBook(context, { addressbook }) { + async getContactsFromAddressBook(context, { addressbook }) { return addressbook.dav.findAllAndFilterBySimpleProperties(['EMAIL', 'UID', 'CATEGORIES', 'FN', 'ORG']) .then((response) => { // We don't want to lose the url information @@ -318,7 +324,7 @@ const actions = { /** * - * @param {Object} context + * @param {Object} context the store mutations * @param {Object} importDetails = { vcf, addressbook } */ importContactsIntoAddressbook(context, { vcf, addressbook }) { @@ -334,7 +340,7 @@ const actions = { /** * Remove sharee from Addressbook - * @param {Object} context Current context + * @param {Object} context the store mutations Current context * @param {Object} sharee Addressbook sharee object */ removeSharee(context, sharee) { @@ -343,7 +349,7 @@ const actions = { /** * Toggle permissions of Addressbook Sharees writeable rights - * @param {Object} context Current context + * @param {Object} context the store mutations Current context * @param {Object} sharee Addressbook sharee object */ toggleShareeWritable(context, sharee) { @@ -352,7 +358,7 @@ const actions = { /** * Share Adressbook with User or Group - * @param {Object} context Current context + * @param {Object} context the store mutations Current context * @param {Object} data.addressbook the addressbook * @param {String} data.sharee the sharee * @param {Boolean} data.id id @@ -366,18 +372,23 @@ const actions = { /** * Move a contact to the provided addressbook * - * @param {Object} context - * @param {Object} data + * @param {Object} context the store mutations + * @param {Object} data destructuring object * @param {Contact} data.contact the contact to move * @param {Object} data.addressbook the addressbook to move the contact to */ - moveContactToAddressbook(context, { contact, addressbook }) { - contact.dav.move(addressbook.dav) - .then(() => { - context.commit('deleteContactFromAddressbook', contact) - context.commit('updateContactAddressbook', { contact, addressbook }) - context.commit('addContactToAddressbook', contact) - }) + async moveContactToAddressbook(context, { contact, addressbook }) { + // only local move if the contact doesn't exists on the server + if (contact.dav) { + await contact.dav.move(addressbook.dav) + .catch((error) => { + console.error(error) + OC.Notification.showTemporary(t('contacts', 'An error occurred')) + }) + } + context.commit('deleteContactFromAddressbook', contact) + context.commit('updateContactAddressbook', { contact, addressbook }) + context.commit('addContactToAddressbook', contact) } } diff --git a/src/store/contacts.js b/src/store/contacts.js index 7b577467..f8c152f5 100644 --- a/src/store/contacts.js +++ b/src/store/contacts.js @@ -54,8 +54,8 @@ const mutations = { /** * Delete a contact from the global contacts list * - * @param {Object} state - * @param {Contact} contact + * @param {Object} state the store data + * @param {Contact} contact the contact to delete */ deleteContact(state, contact) { if (state.contacts[contact.key] && contact instanceof Contact) { @@ -72,8 +72,8 @@ const mutations = { /** * Insert new contact into sorted array * - * @param {Object} state - * @param {Contact} contact + * @param {Object} state the store data + * @param {Contact} contact the contact to add */ addContact(state, contact) { if (contact instanceof Contact) { @@ -113,8 +113,8 @@ const mutations = { /** * Update a contact * - * @param {Object} state - * @param {Contact} contact + * @param {Object} state the store data + * @param {Contact} contact the contact to update */ updateContact(state, contact) { if (state.contacts[contact.key] && contact instanceof Contact) { @@ -145,8 +145,8 @@ const mutations = { /** * Update a contact * - * @param {Object} state - * @param {Contact} contact + * @param {Object} state the store data + * @param {Contact} contact the contact to update */ updateContactAddressbook(state, { contact, addressbook }) { if (state.contacts[contact.key] && contact instanceof Contact) { @@ -164,7 +164,7 @@ const mutations = { * We do not want to run the sorting function every time. * Let's only run it on additions and create an index * - * @param {Object} state + * @param {Object} state the store data */ sortContacts(state) { state.sortedContacts = Object.values(state.contacts) @@ -185,8 +185,8 @@ const mutations = { /** * Set the order key * - * @param {Object} state - * @param {string} [orderKey='displayName'] + * @param {Object} state the store data + * @param {string} [orderKey='displayName'] the order key to sort by */ setOrder(state, orderKey = 'displayName') { state.orderKey = orderKey @@ -205,10 +205,11 @@ const actions = { /** * Delete a contact from the list and from the associated addressbook * - * @param {Object} context + * @param {Object} context the store mutations * @param {Contact} contact the contact to delete */ async deleteContact(context, contact) { + // only local delete if the contact doesn't exists on the server if (contact.dav) { await contact.dav.delete() .catch((error) => { @@ -223,7 +224,7 @@ const actions = { /** * Add a contact to the list and to the associated addressbook * - * @param {Object} context + * @param {Object} context the store mutations * @param {Contact} contact the contact to delete */ async addContact(context, contact) { @@ -234,8 +235,9 @@ const actions = { /** * Replac a contact by this new object * - * @param {Object} context + * @param {Object} context the store mutations * @param {Contact} contact the contact to update + * @returns {Promise} */ async updateContact(context, contact) { let vData = ICAL.stringify(contact.vCard.jCal) @@ -259,10 +261,11 @@ const actions = { /** * Fetch the full vCard from the dav server * - * @param {Object} context + * @param {Object} context the store mutations * @param {Contact} contact the contact to fetch + * @returns {Promise} */ - fetchFullContact(context, contact) { + async fetchFullContact(context, contact) { return contact.dav.fetchCompleteData() .then(() => { let newContact = new Contact(contact.dav.data, contact.addressbook, contact.dav.url, contact.dav.etag) diff --git a/src/store/groups.js b/src/store/groups.js index e1ed9721..abd4599f 100644 --- a/src/store/groups.js +++ b/src/store/groups.js @@ -28,8 +28,8 @@ const mutations = { /** * Extract all the groups from the provided contacts * - * @param {Object} state - * @param {Contact[]} contacts + * @param {Object} state the store data + * @param {Contact[]} contacts the contacts to add * TODO: create single contact mutation */ appendGroupsFromContacts(state, contacts) { @@ -66,8 +66,8 @@ const mutations = { /** * Add contact to group and create groupif not existing * - * @param {Object} state - * @param {Object} data + * @param {Object} state the store data + * @param {Object} data destructuring object * @param {String} data.groupName the name of the group * @param {Contact} data.contact the contact */ @@ -87,8 +87,8 @@ const mutations = { /** * Remove contact from group * - * @param {Object} state - * @param {Object} data + * @param {Object} state the store data + * @param {Object} data destructuring object * @param {String} data.groupName the name of the group * @param {Contact} data.contact the contact */ @@ -110,8 +110,8 @@ const actions = { /** * Add contact and to a group * - * @param {Object} context - * @param {Object} data + * @param {Object} context the store mutations + * @param {Object} data destructuring object * @param {String} data.groupName the name of the group * @param {Contact} data.contact the contact */ @@ -122,8 +122,8 @@ const actions = { /** * Remove contact from group * - * @param {Object} context - * @param {Object} data + * @param {Object} context the store mutations + * @param {Object} data destructuring object * @param {String} data.groupName the name of the group * @param {Contact} data.contact the contact */ diff --git a/src/store/importState.js b/src/store/importState.js index 4e387ab6..024b0ac0 100644 --- a/src/store/importState.js +++ b/src/store/importState.js @@ -34,7 +34,7 @@ const mutations = { /** * Increment the number of contacts accepted * - * @param {Object} state + * @param {Object} state the store data */ incrementAccepted(state) { state.importState.accepted++ @@ -43,7 +43,7 @@ const mutations = { /** * Increment the number of contacts denied * - * @param {Object} state + * @param {Object} state the store data */ incrementDenied(state) { state.importState.denied++ @@ -52,7 +52,7 @@ const mutations = { /** * Set the total number of contacts * - * @param {Object} state + * @param {Object} state the store data * @param {String} total the total number of contacts to import */ setTotal(state, total) { @@ -62,7 +62,7 @@ const mutations = { /** * Set the address book name * - * @param {Object} state + * @param {Object} state the store data * @param {String} addressbook the name of the address book to import into */ setAddressbook(state, addressbook) { @@ -72,7 +72,7 @@ const mutations = { /** * Change stage to the indicated one * - * @param {Object} state + * @param {Object} state the store data * @param {String} stage the name of the stage ('default', 'importing', 'parsing') */ changeStage(state, stage) { @@ -88,7 +88,7 @@ const actions = { /** * Increment the number of contacts accepted * - * @param {Object} context + * @param {Object} context the store mutations */ incrementAccepted(context) { context.commit('incrementAccepted') @@ -97,7 +97,7 @@ const actions = { /** * Increment the number of contacts denied * - * @param {Object} context + * @param {Object} context the store mutations */ incrementDenied(context) { context.commit('incrementDenied') @@ -106,7 +106,7 @@ const actions = { /** * Set the total number of contacts * - * @param {Object} context + * @param {Object} context the store mutations * @param {String} total the total number of contacts to import */ setTotal(context, total) { @@ -116,7 +116,7 @@ const actions = { /** * Set the address book name * - * @param {Object} context + * @param {Object} context the store mutations * @param {String} addressbook the name of the address book to import into */ setAddressbook(context, addressbook) { @@ -126,7 +126,7 @@ const actions = { /** * Change stage to the indicated one * - * @param {Object} context + * @param {Object} context the store mutations * @param {String} stage the name of the stage ('default', 'importing', 'parsing') */ changeStage(context, stage) { diff --git a/src/views/Contacts.vue b/src/views/Contacts.vue index 245711f6..e9c236f2 100644 --- a/src/views/Contacts.vue +++ b/src/views/Contacts.vue @@ -117,6 +117,8 @@ export default { * Those filters are pretty fast, so let's only * intersect the groups contacts and the full * sorted contacts List. + * + * @returns {Array} */ contactsList() { if (this.selectedGroup === t('contacts', 'All contacts')) { @@ -257,8 +259,7 @@ export default { /** * Dispatch sorting update request to the store * - * @param {Object} state Default state - * @param {Array} addressbooks Addressbooks + * @param {string} orderKey the object key to order by */ updateSorting(orderKey = 'displayName') { this.$store.commit('setOrder', orderKey) |