From 6d6217a6d400a9aa48c3bc50afe1bd0db4931109 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 21 Sep 2018 13:55:40 +0200 Subject: [PATCH 01/34] Enhancements for #98 --- CHANGELOG.json | 11 ++++++++ CHANGELOG.md | 6 ++++ .../documentation/docs/about/release-notes.md | 6 ++++ .../controls/PropertyFieldCollectionData.md | 1 + .../collectionData/ICustomCollectionField.ts | 4 +++ .../collectionDataItem/CollectionDataItem.tsx | 2 ++ .../CollectionIconField.tsx | 12 ++++---- .../CollectionNumberField.tsx | 28 +++++++++++++++++-- .../ICollectionNumberFieldState.ts | 1 + .../PropertyControlsTestWebPart.ts | 6 ++-- 10 files changed, 67 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index afdfd9b4..040fea74 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -1,5 +1,16 @@ { "versions": [ + { + "version": "1.12.0", + "changes": { + "new": [], + "enhancements": [ + "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)" + ], + "fixes": [] + }, + "contributions": [] + }, { "version": "1.11.0", "changes": { diff --git a/CHANGELOG.md b/CHANGELOG.md index 19eb670e..aa61e865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Releases +## 1.12.0 + +**Enhancements** + +- `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) + ## 1.11.0 **Enhancements** diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index 19eb670e..aa61e865 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -1,5 +1,11 @@ # Releases +## 1.12.0 + +**Enhancements** + +- `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) + ## 1.11.0 **Enhancements** diff --git a/docs/documentation/docs/controls/PropertyFieldCollectionData.md b/docs/documentation/docs/controls/PropertyFieldCollectionData.md index bb9b8893..20c61a8f 100644 --- a/docs/documentation/docs/controls/PropertyFieldCollectionData.md +++ b/docs/documentation/docs/controls/PropertyFieldCollectionData.md @@ -117,6 +117,7 @@ Interface `ICustomCollectionField` | options | [IDropdownOption[]](https://developer.microsoft.com/en-us/fabric#/components/dropdown) | no | Dropdown options. Only necessary when dropdown type is used. | | placeholder | string | no | Placehoder text which will be used for the input field. If not provided the input title will be used. | | defaultValue | any | no | Specify a default value for the input field. | +| deferredValidationTime | number | no | Field will start to validate after users stop typing for `deferredValidationTime` milliseconds. Default: 200ms. | | onGetErrorMessage | (value: any, index: number, crntItem: any): string \| Promise | no | The method is used to get the validation error message and determine whether the input value is valid or not. It provides you the current row index and the item you are currently editing. | Enum `CustomCollectionFieldType` diff --git a/src/propertyFields/collectionData/ICustomCollectionField.ts b/src/propertyFields/collectionData/ICustomCollectionField.ts index a4993555..78101e75 100644 --- a/src/propertyFields/collectionData/ICustomCollectionField.ts +++ b/src/propertyFields/collectionData/ICustomCollectionField.ts @@ -29,6 +29,10 @@ export interface ICustomCollectionField { * Default value for the field */ defaultValue?: any; + /** + * Field will start to validate after users stop typing for `deferredValidationTime` milliseconds. Default: 200ms. + */ + deferredValidationTime?: number; /** * The method is used to get the validation error message and determine whether the input value is valid or not. * diff --git a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx index a39d5a8c..cc492135 100644 --- a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx +++ b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx @@ -307,6 +307,7 @@ export class CollectionDataItem extends React.Component= 0 ? field.deferredValidationTime : 200} onGetErrorMessage={async (value) => { let isValid = true; let validation = ""; @@ -339,6 +340,7 @@ export class CollectionDataItem extends React.Component this.onValueChanged(field.id, value)} + deferredValidationTime={field.deferredValidationTime || field.deferredValidationTime >= 0 ? field.deferredValidationTime : 200} onGetErrorMessage={(value: string) => this.fieldValidation(field, value)} />; } } diff --git a/src/propertyFields/collectionData/collectionIconField/CollectionIconField.tsx b/src/propertyFields/collectionData/collectionIconField/CollectionIconField.tsx index f072bb21..5cdabd18 100644 --- a/src/propertyFields/collectionData/collectionIconField/CollectionIconField.tsx +++ b/src/propertyFields/collectionData/collectionIconField/CollectionIconField.tsx @@ -7,15 +7,17 @@ import { Icon } from 'office-ui-fabric-react/lib/components/Icon'; export class CollectionIconField extends React.Component { public render(): React.ReactElement { + const { field, item } = this.props; return (
- this.props.fOnValueChange(this.props.field.id, value)} + value={item[field.id] ? item[field.id] : ""} + required={field.required} + onChanged={(value) => this.props.fOnValueChange(field.id, value)} + deferredValidationTime={field.deferredValidationTime || field.deferredValidationTime >= 0 ? field.deferredValidationTime : 200} onGetErrorMessage={(value) => this.props.fValidation(this.props.field, value)} /> - +
); } diff --git a/src/propertyFields/collectionData/collectionNumberField/CollectionNumberField.tsx b/src/propertyFields/collectionData/collectionNumberField/CollectionNumberField.tsx index 77993f78..f38157a5 100644 --- a/src/propertyFields/collectionData/collectionNumberField/CollectionNumberField.tsx +++ b/src/propertyFields/collectionData/collectionNumberField/CollectionNumberField.tsx @@ -1,21 +1,32 @@ import * as React from 'react'; import styles from '../PropertyFieldCollectionDataHost.module.scss'; +import { Async } from 'office-ui-fabric-react/lib/Utilities'; import { ICollectionNumberFieldProps, ICollectionNumberFieldState } from '.'; import { ICustomCollectionField } from '..'; export class CollectionNumberField extends React.Component { + private async: Async; + private delayedValidate: (field: ICustomCollectionField, inputVal: number) => void; + constructor(props: ICollectionNumberFieldProps) { super(props); this.state = { + value: null, errorMessage: '' }; + + this.async = new Async(this); + this.delayedValidate = this.async.debounce(this.valueValidation, (this.props.field.deferredValidationTime || this.props.field.deferredValidationTime >= 0) ? this.props.field.deferredValidationTime : 200); } /** * componentWillMount lifecycle hook */ public componentWillMount(): void { + this.setState({ + value: this.props.item[this.props.field.id] + }); this.valueChange(this.props.field, this.props.item[this.props.field.id]); } @@ -25,9 +36,20 @@ export class CollectionNumberField extends React.Component { + private valueChange = (field: ICustomCollectionField, value: string | number) => { const inputVal = typeof value === "string" ? parseInt(value) : value; - const validation = await this.props.fValidation(field, inputVal); + this.setState({ + value: inputVal + }); + this.delayedValidate(field, inputVal); + } + + /** + * Delayed field validation + */ + private valueValidation = async (field: ICustomCollectionField, value: number) => { + // debugger; + const validation = await this.props.fValidation(field, value); // Update the error message this.setState({ errorMessage: validation @@ -47,7 +69,7 @@ export class CollectionNumberField extends React.Component this.valueChange(this.props.field, ev.target.value)} /> ); diff --git a/src/propertyFields/collectionData/collectionNumberField/ICollectionNumberFieldState.ts b/src/propertyFields/collectionData/collectionNumberField/ICollectionNumberFieldState.ts index 6feef6e0..bfe74355 100644 --- a/src/propertyFields/collectionData/collectionNumberField/ICollectionNumberFieldState.ts +++ b/src/propertyFields/collectionData/collectionNumberField/ICollectionNumberFieldState.ts @@ -1,3 +1,4 @@ export interface ICollectionNumberFieldState { + value: number; errorMessage: string; } diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index 5b6e6d70..c22ad5ec 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -141,7 +141,8 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart Date: Fri, 21 Sep 2018 13:56:14 +0200 Subject: [PATCH 02/34] Version update --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 673a2bb4..c9ed76f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@pnp/spfx-property-controls", - "version": "1.9.0", + "version": "1.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4c121fe0..a8782e8d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@pnp/spfx-property-controls", "description": "Reusable property pane controls for SharePoint Framework solutions", - "version": "1.11.0", + "version": "1.12.0", "engines": { "node": ">=0.10.0" }, From 765947b63042b00a44091ebe3c50556946e743d7 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 21 Sep 2018 14:14:29 +0200 Subject: [PATCH 03/34] Sotre the collection value before doing the validation --- .../collectionData/collectionDataItem/CollectionDataItem.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx index cc492135..843654b1 100644 --- a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx +++ b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx @@ -185,13 +185,14 @@ export class CollectionDataItem extends React.Component => { let validation = ""; + // Trigger field change + this.onValueChanged(field.id, value); + // Do the custom validation check if (field.onGetErrorMessage) { validation = await field.onGetErrorMessage(value, this.props.index, this.state.crntItem); } // Store the field validation this.validation[field.id] = validation === ""; - // Trigger field change - this.onValueChanged(field.id, value); // Add message for the error callout this.errorCalloutHandler(field.id, validation); return validation; From cbcecb3ca0d6f80a89a3cf40c7e52785dc679153 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 21 Sep 2018 15:01:54 +0200 Subject: [PATCH 04/34] Field validation for #98 --- .../collectionDataItem/CollectionDataItem.tsx | 11 ++++++++--- .../PropertyControlsTestWebPart.ts | 10 +++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx index 843654b1..8ae24ee5 100644 --- a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx +++ b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx @@ -185,14 +185,19 @@ export class CollectionDataItem extends React.Component => { let validation = ""; - // Trigger field change - this.onValueChanged(field.id, value); // Do the custom validation check if (field.onGetErrorMessage) { + // Set initial field validation + this.validation[field.id] = false; + // Trigger field change + this.onValueChanged(field.id, value); + // Do the validation validation = await field.onGetErrorMessage(value, this.props.index, this.state.crntItem); } // Store the field validation this.validation[field.id] = validation === ""; + // Trigger field change + this.onValueChanged(field.id, value); // Add message for the error callout this.errorCalloutHandler(field.id, validation); return validation; @@ -340,7 +345,7 @@ export class CollectionDataItem extends React.Component this.onValueChanged(field.id, value)} + // onChanged={(value) => this.onValueChanged(field.id, value)} deferredValidationTime={field.deferredValidationTime || field.deferredValidationTime >= 0 ? field.deferredValidationTime : 200} onGetErrorMessage={(value: string) => this.fieldValidation(field, value)} />; } diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index c22ad5ec..9d6a3df9 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -82,9 +82,13 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart= 3 ? "" : "Should at least contain 3 characters."; + private minLengthValidation (value: string, index: number, item: any): Promise { + return new Promise(resolve => { + setTimeout(() => { + console.log(`Currently editing item nr: ${index === null ? "new item" : index}. It contains the following properties:`, item); + return value.length >= 3 ? resolve("") : resolve("Should at least contain 3 characters."); + }, (Math.floor(Math.random() * 4) + 1) * 1000); // Random number between 1 - 4 + }); } private ageValidation (value: number) { From eb2c6dc7a45b0fead72cf1c08bc57082f152d5d4 Mon Sep 17 00:00:00 2001 From: Richard Gigan Date: Fri, 19 Oct 2018 11:53:26 +0200 Subject: [PATCH 05/34] French translation --- src/loc/fr-fr.js | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/loc/fr-fr.js diff --git a/src/loc/fr-fr.js b/src/loc/fr-fr.js new file mode 100644 index 00000000..1c47b916 --- /dev/null +++ b/src/loc/fr-fr.js @@ -0,0 +1,84 @@ +define([], function () { + return { + propertyFieldMultiSelectNoOptions: "Aucune option à sélectionner", + InvalidUrlError: "L'URL fournie n'est pas valide", + // Common field labels + 'SaveButtonLabel': 'Sauvegarder', + 'CancelButtonLabel': 'Annuler', + + // PeoplePicker labels + 'PeoplePickerSuggestedContacts': 'Personnes suggérées', + 'PeoplePickerSuggestedGroups': 'Groupes suggérés', + 'PeoplePickerSuggestedCombined': 'Personnes et groupes suggérés', + 'PeoplePickerNoResults': 'Aucun résultat trouvé', + 'PeoplePickerLoading': 'Chargement des résultats ...', + + // DatePicker labels + 'DatePickerMonthLongJanuary': 'Janvier', + 'DatePickerMonthShortJanuary': 'Jan.', + 'DatePickerMonthLongFebruary': 'Février', + 'DatePickerMonthShortFebruary': 'Fev.', + 'DatePickerMonthLongMarch': 'Mars', + 'DatePickerMonthShortMarch': 'Mar.', + 'DatePickerMonthLongApril': 'Avril', + 'DatePickerMonthShortApril': 'Avr.', + 'DatePickerMonthLongMay': 'Mai', + 'DatePickerMonthShortMay': 'Mai', + 'DatePickerMonthLongJune': 'Juin', + 'DatePickerMonthShortJune': 'Juin', + 'DatePickerMonthLongJuly': 'Juillet', + 'DatePickerMonthShortJuly': 'Jul.', + 'DatePickerMonthLongAugust': 'Août', + 'DatePickerMonthShortAugust': 'Août', + 'DatePickerMonthLongSeptember': 'Septembre', + 'DatePickerMonthShortSeptember': 'Sept.', + 'DatePickerMonthLongOctober': 'Octobre', + 'DatePickerMonthShortOctober': 'Oct.', + 'DatePickerMonthLongNovember': 'Novembre', + 'DatePickerMonthShortNovember': 'Nov.', + 'DatePickerMonthLongDecember': 'Decembre', + 'DatePickerMonthShortDecember': 'Dec.', + 'DatePickerDayLongSunday': 'Dimanche', + 'DatePickerDayShortSunday': 'Dim', + 'DatePickerDayLongMonday': 'Lundi', + 'DatePickerDayShortMonday': 'Lun', + 'DatePickerDayLongTuesday': 'Mardi', + 'DatePickerDayShortTuesday': 'Mar', + 'DatePickerDayLongWednesday': 'Mercredi', + 'DatePickerDayShortWednesday': 'Mer', + 'DatePickerDayLongThursday': 'Jeudi', + 'DatePickerDayShortThursday': 'Jeu', + 'DatePickerDayLongFriday': 'Vendredi', + 'DatePickerDayShortFriday': 'Ven', + 'DatePickerDayLongSaturday': 'Samedi', + 'DatePickerDayShortSaturday': 'Sam', + + 'DatepickerGoToToday': 'Aujourd\'hui', + 'DateTimePickerDate': 'Date', + 'DateTimePickerTime': 'Temps', + + // ColorPicker Labels + 'ColorPickerButtonTitle': 'Choisis une couleur', + + // Number field validation messages + 'NotNumberValidationMessage': 'La valeur doit être un nombre, la valeur actuel est :', + 'MinimumNumberValidationMessage': 'La valeur doit être supérieure à :', + 'MaximumNumberValidationMessage': 'La valeur doit être inférieure à :', + + // TermPicker + "TermPickerNoTerms": "L'ensemble de termes ne contient aucun terme", + "TermPickerExpandTitle": "Développer cet ensemble de termes", + "TermPickerExpandNode": "Développer ce nœud", + "TermPickerMenuTermSet": "Menu pour l'ensemble de termes", + "TermPickerMenuGroup": "Menu pour l'ensemble de termes", + "TermPickerInLabel": "dans", + "TermPickerTermSetLabel": "Ensemble de termes", + + // Collection data + "CollectionDataEmptyFields": "Aucun champ n'a été fourni pour la collection de données.", + "CollectionDataEmptyValue": "Aucune donnée dans votre collection.", + 'CollectionAddRowButtonLabel': 'Ajouter des données à la collection', + 'CollectionDeleteRowButtonLabel': 'Supprimer la ligne', + 'CollectionSaveAndAddButtonLabel': 'Ajouter et sauvegarder', + } +}); From 1c63711abc96e976e6d2a4c2f29c769d7e61170b Mon Sep 17 00:00:00 2001 From: Richard Gigan Date: Fri, 19 Oct 2018 12:01:23 +0200 Subject: [PATCH 06/34] French translation --- src/webparts/propertyControlsTest/loc/fr-fr.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/webparts/propertyControlsTest/loc/fr-fr.js diff --git a/src/webparts/propertyControlsTest/loc/fr-fr.js b/src/webparts/propertyControlsTest/loc/fr-fr.js new file mode 100644 index 00000000..5f9c2a7a --- /dev/null +++ b/src/webparts/propertyControlsTest/loc/fr-fr.js @@ -0,0 +1,7 @@ +define([], function() { + return { + 'PropertyPaneDescription': 'Description', + 'BasicGroupName': 'Nom du groupe', + 'DescriptionFieldLabel': 'Champ Description' + } +}); From cae66d55aa8f6a6acee3c84c1395755f70c78183 Mon Sep 17 00:00:00 2001 From: Junle Li Date: Wed, 24 Oct 2018 15:53:42 +0800 Subject: [PATCH 07/34] Introduce ariaLabel to number property field. --- src/propertyFields/number/IPropertyFieldNumber.ts | 4 ++++ src/propertyFields/number/PropertyFieldNumberHost.tsx | 1 + 2 files changed, 5 insertions(+) diff --git a/src/propertyFields/number/IPropertyFieldNumber.ts b/src/propertyFields/number/IPropertyFieldNumber.ts index 576232b6..d12d7276 100644 --- a/src/propertyFields/number/IPropertyFieldNumber.ts +++ b/src/propertyFields/number/IPropertyFieldNumber.ts @@ -63,6 +63,10 @@ export interface IPropertyFieldNumberProps { * Whether the property pane number field is enabled or not. */ disabled?: boolean; + /** + * The aria label for the number field. + */ + ariaLabel?: string; } /** diff --git a/src/propertyFields/number/PropertyFieldNumberHost.tsx b/src/propertyFields/number/PropertyFieldNumberHost.tsx index 0846bb8e..b714e652 100644 --- a/src/propertyFields/number/PropertyFieldNumberHost.tsx +++ b/src/propertyFields/number/PropertyFieldNumberHost.tsx @@ -75,6 +75,7 @@ export default class PropertyFieldNumberHost extends React.Component Date: Thu, 25 Oct 2018 15:50:30 +0200 Subject: [PATCH 08/34] Reorder + extra labels --- src/loc/fr-fr.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/loc/fr-fr.js b/src/loc/fr-fr.js index 1c47b916..eb64c29b 100644 --- a/src/loc/fr-fr.js +++ b/src/loc/fr-fr.js @@ -1,7 +1,5 @@ define([], function () { return { - propertyFieldMultiSelectNoOptions: "Aucune option à sélectionner", - InvalidUrlError: "L'URL fournie n'est pas valide", // Common field labels 'SaveButtonLabel': 'Sauvegarder', 'CancelButtonLabel': 'Annuler', @@ -74,11 +72,17 @@ define([], function () { "TermPickerInLabel": "dans", "TermPickerTermSetLabel": "Ensemble de termes", + // Multiselect field + propertyFieldMultiSelectNoOptions: "Aucune option à sélectionner", + // Collection data "CollectionDataEmptyFields": "Aucun champ n'a été fourni pour la collection de données.", "CollectionDataEmptyValue": "Aucune donnée dans votre collection.", 'CollectionAddRowButtonLabel': 'Ajouter des données à la collection', 'CollectionDeleteRowButtonLabel': 'Supprimer la ligne', 'CollectionSaveAndAddButtonLabel': 'Ajouter et sauvegarder', + CollectionDataItemShowErrorsLabel: "Afficher les erreurs de ligne", + CollectionDataItemFieldRequiredLabel: "Champ obligatoire", + InvalidUrlError: "L'URL fournie n'est pas valide", } }); From 0632d2b9ec15cfebb069993fc01a62c0a6087aa3 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Thu, 25 Oct 2018 15:55:30 +0200 Subject: [PATCH 09/34] Changelog updates --- CHANGELOG.json | 7 ++++--- CHANGELOG.md | 9 +++++++++ docs/documentation/docs/about/release-notes.md | 9 +++++++++ package.json | 3 ++- scripts/create-changelog.js | 8 ++++++++ src/common/telemetry/version.ts | 2 +- 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index 040fea74..d4653850 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -5,11 +5,12 @@ "changes": { "new": [], "enhancements": [ - "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)" + "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)", + "French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84)" ], "fixes": [] }, - "contributions": [] + "contributions": ["[PooLP](https://github.com/PooLP)"] }, { "version": "1.11.0", @@ -66,7 +67,7 @@ ], "fixes": [] }, - "contributions": ["Joel Rodrigues"] + "contributions": ["[Joel Rodrigues](https://github.com/joelfmrodrigues)"] }, { "version": "1.7.0", diff --git a/CHANGELOG.md b/CHANGELOG.md index aa61e865..7a0d7f87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ **Enhancements** - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) +- French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) + +### Contributors + +Special thanks to our contributor: [PooLP](https://github.com/PooLP). ## 1.11.0 @@ -49,6 +54,10 @@ - New telemetry approach which allows you to use Application Insights instance [#79](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/79) - `PropertyFieldListPicker` add optional property for target site [#21](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/21) +### Contributors + +Special thanks to our contributor: [Joel Rodrigues](https://github.com/joelfmrodrigues). + ## 1.7.0 **Enhancements** diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index aa61e865..7a0d7f87 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -5,6 +5,11 @@ **Enhancements** - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) +- French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) + +### Contributors + +Special thanks to our contributor: [PooLP](https://github.com/PooLP). ## 1.11.0 @@ -49,6 +54,10 @@ - New telemetry approach which allows you to use Application Insights instance [#79](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/79) - `PropertyFieldListPicker` add optional property for target site [#21](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/21) +### Contributors + +Special thanks to our contributor: [Joel Rodrigues](https://github.com/joelfmrodrigues). + ## 1.7.0 **Enhancements** diff --git a/package.json b/package.json index a8782e8d..ed58ec4e 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ }, "dependencies": { "@pnp/telemetry-js": "1.0.0", - "react-ace": "5.8.0" + "react-ace": "5.8.0", + "office-ui-fabric-react": "~5.120.0" }, "devDependencies": { "@microsoft/sp-build-web": "~1.3.0", diff --git a/scripts/create-changelog.js b/scripts/create-changelog.js index 9054b11d..c3a03fd2 100644 --- a/scripts/create-changelog.js +++ b/scripts/create-changelog.js @@ -29,6 +29,14 @@ if (changelog.versions && changelog.versions.length > 0) { } } } + + // Add the contributions to the MD file + if (entry.contributions && entry.contributions.length > 0) { + markdown.push(`### Contributors`); + markdown.push(``); + markdown.push(`Special thanks to our contributor${entry.contributions.length > 1 ? "s (in alphabetical order)" : "" }: ${entry.contributions.join(', ')}.`); + markdown.push(``); + } } if (markdown.length > 2) { diff --git a/src/common/telemetry/version.ts b/src/common/telemetry/version.ts index 092d558b..8ab92fdb 100644 --- a/src/common/telemetry/version.ts +++ b/src/common/telemetry/version.ts @@ -1 +1 @@ -export const version: string = "1.11.0"; \ No newline at end of file +export const version: string = "1.12.0"; \ No newline at end of file From cf7262f0f54bd34a94522e6bcae6dc47bf1e5bbd Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Thu, 25 Oct 2018 16:06:23 +0200 Subject: [PATCH 10/34] Documentation updates --- docs/documentation/docs/controls/PropertyFieldNumber.md | 1 + package.json | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/documentation/docs/controls/PropertyFieldNumber.md b/docs/documentation/docs/controls/PropertyFieldNumber.md index f5b267f6..b1b31068 100644 --- a/docs/documentation/docs/controls/PropertyFieldNumber.md +++ b/docs/documentation/docs/controls/PropertyFieldNumber.md @@ -70,6 +70,7 @@ The `PropertyFieldNumber` control can be configured with the following propertie | value | number | no | Value to be displayed in the number field. | | maxValue | number | no | Maximum number that can be inserted. | | minValue | number | no | Minimum number that can be inserted. | +| ariaLabel | string | no | The aria label for the number field. | | disabled | boolean | no | Specify if the control needs to be disabled. | | errorMessage | string | no | If set, this will be displayed as an error message. | | onGetErrorMessage | (value: number) => string | no | If set, this method is used to get the validation error message and determine whether the input value is valid or not. | diff --git a/package.json b/package.json index ed58ec4e..a8782e8d 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,7 @@ }, "dependencies": { "@pnp/telemetry-js": "1.0.0", - "react-ace": "5.8.0", - "office-ui-fabric-react": "~5.120.0" + "react-ace": "5.8.0" }, "devDependencies": { "@microsoft/sp-build-web": "~1.3.0", From 86ce17a1617c7ab9a6c1fa72727e7b3865093aa1 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Thu, 25 Oct 2018 16:09:55 +0200 Subject: [PATCH 11/34] Changelog updates --- CHANGELOG.json | 5 +++-- CHANGELOG.md | 5 +++-- docs/documentation/docs/about/release-notes.md | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index d4653850..aa87de29 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -5,12 +5,13 @@ "changes": { "new": [], "enhancements": [ + "French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84)", "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)", - "French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84)" + "`PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104)" ], "fixes": [] }, - "contributions": ["[PooLP](https://github.com/PooLP)"] + "contributions": ["[Junle Li](https://github.com/lijunle)", "[PooLP](https://github.com/PooLP)"] }, { "version": "1.11.0", diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a0d7f87..b528ba27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,13 @@ **Enhancements** -- `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) +- `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) +- `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) ### Contributors -Special thanks to our contributor: [PooLP](https://github.com/PooLP). +Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP). ## 1.11.0 diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index 7a0d7f87..b528ba27 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -4,12 +4,13 @@ **Enhancements** -- `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) +- `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) +- `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) ### Contributors -Special thanks to our contributor: [PooLP](https://github.com/PooLP). +Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP). ## 1.11.0 From ebd86075cc1504f010489398b426fbdca370fbc9 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Thu, 25 Oct 2018 16:33:05 +0200 Subject: [PATCH 12/34] Updated sonarqube version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8782e8d..90052510 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "gulp": "~3.9.1", "react": "15.4.2", "react-dom": "15.4.2", - "sonarqube-scanner": "2.1.1" + "sonarqube-scanner": "2.1.2" }, "repository": { "type": "git", From a499045f1497c112a5d81e764303b7c0781e1763 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 26 Oct 2018 09:52:55 +0200 Subject: [PATCH 13/34] #99 - Fix catastrophic backtracking regex issue --- CHANGELOG.json | 4 +++- CHANGELOG.md | 4 ++++ docs/documentation/docs/about/release-notes.md | 4 ++++ .../collectionData/collectionDataItem/CollectionDataItem.tsx | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index aa87de29..9e2d9415 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -9,7 +9,9 @@ "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)", "`PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104)" ], - "fixes": [] + "fixes": [ + "`PropertyFieldCollectionData`: Fixed catastrophic backtracking regex issue for URL validation [#99](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/99)" + ] }, "contributions": ["[Junle Li](https://github.com/lijunle)", "[PooLP](https://github.com/PooLP)"] }, diff --git a/CHANGELOG.md b/CHANGELOG.md index b528ba27..c626d2a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) +**Fixes** + +- `PropertyFieldCollectionData`: Fixed catastrophic backtracking regex issue for URL validation [#99](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/99) + ### Contributors Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP). diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index b528ba27..c626d2a0 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -8,6 +8,10 @@ - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) +**Fixes** + +- `PropertyFieldCollectionData`: Fixed catastrophic backtracking regex issue for URL validation [#99](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/99) + ### Contributors Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP). diff --git a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx index 8ae24ee5..f6d43240 100644 --- a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx +++ b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx @@ -325,7 +325,7 @@ export class CollectionDataItem extends React.Component Date: Fri, 26 Oct 2018 10:33:35 +0200 Subject: [PATCH 14/34] #82 - Dutch localization added --- CHANGELOG.json | 1 + CHANGELOG.md | 1 + .../documentation/docs/about/release-notes.md | 1 + spfx-locale.csv | 69 +++++++++++++++ src/loc/nl-nl.js | 88 +++++++++++++++++++ 5 files changed, 160 insertions(+) create mode 100644 spfx-locale.csv create mode 100644 src/loc/nl-nl.js diff --git a/CHANGELOG.json b/CHANGELOG.json index 9e2d9415..1ec4b88a 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -5,6 +5,7 @@ "changes": { "new": [], "enhancements": [ + "Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82)", "French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84)", "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)", "`PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104)" diff --git a/CHANGELOG.md b/CHANGELOG.md index c626d2a0..4c2fe648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ **Enhancements** +- Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82) - French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index c626d2a0..4c2fe648 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -4,6 +4,7 @@ **Enhancements** +- Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82) - French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) diff --git a/spfx-locale.csv b/spfx-locale.csv new file mode 100644 index 00000000..7428178c --- /dev/null +++ b/spfx-locale.csv @@ -0,0 +1,69 @@ +key;Locale en-us;Locale nl-nl;Locale fr-fr;PropertyControlStrings +SaveButtonLabel;Save;Opslaan;Sauvegarder;x +CancelButtonLabel;Cancel;Annuleren;Annuler;x +PeoplePickerSuggestedContacts;Suggested people;Voorgestelde personen;Personnes suggérées;x +PeoplePickerSuggestedGroups;Suggested groups;Voorgestelde groepen;Groupes suggérés;x +PeoplePickerSuggestedCombined;Suggested people and groups;Voorgestelde personen en groepen;Personnes et groupes suggérés;x +PeoplePickerNoResults;No result found;Geen resultaten gevonden;Aucun résultat trouvé;x +PeoplePickerLoading;Loading results ...;Resultaten laden ...;Chargement des résultats ...;x +DatePickerMonthLongJanuary;January;Januari;Janvier;x +DatePickerMonthShortJanuary;Jan;Jan;Jan.;x +DatePickerMonthLongFebruary;February;Februari;Février;x +DatePickerMonthShortFebruary;Feb;Feb;Fev.;x +DatePickerMonthLongMarch;March;Maart;Mars;x +DatePickerMonthShortMarch;Mar;Maa;Mar.;x +DatePickerMonthLongApril;April;April;Avril;x +DatePickerMonthShortApril;Apr;Apr;Avr.;x +DatePickerMonthLongMay;May;Mei;Mai;x +DatePickerMonthShortMay;May;Mei;Mai;x +DatePickerMonthLongJune;June;Juni;Juin;x +DatePickerMonthShortJune;Jun;Jun;Juin;x +DatePickerMonthLongJuly;July;Juli;Juillet;x +DatePickerMonthShortJuly;Jul;Jul;Jul.;x +DatePickerMonthLongAugust;August;Augustus;Août;x +DatePickerMonthShortAugust;Aug;Aug;Août;x +DatePickerMonthLongSeptember;September;September;Septembre;x +DatePickerMonthShortSeptember;Sept;Sept;Sept.;x +DatePickerMonthLongOctober;October;Oktober;Octobre;x +DatePickerMonthShortOctober;Oct;Okt;Oct.;x +DatePickerMonthLongNovember;November;November;Novembre;x +DatePickerMonthShortNovember;Nov;Nov;Nov.;x +DatePickerMonthLongDecember;December;December;Decembre;x +DatePickerMonthShortDecember;Dec;Dec;Dec.;x +DatePickerDayLongSunday;Sunday;Zondag;Dimanche;x +DatePickerDayShortSunday;Sun;Zon;Dim;x +DatePickerDayLongMonday;Monday;Maandag;Lundi;x +DatePickerDayShortMonday;Mon;Maa;Lun;x +DatePickerDayLongTuesday;Tuesday;Dinsdag;Mardi;x +DatePickerDayShortTuesday;Tue;Din;Mar;x +DatePickerDayLongWednesday;Wednesday;Woensdag;Mercredi;x +DatePickerDayShortWednesday;Web;Woe;Mer;x +DatePickerDayLongThursday;Thursday;Donderdag;Jeudi;x +DatePickerDayShortThursday;Thu;Don;Jeu;x +DatePickerDayLongFriday;Friday;Vrijdag;Vendredi;x +DatePickerDayShortFriday;Fri;Vri;Ven;x +DatePickerDayLongSaturday;Saturday;Zaterdag;Samedi;x +DatePickerDayShortSaturday;Sat;Zat;Sam;x +DatepickerGoToToday;Today;Vandaag;Aujourd\'hui;x +DateTimePickerDate;Date;Dag;Date;x +DateTimePickerTime;Time;Tijd;Temps;x +ColorPickerButtonTitle;Pick a Color;Kies een kleur;Choisis une couleur;x +NotNumberValidationMessage;The value should be a number, actual is:;De waarde moet een nummer zijn. Huidige waarde is:;La valeur doit être un nombre, la valeur actuel est :;x +MinimumNumberValidationMessage;The value should be greater than:;De waarde moet groter zijn dan:;La valeur doit être supérieure à :;x +MaximumNumberValidationMessage;The value should be lower than:;De waarde moet kleiner zijn dan:;La valeur doit être inférieure à :;x +TermPickerNoTerms;Term set does not contain any terms;De termen set heeft geen termen beschikbaar;L'ensemble de termes ne contient aucun terme;x +TermPickerExpandTitle;Expand this Term Set;Vouw deze termen set uit;Développer cet ensemble de termes;x +TermPickerExpandNode;Expand this Node;Vouw deze node uit;Développer ce nœud;x +TermPickerMenuTermSet;Menu for Term Set;Menu voor de termen set;Menu pour l'ensemble de termes;x +TermPickerMenuGroup;Menu for Term Set;Menu voor de groep;Menu pour l'ensemble de termes;x +TermPickerInLabel;in;in;dans;x +TermPickerTermSetLabel;Term Set;Termen set;Ensemble de termes;x +propertyFieldMultiSelectNoOptions;No options to select;Geen opties om te selecteren;Aucune option à sélectionner;x +CollectionDataEmptyFields;No fields were provided for the collection data.;Er zijn geen velden opgegeven voor de data collectie control.;Aucun champ n'a été fourni pour la collection de données.;x +CollectionDataEmptyValue;No data in your collection.;Er is geen data in de collectie.;Aucune donnée dans votre collection.;x +CollectionAddRowButtonLabel;Add data to the collection;Voeg data toe aan de collectie;Ajouter des données à la collection;x +CollectionDeleteRowButtonLabel;Delete the current row;Verwijder de huidige rij;Supprimer la ligne;x +CollectionSaveAndAddButtonLabel;Add and save;Voeg toe en sla op;Ajouter et sauvegarder;x +CollectionDataItemShowErrorsLabel;Show row errors;Problemen tonen;Afficher les erreurs de ligne;x +CollectionDataItemFieldRequiredLabel;Field is required.;Veld is verplicht.;Champ obligatoire;x +InvalidUrlError;The provided URL is not valid;De huidige URL is niet geldig;L'URL fournie n'est pas valide;x diff --git a/src/loc/nl-nl.js b/src/loc/nl-nl.js new file mode 100644 index 00000000..9cb1c81f --- /dev/null +++ b/src/loc/nl-nl.js @@ -0,0 +1,88 @@ +define([], function () { + return { + // Common field labels + 'SaveButtonLabel': 'Opslaan', + 'CancelButtonLabel': 'Annuleren', + + // PeoplePicker labels + 'PeoplePickerSuggestedContacts': 'Voorgestelde personen', + 'PeoplePickerSuggestedGroups': 'Voorgestelde groepen', + 'PeoplePickerSuggestedCombined': 'Voorgestelde personen en groepen', + 'PeoplePickerNoResults': 'Geen resultaten gevonden', + 'PeoplePickerLoading': 'Resultaten laden ...', + + // DatePicker labels + 'DatePickerMonthLongJanuary': 'Januari', + 'DatePickerMonthShortJanuary': 'Jan', + 'DatePickerMonthLongFebruary': 'Februari', + 'DatePickerMonthShortFebruary': 'Feb', + 'DatePickerMonthLongMarch': 'Maart', + 'DatePickerMonthShortMarch': 'Maa', + 'DatePickerMonthLongApril': 'April', + 'DatePickerMonthShortApril': 'Apr', + 'DatePickerMonthLongMay': 'Mei', + 'DatePickerMonthShortMay': 'Mei', + 'DatePickerMonthLongJune': 'Juni', + 'DatePickerMonthShortJune': 'Jun', + 'DatePickerMonthLongJuly': 'Juli', + 'DatePickerMonthShortJuly': 'Jul', + 'DatePickerMonthLongAugust': 'Augustus', + 'DatePickerMonthShortAugust': 'Aug', + 'DatePickerMonthLongSeptember': 'September', + 'DatePickerMonthShortSeptember': 'Sept', + 'DatePickerMonthLongOctober': 'Oktober', + 'DatePickerMonthShortOctober': 'Okt', + 'DatePickerMonthLongNovember': 'November', + 'DatePickerMonthShortNovember': 'Nov', + 'DatePickerMonthLongDecember': 'December', + 'DatePickerMonthShortDecember': 'Dec', + 'DatePickerDayLongSunday': 'Zondag', + 'DatePickerDayShortSunday': 'Zon', + 'DatePickerDayLongMonday': 'Maandag', + 'DatePickerDayShortMonday': 'Maa', + 'DatePickerDayLongTuesday': 'Dinsdag', + 'DatePickerDayShortTuesday': 'Din', + 'DatePickerDayLongWednesday': 'Woensdag', + 'DatePickerDayShortWednesday': 'Woe', + 'DatePickerDayLongThursday': 'Donderdag', + 'DatePickerDayShortThursday': 'Don', + 'DatePickerDayLongFriday': 'Vrijdag', + 'DatePickerDayShortFriday': 'Vri', + 'DatePickerDayLongSaturday': 'Zaterdag', + 'DatePickerDayShortSaturday': 'Zat', + + 'DatepickerGoToToday': 'Vandaag', + 'DateTimePickerDate': 'Dag', + 'DateTimePickerTime': 'Tijd', + + // ColorPicker Labels + 'ColorPickerButtonTitle': 'Kies een kleur', + + // Number field validation messages + 'NotNumberValidationMessage': 'De waarde moet een nummer zijn. Huidige waarde is:', + 'MinimumNumberValidationMessage': 'De waarde moet groter zijn dan:', + 'MaximumNumberValidationMessage': 'De waarde moet kleiner zijn dan:', + + // TermPicker + "TermPickerNoTerms": "De termen set heeft geen termen beschikbaar", + "TermPickerExpandTitle": "Vouw deze termen set uit", + "TermPickerExpandNode": "Vouw deze node uit", + "TermPickerMenuTermSet": "Menu voor de termen set", + "TermPickerMenuGroup": "Menu voor de groep", + "TermPickerInLabel": "in", + "TermPickerTermSetLabel": "Termen set", + + // Multi-select field + propertyFieldMultiSelectNoOptions: "Geen opties om te selecteren", + + // Collection data + "CollectionDataEmptyFields": "Er zijn geen velden opgegeven voor de data collectie control.", + "CollectionDataEmptyValue": "Er is geen data in de collectie.", + 'CollectionAddRowButtonLabel': 'Voeg data toe aan de collectie', + 'CollectionDeleteRowButtonLabel': 'Verwijder de huidige rij', + 'CollectionSaveAndAddButtonLabel': 'Voeg toe en sla op', + CollectionDataItemShowErrorsLabel: "Problemen tonen", + CollectionDataItemFieldRequiredLabel: "Veld is verplicht.", + InvalidUrlError: "De huidige URL is niet geldig" + } +}); From 9814f2aa1611263509cc0eb8f0dccca0f6918bcb Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Fri, 26 Oct 2018 14:23:24 +0200 Subject: [PATCH 15/34] #102 - Implement onRenderOption functionality --- CHANGELOG.json | 1 + CHANGELOG.md | 1 + docs/documentation/docs/about/release-notes.md | 1 + .../docs/controls/PropertyFieldCollectionData.md | 1 + .../collectionData/ICustomCollectionField.ts | 6 ++++++ .../collectionDataItem/CollectionDataItem.tsx | 3 ++- .../propertyControlsTest/PropertyControlsTestWebPart.ts | 9 ++++++++- 7 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index 1ec4b88a..485fad12 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -8,6 +8,7 @@ "Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82)", "French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84)", "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)", + "`PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102)", "`PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104)" ], "fixes": [ diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c2fe648..7e0191c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82) - French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) +- `PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) **Fixes** diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index 4c2fe648..7e0191c6 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -7,6 +7,7 @@ - Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82) - French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84) - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) +- `PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) **Fixes** diff --git a/docs/documentation/docs/controls/PropertyFieldCollectionData.md b/docs/documentation/docs/controls/PropertyFieldCollectionData.md index 20c61a8f..c72f2cc6 100644 --- a/docs/documentation/docs/controls/PropertyFieldCollectionData.md +++ b/docs/documentation/docs/controls/PropertyFieldCollectionData.md @@ -115,6 +115,7 @@ Interface `ICustomCollectionField` | type | CustomCollectionFieldType | yes | Specifies the type of field to render. | | required | boolean | no | Specify if the field is required. | | options | [IDropdownOption[]](https://developer.microsoft.com/en-us/fabric#/components/dropdown) | no | Dropdown options. Only necessary when dropdown type is used. | +| onRenderOption | IRenderFunction | no | Dropdown custom options render method. Only for the **dropdown** field type. | | placeholder | string | no | Placehoder text which will be used for the input field. If not provided the input title will be used. | | defaultValue | any | no | Specify a default value for the input field. | | deferredValidationTime | number | no | Field will start to validate after users stop typing for `deferredValidationTime` milliseconds. Default: 200ms. | diff --git a/src/propertyFields/collectionData/ICustomCollectionField.ts b/src/propertyFields/collectionData/ICustomCollectionField.ts index 78101e75..a4ee8459 100644 --- a/src/propertyFields/collectionData/ICustomCollectionField.ts +++ b/src/propertyFields/collectionData/ICustomCollectionField.ts @@ -1,4 +1,6 @@ import { IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown'; +import { IRenderFunction } from '@uifabric/utilities/lib/IRenderFunction'; +import { ISelectableOption } from 'office-ui-fabric-react/lib/utilities/selectableOption/SelectableOption.Props'; export interface ICustomCollectionField { /** @@ -21,6 +23,10 @@ export interface ICustomCollectionField { * Dropdown options. Only nescessary when dropdown type is used. */ options?: IDropdownOption[]; + /** + * Dropdown custom options render method. + */ + onRenderOption?: IRenderFunction; /** * Input placeholder text. */ diff --git a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx index f6d43240..0fa38869 100644 --- a/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx +++ b/src/propertyFields/collectionData/collectionDataItem/CollectionDataItem.tsx @@ -299,7 +299,8 @@ export class CollectionDataItem extends React.Component this.onValueChanged(field.id, opt.key)} />; + onChanged={(opt) => this.onValueChanged(field.id, opt.key)} + onRenderOption={field.onRenderOption} />; case CustomCollectionFieldType.number: return ( diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index 9d6a3df9..ca69ba0e 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -182,7 +182,14 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart { + if (props.text.toLowerCase() === "antwerp") { + return React.createElement("b", { className: "Testing" }, `${props.text.toUpperCase()} 🎉`); + } else { + return defaultRenderer(props); + } + } }, { id: "Sign", From bc0bbd2c555ac25f14f3a32a388b73b1d10db3c0 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 29 Oct 2018 16:55:25 +0100 Subject: [PATCH 16/34] only show callout info button in case callout content is set. --- src/common/propertyFieldHeader/PropertyFieldHeader.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/common/propertyFieldHeader/PropertyFieldHeader.tsx b/src/common/propertyFieldHeader/PropertyFieldHeader.tsx index defef92c..e58c80d1 100644 --- a/src/common/propertyFieldHeader/PropertyFieldHeader.tsx +++ b/src/common/propertyFieldHeader/PropertyFieldHeader.tsx @@ -27,10 +27,12 @@ export default class PropertyFieldHeader extends React.Component
- { this._infoIcon = infoIcon; }} + {this.props.calloutContent !== undefined && ( + { this._infoIcon = infoIcon; }} onMouseOver={this.props.calloutTrigger === CalloutTriggers.Hover ? this._onInfoIconMouseOver.bind(this) : null} onMouseOut={this.props.calloutTrigger === CalloutTriggers.Hover ? this._onInfoIconMouseOut.bind(this) : null} onClick={this.props.calloutTrigger === CalloutTriggers.Click ? this._onInfoIconClick.bind(this) : null}> + )}
{this.state.isCalloutVisible && ( Date: Mon, 29 Oct 2018 17:20:57 +0100 Subject: [PATCH 17/34] Added WebPartInformation control --- package-lock.json | 820 ++++++++++++++++++ src/PropertyWebPartInformation.ts | 1 + src/index.ts | 1 + src/loc/en-us.js | 3 + src/loc/mystrings.d.ts | 4 + .../IPropertyWebPartInformation.ts | 51 ++ .../IPropertyWebPartInformationHost.ts | 11 + .../PropertyWebPartInformation.ts | 58 ++ .../PropertyWebPartInformationHost.tsx | 51 ++ .../webPartInformation/index.ts | 4 + .../PropertyControlsTestWebPart.ts | 15 + .../propertyControlsTest/loc/en-us.js | 3 +- .../propertyControlsTest/loc/mystrings.d.ts | 1 + 13 files changed, 1022 insertions(+), 1 deletion(-) create mode 100644 src/PropertyWebPartInformation.ts create mode 100644 src/propertyFields/webPartInformation/IPropertyWebPartInformation.ts create mode 100644 src/propertyFields/webPartInformation/IPropertyWebPartInformationHost.ts create mode 100644 src/propertyFields/webPartInformation/PropertyWebPartInformation.ts create mode 100644 src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx create mode 100644 src/propertyFields/webPartInformation/index.ts diff --git a/package-lock.json b/package-lock.json index c9ed76f1..a0be1770 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1169,6 +1169,12 @@ "whatwg-fetch": "2.0.4" } }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha1-mgb08TfuhNffBGDB/bETX/psUP0=", + "dev": true + }, "@types/adal": { "version": "1.0.27", "resolved": "https://registry.npmjs.org/@types/adal/-/adal-1.0.27.tgz", @@ -2841,6 +2847,34 @@ } } }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha1-iQ3ZDZI6hz4I4Q5f1RpX5bfM4Ow=", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha1-vX3CauKXLQ7aJTvgYdupkjScGfA=", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, "buffer-from": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", @@ -2900,6 +2934,66 @@ "rimraf": "^2.4.0" } }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "dev": true, + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha1-g1qdoVUfom9w6SMpBpojqmV01+Y=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha1-p4wBK3HBfgXy4/ojGd0zBoLvs8s=", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + } + } + }, "callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", @@ -2962,6 +3056,18 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, + "caw": { + "version": "2.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/caw/-/caw-2.0.1.tgz", + "integrity": "sha1-bDygcfwZRyCIPC3F2psHS/x+npU=", + "dev": true, + "requires": { + "get-proxy": "^2.0.0", + "isurl": "^1.0.0-alpha5", + "tunnel-agent": "^0.6.0", + "url-to-options": "^1.0.1" + } + }, "center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", @@ -3141,6 +3247,15 @@ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", "dev": true }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, "clone-stats": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", @@ -3438,6 +3553,16 @@ } } }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha1-D96NCRIA616AjK8l/mGMAvSOTvo=", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "configstore": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", @@ -4055,6 +4180,139 @@ } } }, + "decompress": { + "version": "4.2.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/decompress/-/decompress-4.2.0.tgz", + "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", + "dev": true, + "requires": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "decompress-tar": { + "version": "4.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha1-cYy9P8sWIJcW5womuE57pFkuWvE=", + "dev": true, + "requires": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true + } + } + }, + "decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha1-MIKluIDqQEOBY0nzeLVsUWvho5s=", + "dev": true, + "requires": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "dependencies": { + "file-type": { + "version": "6.2.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha1-5QzXXTVv/tTjBtxPW89Sp5kDqRk=", + "dev": true + } + } + }, + "decompress-targz": { + "version": "4.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha1-wJvDXE0R894J8tLaU+neI+fOHu4=", + "dev": true, + "requires": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true + } + } + }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "dev": true, + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "file-type": { + "version": "3.9.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "dev": true + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } + }, "deep-eql": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", @@ -4251,6 +4509,79 @@ "is-obj": "^1.0.0" } }, + "download": { + "version": "7.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/download/-/download-7.0.0.tgz", + "integrity": "sha512-0Fe/CAjKycx12IG9We9gYlLP03BEcWTpttg7P5mwfOiQTg584kpuHqP7F61RkUJM+mfEdEU9TJonm0PJp5rQLw==", + "dev": true, + "requires": { + "caw": "^2.0.1", + "content-disposition": "^0.5.2", + "decompress": "^4.2.0", + "ext-name": "^5.0.0", + "file-type": "^7.7.1", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^8.3.1", + "make-dir": "^1.2.0", + "p-event": "^1.3.0", + "pify": "^3.0.0" + }, + "dependencies": { + "got": { + "version": "8.3.2", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/got/-/got-8.3.2.tgz", + "integrity": "sha1-HSP2Q5Dpf3dsrFLluTbl9RTS6Tc=", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + } + } + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -4266,6 +4597,12 @@ "readable-stream": "~1.1.9" } }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "duplexify": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", @@ -5068,6 +5405,25 @@ } } }, + "ext-list": { + "version": "2.2.2", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "requires": { + "mime-db": "^1.28.0" + } + }, + "ext-name": { + "version": "5.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "requires": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + } + }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", @@ -5254,12 +5610,35 @@ "loader-utils": "~0.2.5" } }, + "file-type": { + "version": "7.7.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/file-type/-/file-type-7.7.1.tgz", + "integrity": "sha512-bTrKkzzZI6wH+NXhyD3SOXtb2zXTw2SbwI2RxUlRcXVsnN7jNL5hJzVQLYv7FOQhxFkK4XWdAflEaWFpaLLWpQ==", + "dev": true + }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", "dev": true }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "dev": true + }, + "filenamify": { + "version": "2.1.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/filenamify/-/filenamify-2.1.0.tgz", + "integrity": "sha1-iPr0lfsbR6v9YSMAACoWIoxnfuk=", + "dev": true, + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -5465,6 +5844,54 @@ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", "dev": true }, + "from2": { + "version": "2.3.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha1-a+Dem+mYzhavivwkSXue6bfM2a0=", + "dev": true + }, "fs-extra": { "version": "0.26.7", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", @@ -6152,6 +6579,15 @@ "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, + "get-proxy": { + "version": "2.1.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/get-proxy/-/get-proxy-2.1.0.tgz", + "integrity": "sha1-NJ8rTZHUTE1NTpy6KtkBQ/rF75M=", + "dev": true, + "requires": { + "npm-conf": "^1.1.0" + } + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -8005,6 +8441,21 @@ "sparkles": "^1.0.0" } }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha1-FAn5i8ACR9pF2mfO4KNvKC/yZFU=", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha1-oEWrOD17SyASoAFIqwql8pAETU0=", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -8188,6 +8639,12 @@ } } }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha1-ObDhat2bYFvwqe89nar0hDtMrNI=", + "dev": true + }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -8337,6 +8794,16 @@ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "dev": true, + "requires": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + } + }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -8539,6 +9006,12 @@ "xtend": "^4.0.0" } }, + "is-natural-number": { + "version": "4.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", + "dev": true + }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -8571,6 +9044,12 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, + "is-object": { + "version": "1.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", + "dev": true + }, "is-odd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", @@ -8837,6 +9316,16 @@ "textextensions": "~1.0.0" } }, + "isurl": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha1-sn9PSfPNqj6kSgpbfzRi5u3DnWc=", + "dev": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, "jju": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz", @@ -8885,6 +9374,12 @@ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, "json-loader": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", @@ -9177,6 +9672,15 @@ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", "dev": true }, + "keyv": { + "version": "3.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha1-RJI7o55osSp87H32wyaMAx8u83M=", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -9872,6 +10376,23 @@ "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", "dev": true }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha1-ecEDO4BRW9bSTsmTPoYMp17ifww=", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -10145,6 +10666,12 @@ "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", "dev": true }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha1-SSNTiHju9CBjy4o+OweYeBSHqxs=", + "dev": true + }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -10903,6 +11430,24 @@ "sort-keys": "^1.0.0" } }, + "npm-conf": { + "version": "1.1.3", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha1-JWzEe9DiGMJZxOlVC/QTvCGSr/k=", + "dev": true, + "requires": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -11220,12 +11765,44 @@ "os-tmpdir": "^1.0.0" } }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha1-NfNj1n1SCByNlYXje8zrfgu8sqA=", + "dev": true + }, + "p-event": { + "version": "1.3.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/p-event/-/p-event-1.3.0.tgz", + "integrity": "sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=", + "dev": true, + "requires": { + "p-timeout": "^1.1.1" + }, + "dependencies": { + "p-timeout": { + "version": "1.2.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + } + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -11244,6 +11821,15 @@ "p-limit": "^1.1.0" } }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha1-2N0ZeVldLcATnh/ka4tkbLPN8Dg=", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", @@ -12170,6 +12756,12 @@ "object-assign": "^4.1.1" } }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, "proxy-addr": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", @@ -12815,6 +13407,15 @@ "on-headers": "~1.0.1" } }, + "responselike": { + "version": "1.0.2", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -12982,6 +13583,26 @@ } } }, + "seek-bzip": { + "version": "1.0.5", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/seek-bzip/-/seek-bzip-1.0.5.tgz", + "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", + "dev": true, + "requires": { + "commander": "~2.8.1" + }, + "dependencies": { + "commander": { + "version": "2.8.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + } + } + }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", @@ -13289,6 +13910,12 @@ "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", "dev": true }, + "slugify": { + "version": "1.3.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/slugify/-/slugify-1.3.1.tgz", + "integrity": "sha1-9XISfoU1Mp+8bB7bdKuFa2GtfeI=", + "dev": true + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -13541,6 +14168,69 @@ } } }, + "sonarqube-scanner": { + "version": "2.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/sonarqube-scanner/-/sonarqube-scanner-2.1.1.tgz", + "integrity": "sha512-KhvOBP1IBXnnkVAbfdINLyDnsR6W6NsX4m5z57s4/wxlfUIeRMT8MNsqmGWRRIzYqtPPUCpHT3R3sUChGZmALg==", + "dev": true, + "requires": { + "download": "7.0.0", + "extend": "3.0.1", + "fancy-log": "^1.1.0", + "lodash.get": "^4.4.2", + "lodash.uniq": "^4.5.0", + "mkdirp": "0.5.1", + "progress": "^2.0.0", + "read-pkg": "2.0.0", + "slugify": "1.3.1" + }, + "dependencies": { + "load-json-file": { + "version": "2.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "progress": { + "version": "2.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/progress/-/progress-2.0.1.tgz", + "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "sort-keys": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", @@ -13550,6 +14240,15 @@ "is-plain-obj": "^1.0.0" } }, + "sort-keys-length": { + "version": "1.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", + "dev": true, + "requires": { + "sort-keys": "^1.0.0" + } + }, "source-list-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", @@ -13948,6 +14647,15 @@ } } }, + "strip-dirs": { + "version": "2.1.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha1-SYdzYmT8NEzyD2w0rKnRPR1O1sU=", + "dev": true, + "requires": { + "is-natural-number": "^4.0.1" + } + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -13969,6 +14677,15 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha1-sv0qv2YEudHmATBXGV34Nrip1jE=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, "sudo": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sudo/-/sudo-1.0.3.tgz", @@ -14051,6 +14768,53 @@ "inherits": "2" } }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha1-jqVdqzeXIlPZqa+Q/c1VmuQ1xVU=", + "dev": true, + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "ternary-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.0.1.tgz", @@ -14308,6 +15072,12 @@ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", "dev": true }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha1-STvUj2LXxD/N7TE6A9ytsuEhOoA=", + "dev": true + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -14371,6 +15141,15 @@ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, "true-case-path": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", @@ -14600,6 +15379,41 @@ "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", "dev": true }, + "unbzip2-stream": { + "version": "1.3.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz", + "integrity": "sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==", + "dev": true, + "requires": { + "buffer": "^3.0.1", + "through": "^2.3.6" + }, + "dependencies": { + "base64-js": { + "version": "0.0.8", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/base64-js/-/base64-js-0.0.8.tgz", + "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", + "dev": true + }, + "buffer": { + "version": "3.6.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/buffer/-/buffer-3.6.0.tgz", + "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", + "dev": true, + "requires": { + "base64-js": "0.0.8", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -14821,6 +15635,12 @@ "prepend-http": "^1.0.1" } }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://onedrive.pkgs.visualstudio.com/_packaging/Dev-Kitchen/npm/registry/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true + }, "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", diff --git a/src/PropertyWebPartInformation.ts b/src/PropertyWebPartInformation.ts new file mode 100644 index 00000000..c5987d7e --- /dev/null +++ b/src/PropertyWebPartInformation.ts @@ -0,0 +1 @@ +export * from './propertyFields/webPartInformation/index'; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index ff2245dd..07d12da0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,3 +16,4 @@ export * from './PropertyFieldLinkWithCallout'; export * from './PropertyFieldSliderWithCallout'; export * from './PropertyFieldTextWithCallout'; export * from './PropertyFieldToggleWithCallout'; +export * from './PropertyWebPartInformation'; diff --git a/src/loc/en-us.js b/src/loc/en-us.js index f593c1ea..6964e7fa 100644 --- a/src/loc/en-us.js +++ b/src/loc/en-us.js @@ -3,6 +3,9 @@ define([], function () { // Common field labels 'SaveButtonLabel': 'Save', 'CancelButtonLabel': 'Cancel', + 'DescriptionLabel' : 'Description', + 'MoreInfoLabel' : 'More info', + 'AboutGroupLabel': 'About', // PeoplePicker labels 'PeoplePickerSuggestedContacts': 'Suggested people', diff --git a/src/loc/mystrings.d.ts b/src/loc/mystrings.d.ts index 1268b0ec..a7f1644c 100644 --- a/src/loc/mystrings.d.ts +++ b/src/loc/mystrings.d.ts @@ -1,4 +1,8 @@ declare interface IPropertyControlStrings { + + DescriptionLabel: string; + MoreInfoLabel: string; + // PeoplePicker labels PeoplePickerSuggestedContacts: string; PeoplePickerSuggestedGroups: string; diff --git a/src/propertyFields/webPartInformation/IPropertyWebPartInformation.ts b/src/propertyFields/webPartInformation/IPropertyWebPartInformation.ts new file mode 100644 index 00000000..0b1b43ff --- /dev/null +++ b/src/propertyFields/webPartInformation/IPropertyWebPartInformation.ts @@ -0,0 +1,51 @@ +import { IPropertyPaneCustomFieldProps, BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; + + +/** + * Public properties of the PropertyFieldSpinButton custom field + */ +export interface IPropertyWebPartInformationProps { + + /** + * A link pointing to an external source for more information + */ + moreInfoLink?: string; + /** + * A string defining the target for the link, e.g. _blank + */ + moreInfoLinkTarget?: string; + /** + * A required description of the webpart + */ + description: string; + /** + * Optional embedded video + */ + videoProperties?: IVideoEmbedProperties; + /** + * An UNIQUE key indicates the identity of this control + */ + key: string; +} + +export interface IPropertyWebPartInformationPropsInternal extends IPropertyWebPartInformationProps, IPropertyPaneCustomFieldProps { +} + +export interface IVideoEmbedProperties { + /** + * The url to a video, e.g. https://www.youtube.com/embed/d_9o3tQ90zo + */ + embedLink: string; + /** + * Optional width of the iframe embedding the video + */ + width?: number; + /** + * Optional height of the iframe embedding the video + */ + height?: number; + /** + * Any additional properties to add to the iframe link, for instance {allowFullScreen: true} for Youtube videos + */ + properties?: any; +} \ No newline at end of file diff --git a/src/propertyFields/webPartInformation/IPropertyWebPartInformationHost.ts b/src/propertyFields/webPartInformation/IPropertyWebPartInformationHost.ts new file mode 100644 index 00000000..695a5f44 --- /dev/null +++ b/src/propertyFields/webPartInformation/IPropertyWebPartInformationHost.ts @@ -0,0 +1,11 @@ +import { IVideoEmbedProperties } from "./IPropertyWebPartInformation"; + +/** + * PropertyFieldColorPickerHost properties interface + */ +export interface IPropertyWebPartInformationHostProps { + videoProperties?: IVideoEmbedProperties; + moreInfoLink?: string; + moreInfoLinkTarget?: string; + description: string; +} \ No newline at end of file diff --git a/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts b/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts new file mode 100644 index 00000000..8a61d737 --- /dev/null +++ b/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts @@ -0,0 +1,58 @@ +import * as React from 'react'; +import * as ReactDom from 'react-dom'; +import { + IPropertyPaneField, + PropertyPaneFieldType +} from '@microsoft/sp-webpart-base'; + +import { IPropertyWebPartInformationProps, IPropertyWebPartInformationPropsInternal } from "./IPropertyWebPartInformation"; +import { IPropertyWebPartInformationHostProps } from './IPropertyWebPartInformationHost'; +import PropertyWebPartInformationHost from './PropertyWebPartInformationHost'; + +class PropertyWebPartInformationBuilder implements IPropertyPaneField { + + //Properties defined by IPropertyPaneField + public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; + public targetProperty: string; + public properties: IPropertyWebPartInformationPropsInternal; + + private elem: HTMLElement; + + + public constructor(_targetProperty: string, _properties: IPropertyWebPartInformationProps) { + this.targetProperty = _targetProperty; + this.properties = { + key: _properties.key, + moreInfoLink: _properties.moreInfoLink, + moreInfoLinkTarget: _properties.moreInfoLinkTarget !== undefined ? _properties.moreInfoLinkTarget : "_blank", + videoProperties: _properties.videoProperties, + description: _properties.description, + onRender: this.onRender.bind(this) + }; + } + + public render(): void { + if (!this.elem) { + return; + } + this.onRender(this.elem); + } + + private onRender(elem: HTMLElement, ctx?: any, changeCallback?: (targetProperty?: string, newValue?: any) => void): void { + if (!this.elem) { + this.elem = elem; + } + + const element: React.ReactElement = React.createElement(PropertyWebPartInformationHost, { + moreInfoLink: this.properties.moreInfoLink, + moreInfoLinkTarget: this.properties.moreInfoLinkTarget, + description: this.properties.description, + videoProperties: this.properties.videoProperties + }); + ReactDom.render(element, elem); + } +} + +export function PropertyWebPartInformation(targetProperty: string, properties: IPropertyWebPartInformationProps): IPropertyPaneField { + return new PropertyWebPartInformationBuilder(targetProperty, properties); +} diff --git a/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx b/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx new file mode 100644 index 00000000..58dd81a2 --- /dev/null +++ b/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx @@ -0,0 +1,51 @@ +import * as React from 'react'; +import * as strings from 'PropertyControlStrings'; +import { IPropertyWebPartInformationHostProps } from './IPropertyWebPartInformationHost'; +import PropertyFieldHeader from '../../common/propertyFieldHeader/PropertyFieldHeader'; + +export default class PropertyWebPartInformationHost extends React.Component { + + constructor(props: IPropertyWebPartInformationHostProps) { + super(props); + } + + private moreInfoLink = (): JSX.Element => { + if (this.props.moreInfoLink !== undefined) { + return ; + } else { + return; + } + + } + + private youtubeEmbed = (): JSX.Element => { + let linkProperties = {}; + if (this.props.videoProperties !== undefined && this.props.videoProperties.embedLink !== "") { + linkProperties["src"] = this.props.videoProperties.embedLink; + if (this.props.videoProperties.height) { + linkProperties["height"] = this.props.videoProperties.height; + } + if (this.props.videoProperties.width) { + linkProperties["width"] = this.props.videoProperties.width; + } + for(let prop in this.props.videoProperties.properties) + { + linkProperties["prop"] = this.props.videoProperties[prop]; + } + return ; + } else { + return; + } + } + + public render(): JSX.Element { + return ( +
+ +
+ + +
+ ); + } +} diff --git a/src/propertyFields/webPartInformation/index.ts b/src/propertyFields/webPartInformation/index.ts new file mode 100644 index 00000000..c5cdfa5a --- /dev/null +++ b/src/propertyFields/webPartInformation/index.ts @@ -0,0 +1,4 @@ +export * from './IPropertyWebPartInformation'; +export * from './PropertyWebPartInformation'; +export * from './IPropertyWebPartInformationHost'; +export * from './PropertyWebPartInformationHost'; diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index 9d6a3df9..cd3e4350 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -35,6 +35,7 @@ import { PropertyFieldCollectionData, CustomCollectionFieldType } from '../../Pr import { PropertyFieldOrder } from '../../PropertyFieldOrder'; import { orderedItem } from './components/OrderedItem'; import { PropertyFieldSwatchColorPicker, PropertyFieldSwatchColorPickerStyle } from '../../PropertyFieldSwatchColorPicker'; +import { PropertyWebPartInformation } from '../../propertyFields/webPartInformation'; /** * Web part that can be used to test out the various property controls @@ -128,6 +129,20 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPartdemo webpart, used to demonstrate all the PnP property controls`, + moreInfoLink: `https://sharepoint.github.io/sp-dev-fx-property-controls/`, + videoProperties: { + embedLink: `https://www.youtube.com/embed/d_9o3tQ90zo`, + properties: { allowFullScreen: true} + }, + key: 'webPartInfoId' + }) + ] + }, { groupName: '', //strings.BasicGroupName, groupFields: [ diff --git a/src/webparts/propertyControlsTest/loc/en-us.js b/src/webparts/propertyControlsTest/loc/en-us.js index 8b455251..d6a69d2e 100644 --- a/src/webparts/propertyControlsTest/loc/en-us.js +++ b/src/webparts/propertyControlsTest/loc/en-us.js @@ -2,6 +2,7 @@ define([], function() { return { 'PropertyPaneDescription': 'Description', 'BasicGroupName': 'Group Name', - 'DescriptionFieldLabel': 'Description Field' + 'DescriptionFieldLabel': 'Description Field', + 'AboutGroupName': 'About' } }); diff --git a/src/webparts/propertyControlsTest/loc/mystrings.d.ts b/src/webparts/propertyControlsTest/loc/mystrings.d.ts index b05958ef..4c7568a6 100644 --- a/src/webparts/propertyControlsTest/loc/mystrings.d.ts +++ b/src/webparts/propertyControlsTest/loc/mystrings.d.ts @@ -2,6 +2,7 @@ declare interface IPropertyControlsTestWebPartStrings { PropertyPaneDescription: string; BasicGroupName: string; DescriptionFieldLabel: string; + AboutGroupName: string; } declare module 'PropertyControlsTestWebPartStrings' { From bcb760d45f7b30eef5b492aa17d263ce96693008 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Tue, 30 Oct 2018 08:19:50 +0100 Subject: [PATCH 18/34] #106 #107 - Small code change --- src/common/propertyFieldHeader/PropertyFieldHeader.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/common/propertyFieldHeader/PropertyFieldHeader.tsx b/src/common/propertyFieldHeader/PropertyFieldHeader.tsx index e58c80d1..60c2fb5e 100644 --- a/src/common/propertyFieldHeader/PropertyFieldHeader.tsx +++ b/src/common/propertyFieldHeader/PropertyFieldHeader.tsx @@ -27,11 +27,11 @@ export default class PropertyFieldHeader extends React.Component
- {this.props.calloutContent !== undefined && ( - { this._infoIcon = infoIcon; }} - onMouseOver={this.props.calloutTrigger === CalloutTriggers.Hover ? this._onInfoIconMouseOver.bind(this) : null} - onMouseOut={this.props.calloutTrigger === CalloutTriggers.Hover ? this._onInfoIconMouseOut.bind(this) : null} - onClick={this.props.calloutTrigger === CalloutTriggers.Click ? this._onInfoIconClick.bind(this) : null}> + {this.props.calloutContent && ( + { this._infoIcon = infoIcon; }} + onMouseOver={this.props.calloutTrigger === CalloutTriggers.Hover ? this._onInfoIconMouseOver.bind(this) : null} + onMouseOut={this.props.calloutTrigger === CalloutTriggers.Hover ? this._onInfoIconMouseOut.bind(this) : null} + onClick={this.props.calloutTrigger === CalloutTriggers.Click ? this._onInfoIconClick.bind(this) : null}> )}
{this.state.isCalloutVisible && ( From bc6a4fa3b2b522eb04312e8ccd704b03112b017f Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Tue, 30 Oct 2018 08:20:17 +0100 Subject: [PATCH 19/34] #106 #108 - Added translations + small code changes --- spfx-locale.csv | 3 + src/PropertyWebPartInformation.ts | 2 +- src/loc/en-us.js | 154 ++++++++---------- src/loc/fr-fr.js | 151 ++++++++--------- src/loc/nl-nl.js | 153 ++++++++--------- .../PropertyWebPartInformationHost.tsx | 75 ++++----- 6 files changed, 250 insertions(+), 288 deletions(-) diff --git a/spfx-locale.csv b/spfx-locale.csv index 7428178c..4e8b398e 100644 --- a/spfx-locale.csv +++ b/spfx-locale.csv @@ -67,3 +67,6 @@ CollectionSaveAndAddButtonLabel;Add and save;Voeg toe en sla op;Ajouter et sauve CollectionDataItemShowErrorsLabel;Show row errors;Problemen tonen;Afficher les erreurs de ligne;x CollectionDataItemFieldRequiredLabel;Field is required.;Veld is verplicht.;Champ obligatoire;x InvalidUrlError;The provided URL is not valid;De huidige URL is niet geldig;L'URL fournie n'est pas valide;x +DescriptionLabel;Description;Beschrijving;La description;x +MoreInfoLabel;More info;Meer info;Plus d'informations;x +AboutGroupLabel;About;Over;Sur;x diff --git a/src/PropertyWebPartInformation.ts b/src/PropertyWebPartInformation.ts index c5987d7e..798c00d1 100644 --- a/src/PropertyWebPartInformation.ts +++ b/src/PropertyWebPartInformation.ts @@ -1 +1 @@ -export * from './propertyFields/webPartInformation/index'; \ No newline at end of file +export * from './propertyFields/webPartInformation'; diff --git a/src/loc/en-us.js b/src/loc/en-us.js index 6964e7fa..aa502236 100644 --- a/src/loc/en-us.js +++ b/src/loc/en-us.js @@ -1,91 +1,75 @@ -define([], function () { +define([], function() { return { - // Common field labels - 'SaveButtonLabel': 'Save', - 'CancelButtonLabel': 'Cancel', - 'DescriptionLabel' : 'Description', - 'MoreInfoLabel' : 'More info', - 'AboutGroupLabel': 'About', - - // PeoplePicker labels - 'PeoplePickerSuggestedContacts': 'Suggested people', - 'PeoplePickerSuggestedGroups': 'Suggested groups', - 'PeoplePickerSuggestedCombined': 'Suggested people and groups', - 'PeoplePickerNoResults': 'No result found', - 'PeoplePickerLoading': 'Loading results ...', - - // DatePicker labels - 'DatePickerMonthLongJanuary': 'January', - 'DatePickerMonthShortJanuary': 'Jan', - 'DatePickerMonthLongFebruary': 'February', - 'DatePickerMonthShortFebruary': 'Feb', - 'DatePickerMonthLongMarch': 'March', - 'DatePickerMonthShortMarch': 'Mar', - 'DatePickerMonthLongApril': 'April', - 'DatePickerMonthShortApril': 'Apr', - 'DatePickerMonthLongMay': 'May', - 'DatePickerMonthShortMay': 'May', - 'DatePickerMonthLongJune': 'June', - 'DatePickerMonthShortJune': 'Jun', - 'DatePickerMonthLongJuly': 'July', - 'DatePickerMonthShortJuly': 'Jul', - 'DatePickerMonthLongAugust': 'August', - 'DatePickerMonthShortAugust': 'Aug', - 'DatePickerMonthLongSeptember': 'September', - 'DatePickerMonthShortSeptember': 'Sept', - 'DatePickerMonthLongOctober': 'October', - 'DatePickerMonthShortOctober': 'Oct', - 'DatePickerMonthLongNovember': 'November', - 'DatePickerMonthShortNovember': 'Nov', - 'DatePickerMonthLongDecember': 'December', - 'DatePickerMonthShortDecember': 'Dec', - 'DatePickerDayLongSunday': 'Sunday', - 'DatePickerDayShortSunday': 'Sun', - 'DatePickerDayLongMonday': 'Monday', - 'DatePickerDayShortMonday': 'Mon', - 'DatePickerDayLongTuesday': 'Tuesday', - 'DatePickerDayShortTuesday': 'Tue', - 'DatePickerDayLongWednesday': 'Wednesday', - 'DatePickerDayShortWednesday': 'Web', - 'DatePickerDayLongThursday': 'Thursday', - 'DatePickerDayShortThursday': 'Thu', - 'DatePickerDayLongFriday': 'Friday', - 'DatePickerDayShortFriday': 'Fri', - 'DatePickerDayLongSaturday': 'Saturday', - 'DatePickerDayShortSaturday': 'Sat', - - 'DatepickerGoToToday': 'Today', - 'DateTimePickerDate': 'Date', - 'DateTimePickerTime': 'Time', - - // ColorPicker Labels - 'ColorPickerButtonTitle': 'Pick a Color', - - // Number field validation messages - 'NotNumberValidationMessage': 'The value should be a number, actual is:', - 'MinimumNumberValidationMessage': 'The value should be greater than:', - 'MaximumNumberValidationMessage': 'The value should be lower than:', - - // TermPicker - "TermPickerNoTerms": "Term set does not contain any terms", - "TermPickerExpandTitle": "Expand this Term Set", - "TermPickerExpandNode": "Expand this Node", - "TermPickerMenuTermSet": "Menu for Term Set", - "TermPickerMenuGroup": "Menu for Term Set", - "TermPickerInLabel": "in", - "TermPickerTermSetLabel": "Term Set", - - // Multi-select field + SaveButtonLabel: "Save", + CancelButtonLabel: "Cancel", + PeoplePickerSuggestedContacts: "Suggested people", + PeoplePickerSuggestedGroups: "Suggested groups", + PeoplePickerSuggestedCombined: "Suggested people and groups", + PeoplePickerNoResults: "No result found", + PeoplePickerLoading: "Loading results ...", + DatePickerMonthLongJanuary: "January", + DatePickerMonthShortJanuary: "Jan", + DatePickerMonthLongFebruary: "February", + DatePickerMonthShortFebruary: "Feb", + DatePickerMonthLongMarch: "March", + DatePickerMonthShortMarch: "Mar", + DatePickerMonthLongApril: "April", + DatePickerMonthShortApril: "Apr", + DatePickerMonthLongMay: "May", + DatePickerMonthShortMay: "May", + DatePickerMonthLongJune: "June", + DatePickerMonthShortJune: "Jun", + DatePickerMonthLongJuly: "July", + DatePickerMonthShortJuly: "Jul", + DatePickerMonthLongAugust: "August", + DatePickerMonthShortAugust: "Aug", + DatePickerMonthLongSeptember: "September", + DatePickerMonthShortSeptember: "Sept", + DatePickerMonthLongOctober: "October", + DatePickerMonthShortOctober: "Oct", + DatePickerMonthLongNovember: "November", + DatePickerMonthShortNovember: "Nov", + DatePickerMonthLongDecember: "December", + DatePickerMonthShortDecember: "Dec", + DatePickerDayLongSunday: "Sunday", + DatePickerDayShortSunday: "Sun", + DatePickerDayLongMonday: "Monday", + DatePickerDayShortMonday: "Mon", + DatePickerDayLongTuesday: "Tuesday", + DatePickerDayShortTuesday: "Tue", + DatePickerDayLongWednesday: "Wednesday", + DatePickerDayShortWednesday: "Web", + DatePickerDayLongThursday: "Thursday", + DatePickerDayShortThursday: "Thu", + DatePickerDayLongFriday: "Friday", + DatePickerDayShortFriday: "Fri", + DatePickerDayLongSaturday: "Saturday", + DatePickerDayShortSaturday: "Sat", + DatepickerGoToToday: "Today", + DateTimePickerDate: "Date", + DateTimePickerTime: "Time", + ColorPickerButtonTitle: "Pick a Color", + NotNumberValidationMessage: "The value should be a number, actual is:", + MinimumNumberValidationMessage: "The value should be greater than:", + MaximumNumberValidationMessage: "The value should be lower than:", + TermPickerNoTerms: "Term set does not contain any terms", + TermPickerExpandTitle: "Expand this Term Set", + TermPickerExpandNode: "Expand this Node", + TermPickerMenuTermSet: "Menu for Term Set", + TermPickerMenuGroup: "Menu for Term Set", + TermPickerInLabel: "in", + TermPickerTermSetLabel: "Term Set", propertyFieldMultiSelectNoOptions: "No options to select", - - // Collection data - "CollectionDataEmptyFields": "No fields were provided for the collection data.", - "CollectionDataEmptyValue": "No data in your collection.", - 'CollectionAddRowButtonLabel': 'Add data to the collection', - 'CollectionDeleteRowButtonLabel': 'Delete the current row', - 'CollectionSaveAndAddButtonLabel': 'Add and save', + CollectionDataEmptyFields: "No fields were provided for the collection data.", + CollectionDataEmptyValue: "No data in your collection.", + CollectionAddRowButtonLabel: "Add data to the collection", + CollectionDeleteRowButtonLabel: "Delete the current row", + CollectionSaveAndAddButtonLabel: "Add and save", CollectionDataItemShowErrorsLabel: "Show row errors", CollectionDataItemFieldRequiredLabel: "Field is required.", - InvalidUrlError: "The provided URL is not valid" + InvalidUrlError: "The provided URL is not valid", + DescriptionLabel: "Description", + MoreInfoLabel: "More info", + AboutGroupLabel: "About" } }); diff --git a/src/loc/fr-fr.js b/src/loc/fr-fr.js index eb64c29b..128828d4 100644 --- a/src/loc/fr-fr.js +++ b/src/loc/fr-fr.js @@ -1,88 +1,75 @@ -define([], function () { +define([], function() { return { - // Common field labels - 'SaveButtonLabel': 'Sauvegarder', - 'CancelButtonLabel': 'Annuler', - - // PeoplePicker labels - 'PeoplePickerSuggestedContacts': 'Personnes suggérées', - 'PeoplePickerSuggestedGroups': 'Groupes suggérés', - 'PeoplePickerSuggestedCombined': 'Personnes et groupes suggérés', - 'PeoplePickerNoResults': 'Aucun résultat trouvé', - 'PeoplePickerLoading': 'Chargement des résultats ...', - - // DatePicker labels - 'DatePickerMonthLongJanuary': 'Janvier', - 'DatePickerMonthShortJanuary': 'Jan.', - 'DatePickerMonthLongFebruary': 'Février', - 'DatePickerMonthShortFebruary': 'Fev.', - 'DatePickerMonthLongMarch': 'Mars', - 'DatePickerMonthShortMarch': 'Mar.', - 'DatePickerMonthLongApril': 'Avril', - 'DatePickerMonthShortApril': 'Avr.', - 'DatePickerMonthLongMay': 'Mai', - 'DatePickerMonthShortMay': 'Mai', - 'DatePickerMonthLongJune': 'Juin', - 'DatePickerMonthShortJune': 'Juin', - 'DatePickerMonthLongJuly': 'Juillet', - 'DatePickerMonthShortJuly': 'Jul.', - 'DatePickerMonthLongAugust': 'Août', - 'DatePickerMonthShortAugust': 'Août', - 'DatePickerMonthLongSeptember': 'Septembre', - 'DatePickerMonthShortSeptember': 'Sept.', - 'DatePickerMonthLongOctober': 'Octobre', - 'DatePickerMonthShortOctober': 'Oct.', - 'DatePickerMonthLongNovember': 'Novembre', - 'DatePickerMonthShortNovember': 'Nov.', - 'DatePickerMonthLongDecember': 'Decembre', - 'DatePickerMonthShortDecember': 'Dec.', - 'DatePickerDayLongSunday': 'Dimanche', - 'DatePickerDayShortSunday': 'Dim', - 'DatePickerDayLongMonday': 'Lundi', - 'DatePickerDayShortMonday': 'Lun', - 'DatePickerDayLongTuesday': 'Mardi', - 'DatePickerDayShortTuesday': 'Mar', - 'DatePickerDayLongWednesday': 'Mercredi', - 'DatePickerDayShortWednesday': 'Mer', - 'DatePickerDayLongThursday': 'Jeudi', - 'DatePickerDayShortThursday': 'Jeu', - 'DatePickerDayLongFriday': 'Vendredi', - 'DatePickerDayShortFriday': 'Ven', - 'DatePickerDayLongSaturday': 'Samedi', - 'DatePickerDayShortSaturday': 'Sam', - - 'DatepickerGoToToday': 'Aujourd\'hui', - 'DateTimePickerDate': 'Date', - 'DateTimePickerTime': 'Temps', - - // ColorPicker Labels - 'ColorPickerButtonTitle': 'Choisis une couleur', - - // Number field validation messages - 'NotNumberValidationMessage': 'La valeur doit être un nombre, la valeur actuel est :', - 'MinimumNumberValidationMessage': 'La valeur doit être supérieure à :', - 'MaximumNumberValidationMessage': 'La valeur doit être inférieure à :', - - // TermPicker - "TermPickerNoTerms": "L'ensemble de termes ne contient aucun terme", - "TermPickerExpandTitle": "Développer cet ensemble de termes", - "TermPickerExpandNode": "Développer ce nœud", - "TermPickerMenuTermSet": "Menu pour l'ensemble de termes", - "TermPickerMenuGroup": "Menu pour l'ensemble de termes", - "TermPickerInLabel": "dans", - "TermPickerTermSetLabel": "Ensemble de termes", - - // Multiselect field + SaveButtonLabel: "Sauvegarder", + CancelButtonLabel: "Annuler", + PeoplePickerSuggestedContacts: "Personnes suggérées", + PeoplePickerSuggestedGroups: "Groupes suggérés", + PeoplePickerSuggestedCombined: "Personnes et groupes suggérés", + PeoplePickerNoResults: "Aucun résultat trouvé", + PeoplePickerLoading: "Chargement des résultats ...", + DatePickerMonthLongJanuary: "Janvier", + DatePickerMonthShortJanuary: "Jan.", + DatePickerMonthLongFebruary: "Février", + DatePickerMonthShortFebruary: "Fev.", + DatePickerMonthLongMarch: "Mars", + DatePickerMonthShortMarch: "Mar.", + DatePickerMonthLongApril: "Avril", + DatePickerMonthShortApril: "Avr.", + DatePickerMonthLongMay: "Mai", + DatePickerMonthShortMay: "Mai", + DatePickerMonthLongJune: "Juin", + DatePickerMonthShortJune: "Juin", + DatePickerMonthLongJuly: "Juillet", + DatePickerMonthShortJuly: "Jul.", + DatePickerMonthLongAugust: "Août", + DatePickerMonthShortAugust: "Août", + DatePickerMonthLongSeptember: "Septembre", + DatePickerMonthShortSeptember: "Sept.", + DatePickerMonthLongOctober: "Octobre", + DatePickerMonthShortOctober: "Oct.", + DatePickerMonthLongNovember: "Novembre", + DatePickerMonthShortNovember: "Nov.", + DatePickerMonthLongDecember: "Decembre", + DatePickerMonthShortDecember: "Dec.", + DatePickerDayLongSunday: "Dimanche", + DatePickerDayShortSunday: "Dim", + DatePickerDayLongMonday: "Lundi", + DatePickerDayShortMonday: "Lun", + DatePickerDayLongTuesday: "Mardi", + DatePickerDayShortTuesday: "Mar", + DatePickerDayLongWednesday: "Mercredi", + DatePickerDayShortWednesday: "Mer", + DatePickerDayLongThursday: "Jeudi", + DatePickerDayShortThursday: "Jeu", + DatePickerDayLongFriday: "Vendredi", + DatePickerDayShortFriday: "Ven", + DatePickerDayLongSaturday: "Samedi", + DatePickerDayShortSaturday: "Sam", + DatepickerGoToToday: "Aujourd\'hui", + DateTimePickerDate: "Date", + DateTimePickerTime: "Temps", + ColorPickerButtonTitle: "Choisis une couleur", + NotNumberValidationMessage: "La valeur doit être un nombre, la valeur actuel est :", + MinimumNumberValidationMessage: "La valeur doit être supérieure à :", + MaximumNumberValidationMessage: "La valeur doit être inférieure à :", + TermPickerNoTerms: "L'ensemble de termes ne contient aucun terme", + TermPickerExpandTitle: "Développer cet ensemble de termes", + TermPickerExpandNode: "Développer ce nœud", + TermPickerMenuTermSet: "Menu pour l'ensemble de termes", + TermPickerMenuGroup: "Menu pour l'ensemble de termes", + TermPickerInLabel: "dans", + TermPickerTermSetLabel: "Ensemble de termes", propertyFieldMultiSelectNoOptions: "Aucune option à sélectionner", - - // Collection data - "CollectionDataEmptyFields": "Aucun champ n'a été fourni pour la collection de données.", - "CollectionDataEmptyValue": "Aucune donnée dans votre collection.", - 'CollectionAddRowButtonLabel': 'Ajouter des données à la collection', - 'CollectionDeleteRowButtonLabel': 'Supprimer la ligne', - 'CollectionSaveAndAddButtonLabel': 'Ajouter et sauvegarder', + CollectionDataEmptyFields: "Aucun champ n'a été fourni pour la collection de données.", + CollectionDataEmptyValue: "Aucune donnée dans votre collection.", + CollectionAddRowButtonLabel: "Ajouter des données à la collection", + CollectionDeleteRowButtonLabel: "Supprimer la ligne", + CollectionSaveAndAddButtonLabel: "Ajouter et sauvegarder", CollectionDataItemShowErrorsLabel: "Afficher les erreurs de ligne", CollectionDataItemFieldRequiredLabel: "Champ obligatoire", InvalidUrlError: "L'URL fournie n'est pas valide", + DescriptionLabel: "La description", + MoreInfoLabel: "Plus d'informations", + AboutGroupLabel: "Sur" } -}); +}); \ No newline at end of file diff --git a/src/loc/nl-nl.js b/src/loc/nl-nl.js index 9cb1c81f..2e884579 100644 --- a/src/loc/nl-nl.js +++ b/src/loc/nl-nl.js @@ -1,88 +1,75 @@ -define([], function () { +define([], function() { return { - // Common field labels - 'SaveButtonLabel': 'Opslaan', - 'CancelButtonLabel': 'Annuleren', - - // PeoplePicker labels - 'PeoplePickerSuggestedContacts': 'Voorgestelde personen', - 'PeoplePickerSuggestedGroups': 'Voorgestelde groepen', - 'PeoplePickerSuggestedCombined': 'Voorgestelde personen en groepen', - 'PeoplePickerNoResults': 'Geen resultaten gevonden', - 'PeoplePickerLoading': 'Resultaten laden ...', - - // DatePicker labels - 'DatePickerMonthLongJanuary': 'Januari', - 'DatePickerMonthShortJanuary': 'Jan', - 'DatePickerMonthLongFebruary': 'Februari', - 'DatePickerMonthShortFebruary': 'Feb', - 'DatePickerMonthLongMarch': 'Maart', - 'DatePickerMonthShortMarch': 'Maa', - 'DatePickerMonthLongApril': 'April', - 'DatePickerMonthShortApril': 'Apr', - 'DatePickerMonthLongMay': 'Mei', - 'DatePickerMonthShortMay': 'Mei', - 'DatePickerMonthLongJune': 'Juni', - 'DatePickerMonthShortJune': 'Jun', - 'DatePickerMonthLongJuly': 'Juli', - 'DatePickerMonthShortJuly': 'Jul', - 'DatePickerMonthLongAugust': 'Augustus', - 'DatePickerMonthShortAugust': 'Aug', - 'DatePickerMonthLongSeptember': 'September', - 'DatePickerMonthShortSeptember': 'Sept', - 'DatePickerMonthLongOctober': 'Oktober', - 'DatePickerMonthShortOctober': 'Okt', - 'DatePickerMonthLongNovember': 'November', - 'DatePickerMonthShortNovember': 'Nov', - 'DatePickerMonthLongDecember': 'December', - 'DatePickerMonthShortDecember': 'Dec', - 'DatePickerDayLongSunday': 'Zondag', - 'DatePickerDayShortSunday': 'Zon', - 'DatePickerDayLongMonday': 'Maandag', - 'DatePickerDayShortMonday': 'Maa', - 'DatePickerDayLongTuesday': 'Dinsdag', - 'DatePickerDayShortTuesday': 'Din', - 'DatePickerDayLongWednesday': 'Woensdag', - 'DatePickerDayShortWednesday': 'Woe', - 'DatePickerDayLongThursday': 'Donderdag', - 'DatePickerDayShortThursday': 'Don', - 'DatePickerDayLongFriday': 'Vrijdag', - 'DatePickerDayShortFriday': 'Vri', - 'DatePickerDayLongSaturday': 'Zaterdag', - 'DatePickerDayShortSaturday': 'Zat', - - 'DatepickerGoToToday': 'Vandaag', - 'DateTimePickerDate': 'Dag', - 'DateTimePickerTime': 'Tijd', - - // ColorPicker Labels - 'ColorPickerButtonTitle': 'Kies een kleur', - - // Number field validation messages - 'NotNumberValidationMessage': 'De waarde moet een nummer zijn. Huidige waarde is:', - 'MinimumNumberValidationMessage': 'De waarde moet groter zijn dan:', - 'MaximumNumberValidationMessage': 'De waarde moet kleiner zijn dan:', - - // TermPicker - "TermPickerNoTerms": "De termen set heeft geen termen beschikbaar", - "TermPickerExpandTitle": "Vouw deze termen set uit", - "TermPickerExpandNode": "Vouw deze node uit", - "TermPickerMenuTermSet": "Menu voor de termen set", - "TermPickerMenuGroup": "Menu voor de groep", - "TermPickerInLabel": "in", - "TermPickerTermSetLabel": "Termen set", - - // Multi-select field + SaveButtonLabel: "Opslaan", + CancelButtonLabel: "Annuleren", + PeoplePickerSuggestedContacts: "Voorgestelde personen", + PeoplePickerSuggestedGroups: "Voorgestelde groepen", + PeoplePickerSuggestedCombined: "Voorgestelde personen en groepen", + PeoplePickerNoResults: "Geen resultaten gevonden", + PeoplePickerLoading: "Resultaten laden ...", + DatePickerMonthLongJanuary: "Januari", + DatePickerMonthShortJanuary: "Jan", + DatePickerMonthLongFebruary: "Februari", + DatePickerMonthShortFebruary: "Feb", + DatePickerMonthLongMarch: "Maart", + DatePickerMonthShortMarch: "Maa", + DatePickerMonthLongApril: "April", + DatePickerMonthShortApril: "Apr", + DatePickerMonthLongMay: "Mei", + DatePickerMonthShortMay: "Mei", + DatePickerMonthLongJune: "Juni", + DatePickerMonthShortJune: "Jun", + DatePickerMonthLongJuly: "Juli", + DatePickerMonthShortJuly: "Jul", + DatePickerMonthLongAugust: "Augustus", + DatePickerMonthShortAugust: "Aug", + DatePickerMonthLongSeptember: "September", + DatePickerMonthShortSeptember: "Sept", + DatePickerMonthLongOctober: "Oktober", + DatePickerMonthShortOctober: "Okt", + DatePickerMonthLongNovember: "November", + DatePickerMonthShortNovember: "Nov", + DatePickerMonthLongDecember: "December", + DatePickerMonthShortDecember: "Dec", + DatePickerDayLongSunday: "Zondag", + DatePickerDayShortSunday: "Zon", + DatePickerDayLongMonday: "Maandag", + DatePickerDayShortMonday: "Maa", + DatePickerDayLongTuesday: "Dinsdag", + DatePickerDayShortTuesday: "Din", + DatePickerDayLongWednesday: "Woensdag", + DatePickerDayShortWednesday: "Woe", + DatePickerDayLongThursday: "Donderdag", + DatePickerDayShortThursday: "Don", + DatePickerDayLongFriday: "Vrijdag", + DatePickerDayShortFriday: "Vri", + DatePickerDayLongSaturday: "Zaterdag", + DatePickerDayShortSaturday: "Zat", + DatepickerGoToToday: "Vandaag", + DateTimePickerDate: "Dag", + DateTimePickerTime: "Tijd", + ColorPickerButtonTitle: "Kies een kleur", + NotNumberValidationMessage: "De waarde moet een nummer zijn. Huidige waarde is:", + MinimumNumberValidationMessage: "De waarde moet groter zijn dan:", + MaximumNumberValidationMessage: "De waarde moet kleiner zijn dan:", + TermPickerNoTerms: "De termen set heeft geen termen beschikbaar", + TermPickerExpandTitle: "Vouw deze termen set uit", + TermPickerExpandNode: "Vouw deze node uit", + TermPickerMenuTermSet: "Menu voor de termen set", + TermPickerMenuGroup: "Menu voor de groep", + TermPickerInLabel: "in", + TermPickerTermSetLabel: "Termen set", propertyFieldMultiSelectNoOptions: "Geen opties om te selecteren", - - // Collection data - "CollectionDataEmptyFields": "Er zijn geen velden opgegeven voor de data collectie control.", - "CollectionDataEmptyValue": "Er is geen data in de collectie.", - 'CollectionAddRowButtonLabel': 'Voeg data toe aan de collectie', - 'CollectionDeleteRowButtonLabel': 'Verwijder de huidige rij', - 'CollectionSaveAndAddButtonLabel': 'Voeg toe en sla op', + CollectionDataEmptyFields: "Er zijn geen velden opgegeven voor de data collectie control.", + CollectionDataEmptyValue: "Er is geen data in de collectie.", + CollectionAddRowButtonLabel: "Voeg data toe aan de collectie", + CollectionDeleteRowButtonLabel: "Verwijder de huidige rij", + CollectionSaveAndAddButtonLabel: "Voeg toe en sla op", CollectionDataItemShowErrorsLabel: "Problemen tonen", CollectionDataItemFieldRequiredLabel: "Veld is verplicht.", - InvalidUrlError: "De huidige URL is niet geldig" + InvalidUrlError: "De huidige URL is niet geldig", + DescriptionLabel: "Beschrijving", + MoreInfoLabel: "Meer info", + AboutGroupLabel: "Over" } -}); +}); \ No newline at end of file diff --git a/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx b/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx index 58dd81a2..15f1b99c 100644 --- a/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx +++ b/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx @@ -2,50 +2,51 @@ import * as React from 'react'; import * as strings from 'PropertyControlStrings'; import { IPropertyWebPartInformationHostProps } from './IPropertyWebPartInformationHost'; import PropertyFieldHeader from '../../common/propertyFieldHeader/PropertyFieldHeader'; +import * as telemetry from '../../common/telemetry'; export default class PropertyWebPartInformationHost extends React.Component { - constructor(props: IPropertyWebPartInformationHostProps) { - super(props); - } + constructor(props: IPropertyWebPartInformationHostProps) { + super(props); - private moreInfoLink = (): JSX.Element => { - if (this.props.moreInfoLink !== undefined) { - return ; - } else { - return; - } + telemetry.track('PropertyWebPartInformation', {}); + } + + public render(): JSX.Element { + let iframeElm: JSX.Element = null; + if (this.props.videoProperties && this.props.videoProperties.embedLink !== "") { + let linkProperties = {}; + linkProperties["src"] = this.props.videoProperties.embedLink; + + if (this.props.videoProperties.height) { + linkProperties["height"] = this.props.videoProperties.height; + } + + if (this.props.videoProperties.width) { + linkProperties["width"] = this.props.videoProperties.width; + } + for (let prop in this.props.videoProperties.properties) + { + linkProperties["prop"] = this.props.videoProperties[prop]; + } + + iframeElm = ; } - private youtubeEmbed = (): JSX.Element => { - let linkProperties = {}; - if (this.props.videoProperties !== undefined && this.props.videoProperties.embedLink !== "") { - linkProperties["src"] = this.props.videoProperties.embedLink; - if (this.props.videoProperties.height) { - linkProperties["height"] = this.props.videoProperties.height; - } - if (this.props.videoProperties.width) { - linkProperties["width"] = this.props.videoProperties.width; - } - for(let prop in this.props.videoProperties.properties) - { - linkProperties["prop"] = this.props.videoProperties[prop]; - } - return ; - } else { - return; + return ( +
+ +
+ + { + this.props.moreInfoLink && ( + + ) } - } - public render(): JSX.Element { - return ( -
- -
- - -
- ); - } + {iframeElm} +
+ ); + } } From 84f6d3d1be68b076bd609ad9aeaf4a65c60359ea Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Tue, 30 Oct 2018 08:23:41 +0100 Subject: [PATCH 20/34] Changelog updates --- CHANGELOG.json | 9 ++++++--- CHANGELOG.md | 7 ++++++- docs/documentation/docs/about/release-notes.md | 7 ++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index 485fad12..5e948a82 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -3,19 +3,22 @@ { "version": "1.12.0", "changes": { - "new": [], + "new": [ + "`PropertyWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108)" + ], "enhancements": [ "Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82)", "French localization added [#84](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/84)", "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)", "`PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102)", - "`PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104)" + "`PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104)", + "Hide callout from the controls with callout if no message is provided [#107](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/107)" ], "fixes": [ "`PropertyFieldCollectionData`: Fixed catastrophic backtracking regex issue for URL validation [#99](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/99)" ] }, - "contributions": ["[Junle Li](https://github.com/lijunle)", "[PooLP](https://github.com/PooLP)"] + "contributions": ["[Junle Li](https://github.com/lijunle)", "[PooLP](https://github.com/PooLP)", "[Erwin van Hunen](https://github.com/erwinvanhunen)"] }, { "version": "1.11.0", diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e0191c6..7f1ce620 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 1.12.0 +**New control(s)** + +- `PropertyWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108) + **Enhancements** - Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82) @@ -9,6 +13,7 @@ - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - `PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) +- Hide callout from the controls with callout if no message is provided [#107](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/107) **Fixes** @@ -16,7 +21,7 @@ ### Contributors -Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP). +Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP), [Erwin van Hunen](https://github.com/erwinvanhunen). ## 1.11.0 diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index 7e0191c6..7f1ce620 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -2,6 +2,10 @@ ## 1.12.0 +**New control(s)** + +- `PropertyWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108) + **Enhancements** - Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82) @@ -9,6 +13,7 @@ - `PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98) - `PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) +- Hide callout from the controls with callout if no message is provided [#107](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/107) **Fixes** @@ -16,7 +21,7 @@ ### Contributors -Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP). +Special thanks to our contributors (in alphabetical order): [Junle Li](https://github.com/lijunle), [PooLP](https://github.com/PooLP), [Erwin van Hunen](https://github.com/erwinvanhunen). ## 1.11.0 From 04966998b0bd1033c3fb92d1ef262d09d2c926a9 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Oct 2018 10:32:30 +0100 Subject: [PATCH 21/34] Added property editor --- .../PropertyControlsTestWebPart.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index cd3e4350..8754f021 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -36,6 +36,7 @@ import { PropertyFieldOrder } from '../../PropertyFieldOrder'; import { orderedItem } from './components/OrderedItem'; import { PropertyFieldSwatchColorPicker, PropertyFieldSwatchColorPickerStyle } from '../../PropertyFieldSwatchColorPicker'; import { PropertyWebPartInformation } from '../../propertyFields/webPartInformation'; +import { RawPropertyEditor } from '../../propertyFields/rawPropertyEditor/RawPropertyEditor'; /** * Web part that can be used to test out the various property controls @@ -523,7 +524,17 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart Date: Tue, 30 Oct 2018 21:11:55 +0100 Subject: [PATCH 22/34] Added documentation --- .../docs/assets/propertyeditorexpanded.png | Bin 0 -> 29141 bytes .../docs/assets/propertyeditorinpane.png | Bin 0 -> 2160 bytes .../docs/assets/webpartinformation.png | Bin 0 -> 96341 bytes .../docs/controls/PropertyEditor.md | 49 ++++++++++++++ .../controls/PropertyWebPartInformation.md | 63 ++++++++++++++++++ docs/documentation/docs/index.md | 3 +- 6 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 docs/documentation/docs/assets/propertyeditorexpanded.png create mode 100644 docs/documentation/docs/assets/propertyeditorinpane.png create mode 100644 docs/documentation/docs/assets/webpartinformation.png create mode 100644 docs/documentation/docs/controls/PropertyEditor.md create mode 100644 docs/documentation/docs/controls/PropertyWebPartInformation.md diff --git a/docs/documentation/docs/assets/propertyeditorexpanded.png b/docs/documentation/docs/assets/propertyeditorexpanded.png new file mode 100644 index 0000000000000000000000000000000000000000..928e974c8ca60f4347cfc653b68ea72a7301c959 GIT binary patch literal 29141 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 XZI1=ddU;RbUV6-nhF{xXbXockWs<-;bFe zS(R&NoQybed`D!Mg1iI*EG{e<7#M<-q^J@Y7&znC{RIH}>z9+3s_E+w#!gbx5ey7* z;J*tzi3Snx3;gaRB`5ZM7xpJSDwEvLywd+cVj50D&Q9jG4q&BK6OvyLywevXYU*h0 zU}5KEVQT}1217*hg~R@bi`d$^J6M>RJAqXoO>lpqi2p+!Ob!1NC3Lc|HU(pQM1uKx z0`uP!W!v9Qu7(b#V7hjn|B1u>@8uSb##V-3q7GoqJqYPFAL1C6{v)U|@t`QldgC zZkgwu?wPt0&Y;)Ivd-z5gx}hAHUFZb5Qc2f+7R60Eda`y4eqrV-z9I+$@YaR_Q`WJ zMhuaK4)to1I#P6K`k{!OW<94S*{&+41XKTF_r9)U3!OJv85_yaxzErxdhqsFl|4!< z{G2+mK^S7cbo=BdXl$D<)m3c|(XVW@T%b0rY}_A-BN@gIdec-Vl!(UX%4TqY82>^t z#pDgR9QIS|M__2ba7Roo|AUb@<0)dIn%?`)y9f4n?atu5losK@GtU!Ufu}bX?A5;0 z%>^s>QkrZMiRcu3VwZeuovrbQB<)sPUDum~?H4`vi*uvN#n%z9x4OQW&#NbG~w%u!@fH*;?6 zy~n|5P>ceqC@!_XK`+g>d%$VGxt@K`5=|n-R$eY8@ zqP=3z{imhFDt)2#Bkik>J!w%-8#KozsozAlM-0)d)+aAF+E+R~NwU^1?@X9RUgY{K zR!+OuxO-r82LH3ac2=N1qY|iA^bA@X`Z(J-VgdTUE;qSgExnq#+Mb)NX-W9W3!evc zMb+~Qv~;D&^#hl21-hLP`ZLn4On5kI&t5n``5(wYiT}BXWy%`M!48Y3eUUL1Sxn#? zaN8d=RPRmj`sclRmS1{ z`NantpzJ&c{9U~}hy21Cq%QC+r02@#!MU>F7OLEVgNEDibA@#BA78{&lJ5DM0DOn6 zE4jn|h`kyoi9dqP7BsMl8^&CW;x5Z(xH@OD{nekSsX}kuvdLkqEXnC&ZJLn*T^HWo z0K4UbHr}N=H{pBc%bJSY(%2MM0sB|8KCSGqQtu;ctMR0gIW?pCr@_5eF*)~uj}eW5_2F|@)cM0e^JQ0M zjR#%lwTLcox$V-be0eZEseR7u#CY%WU(rIRjbGQM+}(rCU)wz=5ufgPAd4kve65=9 zYb2NO5>i^|^qa1*20Iefap9|`83LX)g#sed4(QjH!`n$nK6ua~K3I>pI$kqDre6Hh z`)*u2`p<8x`iIszsWJm60ZxZHzQ6PKt*#shFLi<^u6gZKeF?aG%V3Ln!|@3tPud{ibE&G^>3-6@)@+Cnxr&sv_RY;V>bxAv#B)$QeM8J0HO@bq64 zxdY2%e4}`lUfw*a4OKs_t)4F(S^iyc`rfW}-gUjwcYy?OKIW?D*E|u$_h?th?+vSJ^cC z1XK^gMEmA2YOc# zZf<4G5djkf$j|N&^q6pihk`+#@0zbr`efPdb^=M z`Z6@H6{xjvc(W`2WZu)JmX9xO+I8K=)5E6rkvH>s(>LvXLksA7Zay|4?>ltavhlF) z5aZ4HVKW@P|5)_r{Njjj7Pv=nU7>d3vGgGn!#dH-^{z^D@SF{^9;^ zIXipp0ufkQ`8KoZc(%|~3}Syh`2M&m(e=#bdA7jU1XA9r!vJ1HuX$SinqGLw`aFqn zSqf}F$Fe=E=i}p8?sE0%@p%FLY(Uy{ZSSlt9@g_-+gdeV)OtNf^z_t^>1_K%d>ypq zGbdQNH}#bGTxdEv)xOZ5P#E;qUNTv|O6`0k;cF@`9^SkvwbcYx^0|N{zBEakcMey0 zy9{46RUcV;o*i{r5UjlBzTa4Tf0bu*IYV32YVY6NoHzD-*|hk+>-v6I`EZ)uV7=bH zZt&`JJO4n_{&D{0N?2qFyt%)AC-|(}xF6ALf9z#gTYK@anqFvL`;jF3!RP(( zP>r}2-ngh1z4GqaytZ|6Qp?v}zwxyqEd9jIsKxtz36lM6jY%KgK*U4J`192+_Esjh z?oU5GWq#w6J5LtamJK#sUko)7pr!Gq9|?-QSbgx=H1nl3Wvdnc0o68>KDXb@-|RNY z&4XGxDdy$*y_=YMY-~%a&(?}smt%dK=y}egaSp9S*4TWLv&Ne_e7g4@ik_ELnh)LI zjkeFpY8+d6?4JaQh3+473bV$ybRcIowghew#5c~CGY66{e=i_h-dk=Kgne1M{)c^h5!P|1DowR$lt#Fq8_-@3?J2cQO7b)sWkd*XB zV(NcBI|Hk#=%;KmYSpJ<`oG632I8@ccs=@i-yyJW_;1^W6TDo0J3qr43Bm)J-41m* zQqCTAGXc*o%nanPc+5K7oIJdbw`7|}ESyjEh6VNa_=+st-*vXWo6J4xZ>3D-+G{Izh!>7}JPHpR?*2l&z_YC5bc3O5?g{^IJ&n~w z2NhxsO+{285ByS5_FW&fz~`6Yx@mFIQIHH52=x=_Npk^KdGQfAuHi#8P{DH!yU(T> z-?7h|3=u=X!`~U6(h&xX^WXufXBV2&IHL zji9=*Hx`2jIOxGj+|}cHoP9l*G2_+W@L`yGtH|nwUJVia_3=G%X%C^^S08Iq)2aG6 z==-|p1%JdH0@cHCnWjkai5Ax_?WN9&*pd|;&t6v997VRNFcbs|jS3$CWqMTVsmlEg|P4^R_2e14w{G8+Z zhUp4&|JHq<*6u!hLx%tU$NBA{$IA$CJqpF^4Ya2)o^MuadS)gG~)a}-=+VW5=K9w40oFHDYiTcuQv_CxwPby zL3O+Z`fXey5T^?>h%e;tI-T;Ywbhg?b&sRs^fs~&h_Wv zQ!Osopb-t)^ar2*$Ewvux|pB>ScvQGy&v-Dt__{;U|(&=rN zIx&}a*lxz5Gn`8mQ#-y4mj@=}`*fx?-Ac2t9dZ~~yQQfWv^|xHp(d~E>i`*pESf)> zYiki`xmnz9MNKa1(hqf$pBv5gkMJ}$9B0rk$8!I|=wDub7Y}n(u1yTff1voj{K`3a z>~iO~{a8SFdr|!y${F;oImUX*7pS&7GHbfp@&ReT;XrB8yU~H(Hx789xF5Z` zvZlQs7@p>SZ0#~o&Dx)=wd~!x+KrRd^Ez51*;=&6bRY5QIPwX`0k@u@*)P0e2g|qO z0S+4k&jQbxAJcEwpKlCa`?i(}r`vPQUa6`G?(ewWb~g;q?`(fc6Q_=-Y<-HNIQ4Xar_7s|(}g0_<&zRwi;wOkNC3G+7lui9&fAl<>9G$NthGto5QGqeUuo@-yQm_-cd!K;;-y=wYC&eaT{kX zwtFA4Szet}bHxr?-WebjzLXAmNA#KHibrlOovwbB zXD#cB$|9@}yr^0)1i5aqiBb!*v1E7544xvm@laJ1w%dr)K?mdjgxGu3sZm8;5KbUYIUU4TX=-ubvstBmS^X zeBsxrpcG)I!`pB#zB-Zi^UZtwpU2~)$EUNkXWvUycs_eX$khMNr3gw8KmgRMm)g{d z$O8ntS^pJ#n0YY*ju$lVi|FZ}*W(S6P$c=9y+E^SBmP!1c7aWebo_KSo$3U}rl+eO z`%adffa1>Sv|C*IXSjp@5g#w*L7!x?I3p+q_0cfuw#c&thlc=EYuo$(?c@r;RRRlc^22cP5NO2 zQD8=`*+0F}&`yD8gLOo^KEx-ahjr(<_~*4v0i&IQPT;RY5RJq|cE}s^*7OxU-+bRU zj^NKMB7A%H37fswEUsymKML7D#oM_WK#_SqW+(M0MDZYdXN%L~eed~}UAdi%;y(h} zT>Dq>?!U)v5l1sCUspnYPG5%$5&PfUPKi<4JV_*dFIF?fOYs;Jc-=UqwUbnLXk4X*Y0ieVYQ@>^9>k@P0p61+BU1E4yub z^Tvk7tsx7$elY^|Al&ZhuA!Q?`XhJti`n5G9EiDlqzZrQwFEP0*NcL)5LFh@Fl>`o z_OCU;Ds01KxVwuO5ak zdk-U!6?gFK2vfZwj+;>#!N%ZmZ3e*M-8)WPw>`3-m(|ZgsDfXc5r&+|M>iSG$vToqamcU3=mN)!)HdVn1c*x2A3r?3M;_ssy zT_Fl2JGI%!Y3TaIEiRD))$L5-m?JmS9+c((>7MSn+|WzMHhDjZ_l1&QFl`lPEQg&-ml2V$*E1RPZ0oC zyw(H0s+IJuSeRY^Cu2**{P!5|JiC|JUWV_iAxJJeUS_I0FV)4iTkMxsEiAY4P4?f) znPVohkKmSm%HOX~onG|IaZIwRq@KM#uqAV}1k;JovpOtI$;oA4W-PC`zQbXo+lSoz zX|g+FZ!uiBW9M(5+2hiavP0GQ1OqlzPX>)%WIWg9uo#8JcA9zYIuQlxLm#(;U!Gsw zm))lcn+!MinDjkOAuByPx%1~dq++f%uPq$Bbjh9L>-AIoBFU45i<2e5bNyD)FUB%e zQh&6}Fn{W-b}(Iqo2`3%jbBZ=f8FytxP8#{6V79NEF$jcJk-{nd#SwPi=(4SRVFG7 z=6wEpV0{sQMF+}(>9B0GC*Sjq#{U#zEC!ql;E#4tVw-q_$X&7zq7=Tk2Gf0Nlm9Uj zhfkU#U*tna{QrY(_Gm)sAQD}U+MQ%fxp=J&GA zlE@HPS2X<=?@yzjF3m^4+dAxUaBym-8}*-ELFS}2kAK$126W{-)}pI%q4{<9Zw`wy zY@eUEMGwbe_$kF(UN4oSw%B-C`Zng5=k{iqHe*X-<@w&Wqha_tFEk%FJe&Lb@rrP7 zyzVaJj(h_Z|5N^89^Zpb@ZMnZT0Epgbw10)->B>0=m^>SqZk>~xZX(7MN~4OE7C|F zUt_h5)&lBYKg}WPR6X|T4MB>OOL_X;`|v2fexB3m+w)>3<8_w@wJrdrzNtE-g=Kg@ z+b+@K6`1N0IIGj`Px(a=Q5AuNH_;idY7Pl_%g)%mU59EK7xK6dohVt;C_*rgb}s#E;- zBL0t>MPg}DY^d9zU$$HN+I^`v!)^NRIpu$#iOhIg%pYNm&&Q9UiPWZJl{+h2xwTOJ zeusmY%>DzFqQCxha>jtcXfma>`yb^yj>jUN@AfVs0xdeQk)qv%6trvszAvM*$~V~g zOT~{IwOz@<-tlIFmG|wx*6Lu4AOX^FAYrpx=tE^A=#FgL|$QBeh5N>kj%(JGi;Krd_k>GE`0ilE!XdVODkabpY-~BCR;PazWS>o zBapWygB?p z{S$W_*Sss>KYq>;*PZwO&}ooYyCIf7T*NWw=_JFx@c);KyD>-qAF&MpQ>)OpuCMwk z!{w04;_!cXZq(*Y4`4ptVClnni71L1Ri@!YKqCO2IekB>T6gIAzz?~mDVhxoHAqk+ zOd&aN&pF%c5VG3){#oS|Mc^mD@L-VWUq3OT8bCRU9|mEepb7<5kOJ)=m9vo1^qyru zj0oYf`%sa56lMUjTI|3w3dD{>FGOE=V3h9@Qv9?T<2?)zSrmXqQ~?e|hGG-m~qCOU{I>YBd7LLSe8v2GOuXVFjiE`jS`3TPlTm`)Ib&{43aDZ zg8vXpYlH1$1cTH%3vopb5CAw*f$0)lKW z8YW~_d)q!#q@O>Clnn0Ks;$(dJ^lEwu_$#}X+~_X(q5KvI&$%_&hsH#8?H%n=9U9f$)Pn0(B` zOxAJtUdE#C0oG2;Jp~{UpbmiskV)%Sru$At&c~q7wI)Y}5T%cpj*>`0kP>4~tAdvB z8;4MXvqew?A(?fdAK3wzG9tF-^3Z0WG2{WWGf6B2DXf357Ng>T7}nHLM{wmoR!IN- zG-Ks+KDz+86nYaUulW9A%OGY!?O&p4qXfUuufFxo5vr3X(Ep_MVK$=c!_|_GU($5~ z?~^2jphEZ~FMEBy1FHsQj^__fguePhMMWztt=H(qZ*1&5l!GGz4ZA~8L^Eu}1UUFf zg&|UdSqWYmFO|5sbsOyDEb}|UE>KeA(OnjM(ba3+Ho(fqW(G#!na;;S`T*K{-DQID z8r+aiHPkJ3C2^m2bT=U~O_mQCHAp%eL&NHgYYs_zZ&jbVBB`MfgNk~|M+p$wKv}4u zM3e;V8Pehw#u6qpU0tCf8n_^RH*pRM^kwkUrYd|BNYlhpUR_W^g#=e>gE7`ACL+bI zgn0}4#wY}~7#A1|3sj0{=N6XqSBV#dlB9}%DTD+U5^jpVif50+;-ZQjA+_Bb9Vp=2 zUL7b-QOYgwmG~7d3`k5gw-%HvTfiOCfWT0Sabl(~jIDixXyMf*!LyPz=wg5xdSrkU z@>eR2M8>QvS1C(RcGym^EJ)O#9ctlMR3a*L3J5?JjeCG299?c0`b+XykumI62Xrt= znj?2qe4n1qGLlU4>=rPNfofs^4JoQos7r>!fK--i%&z~rgDD$7@e1( z4jN=$l>VHHmt5lXwWq<#+#2fY9Oh!P0gOXM##2HK;S%;(hD8%MfMd8xN%%EFE63m~ z0>WU0E9?Tt<&cH==7OY&3W>x27NC4P0Fa?4CmW4)QN$oyh?J7$-u4Xw6t{bJqzVE& z&9&il~O`c$>Jg%A=gLszR+gZTW+V>|iAB@P)GlG%2+ z#2iDUG!-cUZ{tHiwQp;tMb0;_ZDnNml#ps}4$>nuGBDQ#Q90pQf86NJ#%t%ZM-TU2 z#90@9J$2MS10<#vYjQgW-*FgZF**DTWy$lWzXDVz>12$vGn|Vt!{U1_L~&W|*X8q%AxGFOyg5Y#0o8IMETq zKLsUoNa^5A{1~^Z(tO#)-c#!8ZWA2xIebnJSWU}etzgt}%Cb5;J^#^bs%(BQ)RnqW z^S*$n*hPfI621INup>Iel7HJz=1G#&4gQ!^nl*wbkc>1RH20Y?Z%S^henF3)1lSQVNYsM z2w5H7EIk=emoSkqN|{NWmgV)uvCM>k%*+YmSU2FUDF*I9c%fBs$Au~eveY;l)nm`y zg-WBsq}~~@J@fFW%`-SuXg0q_a)n+TbH-Csbwfs9;fNR!s2!=0q-tCUgWUvycjHA5w9K$$5rhrUNE+2Ylbc zkzGqL=A;Oe{uYpyX%7w2bX?A}?@s|Fs;~$mHZ>QZs%Icc;~4j_EHZk28cL280#Sn)lB=UoGgjS+p1`E|Xl zEMY;@Y`-D~2PhQM5|UB8PWVRQcDfCqNoFuSd1D`1yFr2azqtTq7-QB%zto~<-1YE| zvIJsA(~AmoIem-*h97^5gd!7>8P;N0uQ4`-)WQZAQkLmB%swZMLs_bdl$N-uvh5E4 z`e{~S>Hbb8!^Olrn9xtrdZ&6sBqq7>4+cWWlWV`nk;469gj5%czJLxnC}NF@q2_#r zN8ZGgyKOfKPY_#RJ!_S$;1`7~vtQA#q14c;Infu*Me^j5)KSs6s5zyO7Uud2MKECU z-A~V@2i;s?^ znp_TRZ8nG<8{9llVTu*yBvh+Y-r$;=NP{Ny6k5mj$>sCke%g$AUYpHhT;KUqjAbu_djh%HdI!PH*p?^0Ik+JbI7^YULSi+R_lz zQFGmAnz2)-CCWu1gn*Y5L&CjZKtMTtcdQH#)=mE~qEaGsAuFXEVV+LS+tqcytn9+E zPMco@57zBOoc&LaJDjSM%iW&(?<<~vVS}Lv#qy)5(+)O&?|rWxToVp*VjqI9W3O?` zCC^_j3ObMuy>&VDzR_X6F=is1& z%=53Q+mEl+A#*o{u_7mh#9WKFD)QP=n_JUYB9^)+jqX_&jTbjSTZ_7$i>gNhSXWj;8pg%V+FLfJvt)Z3LVY8*VZw_cF*9pgF8EMtdyM(Zty07&7E#HKp$8+? zSyj5gW>~_wnx=-jF%?eAK!vUZL!1%kB&S3zJ!-;2 zV({K1m_5&;{hIfDmOe~@lcZIG!C!%8g&-1%)K8;DZjFNlM8XR-T8MD@ztohC*~7;{J&RDc(qh^C+=$qEjc>f+gT%L3=ruzMvEWKj znH9Lvkt#3|m9(1wLaHndo11IR?cs)GjUr8ZJJ{uaW)$E{ZeG1ag!w6i@VZ*Xo5e(4 z6=g5gxIO`l?@{S&`iNQ*z zk*KM)n58CKZDfjKMkJ3;Fca^QufiS{p{swILisVg&ai`N;a}}C%>bSuLDSN+vdVGZj_`}q=!hUP=;pa<^t%Fv2#-Y zDwVnkOS@t#hjG|sh&x1`Q3VM~#C`FQztHBa9VFEmDtj$lSFIUg6#CqGj+dv%Gs~(X zB@22?l>4;0^J!7TP=6CLQUn*Sflj1pQKV5QgR7Qc3bwOV;qc(!lA59(Q%2$ zhO{i(q)Xu2_{I1vO(!I?Jq{`Rhl>H>bOz|of{ z$-K~l;2tR&aV?eHSWL_*ni~utIJkDKfaf z%WIiZuz6t(^_Lw5!jfT0m?)AGm%@e>V4u1!gc`OT5-++EJ9FTdpA&!MXRk)faKpGQ z-=<=bebg1vK<2w-(5UyUX|1CLlB8UQ^C;^Izi%a7NH$>87P-hL_JuOMh-c6-Xf18U zs3p)fPe?b2GJO-=IyoVQm`)8gekNUQ1zUzOqkWK)9VXPyg z6=9k@c_s)04hb-}sEs#`fctmqYz0i4n!0u0FEz&JWDllHLUE%)5>m4r16lNMv~ z+J?04u;PL`&_O7G_d_-%Qxg+~V0EVNH0K(Y5O+VWHCC~7u5!DFP-}2**}x0iGNe|h zl%ZzdAK6F$e3?-$+4VxUA?ZW4^N|Px^v=e??sfT_)V4OC>UPNf8 zu_m`E*pSutwPpbrm5jtf$*-0 z&-9v@EYv2JJZN%T&s)}qX;we4!J<@u(kP{bIVqTk_E-?aR_sbWoOqI!`8Oqg6Y*SW zN0f}a6#iXMy`nO3j;Ou(lqE+Xu$38jpP>K3o^Jom&q)zQ*lj6OWl+xRxZ`Uv&r_g8 z4Ke(C!`Aj&kQXK^nJRv3?;&}P{In$UBD6LN;e-rTf?P=&^gU$Fnnj*@yeU{4g%1U% zIn;<&y7gMWQe{RQZGptrGadnS&>(K>Iq4wWmnT0awq}wbBH>)oAW7@I$4-){^zSU) zQVwmThpJ|k6wXxVcO5VX<2C-l(HdPWE}w%b5c1ILml4L?y;H}WcAi3>Fr^q!^V+dm zw|7J|iR@N8O`jear}@@UY@jci*w$mip=^~=uldcyEy(PbDC9w~d7if>ta7#EY&fFI zhTYAwVgTZ(nC=l1vrVZ+Fr`!|1TqwHIVEfue5OWOL2jptfu2;2o6q-Z_j@Q6OI#9d z1tCd7QYD#y+~9r*nvUzbL7jEgoslr=LE(|VP`AsE=ahZ_01&~{4Y{&7Gzfr*D$Qv8 zpGR{M$%>VHleJ;Ww3-_GbxX8|TS%FNbKukp$bbe&9BK$tWVJj|Kjh@xZT4>vBnpz4 zE)5QDPKlK8B^EWK4@y=b2(!RQGP<2Y(#)TfQs?-S(J3&RWZd!hs2UR%o5`emNLETV zA)Rk#wUC>n>2c&3Cg&uhb`Rw(vhQU|s`FBg?8^Uk-K`V91+z|7)2~R4OB%40#%jJU z$?hk}3e%t^(Z1p?me(m!Ej_YG8~C7&NixK_$r!ot)!1W6Mb2*eD|=)pyw$ zMNY89DY9T}C0$*3BiQ6F@Rlg%3l?!}P>WUZiiwS8$@^9zR$pht;)K?g7f640)xw24 z$}w}-x^h0k9<)dT)vGNV!yA(wTH$3K^X=#;t$5S$^ID|}?VwGM*6N&m@MMmfxke|1 zb6JHYBT<9=3u(#3s8;G93BM!Cp(YJw0(F;4%iE3lxRo)&e|CtRY z-cuE8#3VKeRfRPsOOnhp4I6&=xf7M5-=kfn*)!rc;7C!V5KK%Bj~yc%klrKhPYI2W zTY8o7Zd`HR77NGVKu=dJuTpxdY>vUKmw=6y`&N}HB$Ag!fhea42di`QB2Pbru-rMF zX|mM|TgDm_=g|{{z%&S9%xxgegCQ*`r3;N;EmZ+qni1ML9c6za7D1KW9ZJCG0_$|D zfSV9^Ux2p8xo(+>m|D>g`+{Ps!V%OU5sj0tsMcu_BPe#+qjJ*tH-X{SqfRb280y8FxqRhGj$@N z2xsZWqrobZ7P6xXjNdg zJ+Y{gOS@4#5q1}Pd)-u&y83i%a@h7K=GLry`~ z_HRs*&**Vag6XdyC6suO232U{V93>;+0csT6M9~W@n64D*b)ake`MY^S9}uMvi08V zV)0&BmD125MlFuFvzQn|;$X@~Ca;RVyz4-KMX2lw5BOLjX%Lu`QSAL$CsqL|W>yQu zQ^<5|q|{9f%xGFr&m3ru?!$?+XzgM}L{n|x=f+8RYN$RljXzt}%%V(G7?QHm9}Qfm zKo-iN2_T)vAa=iM*S15M~U^>$zdks903~lnl04EXkTI2)6`o$t77mjU(+T^;ew*q4HWT z`)VtN%Et9jP{Y< z!KVXH(6t*Y0LP$`2#^GV5bCUgk*T5=FK}VNp)8&Sqh_9BT1RU@|4IrhsQS1QcDec* z>u=PT&`Bh2{_ryRoUGw#`bCw6vaPf*Nq;GWrVISQ0|K_6(7k}iEo<=zTDrxlZENAl z@zIOKK-&)gr17cz*Z8CfTcF{=%`Mon?-gbL_ZSvt_TFp)fx)e>Jcwe%9ASg7$RcuS zQKj6(+#-a9GI8qWSIyaYNh;z~$gchZHc3-LN`+>HEIaK6bh5sXf3lJrfFM>%v^)}j zYRUqK05c+57Sl2nr!X*oY8YZjF)Bgyj_wE^OJY+$blg06@jw5p{m`cZD1~LjmQYru z>V>6)1o}|hu?EF=ml08Adc(j47LSM)^mliX8o$F_jW>PLC-*2d&P}#Qp5h`+yE&jR zn6UF0;UUjkY5j3Cqf6?EXX9PTg8Z?d`A_M$o+q5N1?1Q-NDlBQXP0!s5%~3>YCN)r zL)^l*pT&yvtUDSDNlIiPZ{jc$pm?faw#)rLD0)7(myko8+P{%Q!blHT;V7(!o(IYb z&}#{-Rwb@M5Jz`7GNvmJQ43N)wlTD_#p}yV(P3+Pp(kUb=zp1altH;F)Jl}-@nT}I zfJCR^{Dx)`AO)1nuMU5Q;k*ippB$KcC}!xA%|eiimcAy^L{WDV$ME+aQ4TV2(oiNR{OKBW+?0f<7s4HGc<34F^gVr8sv5AdJ`Fvee-$!KJLz z>8bg#sZP;+X=;Y~3&8=t+s2b$BUp9^pDpJT+n`;ixI^|MskXEA_r$qDxJqb*swj|7 z=&$h0Xbc!AqoBa)-G;cq1uSv%~7E*AYSiZpzEF+n+x4tLL+LDhpD{Z|t+UpgAOL>jA*0$5({&^ybj0Wm1X zbR&*8tXC9e%)A?u8w&-ked(!7GP%nnwAGbO3k@Z&<5RO!jl{~{MjrbJRG8SK5g6~^ zyg_AVmRJSKs!r{pZq~pCMc}%rhvSejikz~Tc-^ZQnSrVJ14>9raQm0tvI0ra3@jnR zg9=fZX%&fjpotc>z7EbeJRnb`?$<8YNog&!zOv1w`m)D+uigIcG2izL-+g6YABIM0 z(MjyYU}2_QwU}7!@Ik-P^dVexI*d}y5>$go(~l0~gMeJz1sN0k#7JhdBTIWoyTmW1Z z%ij`VV5?+hQCJ6wzCx@D$=*UpBqYY8@3|0z@ja8XUBf8V{lCw#3(Ub?`HojfVqLDj z+s$_-p@9T?_U(bDC{gBwuzI78Q}TTF=aW$;l14I@h=MNrMp`!sImjSsrfxdB)5!bi zIL$uQQm4eH3R6h=6!}7Di{)jzEp218eviE=9S>v;wkQ8Vi%e1+P_U?$aYM!kGy43jk5Cc4o_D^E+4n9Pay5?(1Z`tA=~&kBCMc@D+9TTJ02KiSl4tx*pui7 zYza(Q$`shda5DL*XeQNi_hP5B>0@>g!XR*(_&kHkUUL!bwyb_>({QEIASNND;-2Qh ziMzOlT-adQ&8bZ+9&$Wu)O&(-fGiYLB6K;d4@MNn&AVEK??@I7LQk@vJAf!uHVY6H zMoa93;dX|{a1fF6giMn{m;Ep{jrG+N^bO=bwOjW-UqDu$?Y@V*Q>OTQOj5bDm2_kc zNtxI{l1cKvLXk6ZMgKMfFp`xM5+sQUuZDzsmnDNO3)~lif6(eJi@$cb z<8$##=QSoNY34R=e|>zTQ)9)HTe_5)P|=`Jxl{t|?<2c_1kdE9Qm7MbRS^cGh|bx4 zyVaUy-##w+U8dz)&Oq9P7Y4Tyn1UFTC`ph#__Bdo-2230R@;`EY9u;eRY*ZYA|x)j zD2|CVq!J*luChW|`^0Qq5QvUSq5dmK4K@}$8@y9-3&%2834oW!NUOuSC1(=hiV^#f z!=fYMPXq`Lt4WO~ij0X-EMK5RhihnPP^gxO%)~dG{X1BaI#8*-FpryI0%5M3uNIS9 zCd+8+^Id5BUvotjZBVWPU{(=D#t*V#c5`BvG;m9wQ-F@TIwXc`kkMU&PnU-iUYwL@K#zy;DF|6Bi&?{K?XO2$>pXURq zGuDT%742+LXuyDF#KMp@Dj;=fcB=Fmrbs?pSV{^Tk`m~)Fjv^n_?7T-jFQdomYN=> zz#K~FCnZ_ZGP;|k7DxO0X=Bojvu(hTr~o-cGLI;Bb3=*?3l`*JD7#;H>Shxgs}YnC zWbC=Ziicfm&xPo{`(589Np*4Cg}jg_n`T`xLQuM3)&RcywH&m&*Zr(_*vuzTdggR& zZoR|6e~qH&{2|=+aAE6smDaE0vQm!C<({d$mwqsgg`zS3^h8P_FOQ0zWynVhIAowT zkXK3LX79a$o7!6;*$ZMOg*SM0- z#OG&~C!(CuqPM$wqQYdbC{|DrEt;DDE$vMQITY54B(^Z$!*QvhImkyo{)88wGSGFa)lvE!cAuC+ z{tS0;lWR6PQMrY&lu3vxW=Tr?J9D;dlb%lzoNWdOVEn*VSs{wxrajlKKJ` zMq9@;##s4HJN76F)N#ZX6Lel!{1=DElq88LlfyOgy`QkL#G$KS7RuOsJ|B2m9#&Nc z{?zRy%YXdx5!BYk(|2RRe!9Vzah+$v{Vc_4&CH4SBOy~?1ne5A?(YdN$+p6->BV**4_0e}8CC1Iy>%evl~ACIGf3OR<%1iU~SH`*Yn zn8@7+4hCopzZtSEkX7lseL_ zOD4Gu4KLMemN-F7rCJ0)CAMUH5w}9hRWTX0IT4f9iBJE0?` zhNKcBKX`PtAPp2`MH3UJ_^@=Lq}38MVFh6=fVS}8gk&R`wEW>1Cf`xszB&^lQ~>Qo z#45_5-z-f3o7inuRylRa2{I05DNZ0QMyx-WW`T;D>;id*)4?jE+QQrq+Q;U5Xe=UY z=G=Od-)I;!GMZ`iu~h!gX1nGw2)e7w-2=~NDnmm~IK;qZ7_wV;9W|{b&h#)=XUxVX zWJ!P2z8{t-QSuc-*k%l}__B0b?dC;_d`1pqKX}=Pen{Hb+KRxAE-zynVsldrqta^B z_$igjY5-tVW^y+NKGlKBqH#qk)MPn>mw?*4Gg4lT>(jVL@)V!?zO~+UahYT*soR@w zpmhg&3Xu;3J~}MXf@M}!gx=(R`3owV5dH`%B*^Qv(SUC2?FeM{Z`4Zfs_L=hkFD3< znb*+TzN8}0W8lO&H) zI}y;?)7DGX@A0h<5^;3*L%S#?i=S+G4*Mst)aDe-$;CNYMtYv#4cwn*jnN~B$`l}o zxZKVQ>VKhYgY}QX1TKO*BTWCCgA69)y}yH0#=tHYb!uQBuVc&RQp(pkHL!9Bx7<*u zXA2KzCkG~|L}&la?~JSxSBWanptV2V=cE`u9jQ4+{0v_v1dU2_OD%d-NsaWBsm!G> zGSv3+xwP8lu%e}Er>y@a4U(Id`R!m2H2_J9YQ$9QpLw_+#a^?Fm}1F!vOGJagh&>_ z6ON9)N!L@ZrAB(MOevqq+k1RWRn|z|sI@TYcQatnkk{B4mAr@=fk}VEV+|EBBZUFL zGMIDQ>S?izQX`e1_lK?RYuOOfpVlA_|Dk)GHxp;`O0W~tDH*s(TJ{_NxtCQ&MwqZ7 zf*Zvx1wlQ8ESz=F2nLwF`L7{R15LBQ+`635vwnq;Meql}5kSr7G5yfcNUesurqyU9XP26qAD*A6EmemdQ zHO2P!p}9LFP$If@hIdh{oGwKMT?Q&K6q&g|sgf8H9S({D92)%Twph&s{t0IZ#~5A; zeJuo0E|W%?Y68JEVbv6jXx*i&X4Cb1FGFQp{I9ADTO}zy?)A<~^{;pu$=A1BB4RS+ zmd@DoC4{155MQYZXQBBNmY1C>G{y{K`zWl#C^VwQU-N|$!r5*8ys|%*T!Ko+|5tL!xF^QAg zJrRlCYh|ekSq#G5Q%OC2miZIGm1qJzH^PVbH44)&huT9FyvaPpAA$qzDQR_YF%?dd z{VWC3L#Ay1F94uGU%%BwSVK#pz{1ud(rT0poqf*6X?zxeU~+PjdaX*ST&BIf-Nmji z6;Ucc_}$nbK58V=GmD9nt5DRUIzmW)uR#1RS&2m;gma*ji3^6e8M>u9nKZ(0pu|## z@n>3Hln2*G+SfrQ@7;)4Qd7zW<%^=a-r^l#2{M@dOJNETC8} zqm3a56hej6j78V#i4lL<(q+8;9dG9y@A!EZE?n49*YAAipLoZ+eu=Jqc^w*-N8|ghb(v5(IHD z`RwF41ODvx|DF4Htw$(c@ZjzC7allLVJ>O2az55 z_{%D6OfGJ6YYfFAgkb@tWE^C)QDX*-QAp{w^pmJALJ%()$vH{uLK}xcKomt3yu=nu z7D2;@ydNPvVA2oS)OBoIO%p@U;=gKcc%ij8eaZn7*{T^dbqx16^3`^Vnr&d88o zlJohDXFR(1&Z%p!^{i(-kHw7;mCW}b2nd3JJkQ9ooO928zPn}%g45~Qjcs$fe(^RR zoG*IOi}>92pYr#dm(>vxAvIxlH=-~IYf00lmvA`C-Jo|7gCMUjx^IW|cM z!J_D1|v!)l0Y0L}bS_D|tet3+u{N^jvbu0^8|jHB zK@>=-FgZx!Mbv}EUpk< zPR4_`QcCio05t9Km<8nl?Tlc-?dLNve?jm|kXv5MU{?mFc4<&{D*bh9XFv1h<9s>k zzx?$qPi_1Clwi8sqj|2_>A4HgE_~<9*|Kc)8H-=&ETTOMv#7U|YG_?M-%*DgrNED^ z2`PNQacZVYYOF1Xp8c4P03C!ro6+slwJ>T(>CTs1)dfoZqNatzwWObl5N*vb-&_&C z&5sLES_KQps&1h$Mb<8_OY&_QbQUiCRtmJ#9#Hp#)jso(zVhksU;LaieEQbr^!;}b z&4SCZY}xYmuzgwHmWythq!?qEot~kUq_mP27DE(;Bx!<7Q&y}Tpu4As@yTiD?i7X~ z6{}Vb@QLfMXT!z~?OnD1%_Ay=Ac`Vx{Qft%_Kk0*)tV!UGYP`LpEsLvGpY>!|XlufLq0&dP$<_$ARm zW^;@cL{gDUu(nDd=G|P%ElCTeOqEuafi_?iQ1E}=7HvR{A3>ybtid@a38&}p(->E- zNaK+^g;dhLR^sOPOi9QDtiTqcT{^gjLAJBcb_^221vKW_)c9Xp;|5qIw%z%XQq7P0 zctF(7rvURop*;&|eMaL?FJeC9@NbzP9V$!5^8d~JC{O!1{DV-|gf9K_F>{^=Hh)D= z$H0EBloZT!&-^}1@LgVkwuVTg4D?p1L@7m@lNp0j5K4)WAy~&Op9j%P4C?e1-ZA27 zt2(s1tYxskwd9o_oSt_9a@WG0a?{3d9FbCDags8|2Nitgf-en`j?FH$Y*Q$d4*mU* zk!2}TyP&4E6Y@0H;bkVx9F3yLk-`c58Dr5w=!mi+_c+{q`DxpEd3oGLdpxK;!nL4C zX;Y@k*9%AfltL0n<($2e6lDypW|L;K(H>F{q#%?Qg`uOnlX!7I#32D+Tx@PQzM02dJezI#TZRAH3#bx@r-5kz#UzP_Arp z6{aSjWYrds6rdD^a6WNmr6Z-Fz?0Ktjua_IM*hbAzhz*k2>MsU$-R^hvn_FwGH?pt z4li*JA;1_HxXK&boe&pXTn^!%apAdgJ zBtrTqeA;O)A23f`cfXKj23Ar*aGgh~5H_O{Dtfyjl*~YBg3z_iwXiPRHuEg`Qf=b2 z*+4OWd_t5`ITmB*GtxGGCk#rIc4BUCt+5oM@ZBsY;#YY76~bG4;jW1&X&lmBCt*!{ zTA;|CDTRS~<~(@mX4g1SGH9>k2uTn{2%lkC;|G;-BSA`OEN;~3wB+hJDR0^N{J{JE zlDGWUTNzlk{PY+21-H!VTqauTl@%@{HU?8<6uHxs&(jPg1eGZAbGw#mwThCGk+E^= ztrlUW!V9msk`I3T@!s8BBaPu3Ub0I!Wv1S zBT97&Asq8xFz;Ga-U~{qHm-U4(&jTTgmT2gva2QicmMl^uX*A2^#Euk2%~^NI}0;| z=EUd}_dRi(zxmESh9@#~q)8|c<(P{Q?T23?k*4JmHxoJbxOMhum@->1r+=9R-^-t^ zrC7Ai@AJZjglw0{E>JJXG>rw5V~Z4{>RbF0PxxnAf%okpN|2ZBrZD;TvyDL9O z2tk(R^mf+h>8xN7=pZ5rG+_{+f{;MFR{BCM{O8gUqz{HpNx_#yTKg8gYX7Xu&sExC zC?2CKY(bvqq-jbkNocj2Bxy>P=B~SE%Z{RK%jP&7%zbI42?I^FS|JFXGj+}|h z2m=)m>I!LEkfk{SMYU2Rj;bgX_<*JSXGH{B69gJ11g%!Z7zG27`W2bKa%0M=sK_eVK`?r7lVGbVHPgh4wpde8GS_?%buA+n@j$;>E zr1ctYk~j(pd=tXqg?gUY>jUR=Og#kcRy-xw>-6%mofTnOxwxD2x2?gNgvXCJd366A zCuin(VE-gfpUTLxjB%4PF`QG=f>&QS#F~CZk!Kibu%d!0tdoou!pS!W(v<|pi37Ta zBf$!dC|rAA3jD~8KYca@8G$m$42%vT>_B8qN=(Kdpzoe67@Woh#>?OFcD{UJ_s`u3 zS#yRXPe05%|Mphy&n-d(KHCxtGL#bSm@m()HHaOr;gLVz%(CZxXr6HD)KR|mxv%o! zeg3_^-Cves(Hnn*L*ui;8J~?SNXsv-^Fh(JHTJP?u+~r0;!!@0++sl z$9{hU6F>eumwtYn=VEN`TrrsdLF*AXg(l0Gw@&*sZuU$**{ zaB@(&F{DXKW_#Fr>E-NP-%nQ@ASp=a#yR-Yo4I-SxC>aJZqMgA*>JZ?2qj4~rI{SUnB&)&;rS6p@4WgZ(F zLrIC!iZF_(R;x7T>SWCp9bwSU99^(*V?0TgVXb9&Zzw$xpEm%kdkMabE_8;D@$Cuog))Q4&;}@ zmGD9or^!gWV5ZxP+jI25T&H3lh!%LO0=M%*(5@LQTzTF$L}5_6!oS~rfDix29=exz z5a@_ly|Rn5)+{1VGticT4B4gr%e?nMM58TmO@rt#qKW5MHg)wgXyes!>X=l$h4kzK8hg?rE2mAm|ua$JOVr z=WT!ehphRB&+xmClz)Go2GP3bBnMuzk~Qnj0Q0zSqZq`Z3%Fnvpq6pTr5XSHlc0SZ zTh8dEhX#*6bsS6F28kWs<-X>nlG-_%4`9xWS6J0{qbda~t-ra--&*UrYQo~Qy!^g< zexS>Wy%v@Sd?EqM`YJ>UGAH2a=mVy}0Lm1eRwCN8g6y1E@ki$mF#N#B`R=2!yOE_p z`K(SVud-kqx5-$iAW>2)9G)V*m|j844DqsGe<^47!0gCDp4c_cY|zE(jT_l?`L8js z^85VT507C22c<|Q(N+<-COKB%9(Yk|+KcwEb{tojnV#mcryghDGl!U)YhV$y(lMSr zc$g>(sMe~Sch1?YT{nclVL3{c4`s-n-H)(*#fsCa!e4}-oVjHSH{5&&H{S4FKL6Q& zj3^2rNy)vZV;F?wc|n$>=s=^S;x%vl z4K{At)b6sHqG0&sN$&m0T|D^H`?>9hKctmA+qApxzn}ia{eEGGPyWLvIehRCJ>8vz zf#duIS|O|?&vT+M!ulWxIPEsyX;#`9QMlgu}s1Ih_t<9J}`x{_c?w;k%Z3dNWtQ^N;zbi?;C2H`ciMUz_up8`fuYP^8b1UyV?^^DB*H*52?WHV#_zq5%*^BgL`hmk7n%&8|fk8Ig zJ?sXTnO!-=CY91ms+@7|Cb;W}-xtl*tNNfg%ENaE*HADPYhC$kiv)55O5vR*7VKk* z(`8;x$(4&jY8RKvMgj&*4tb7s2t6o09}q1#sTQCp9R6pVSYJhEEa~lZMyg&9K4~Tt z!pSX#*6o`PLa^4AdAYl>P2MC;C1K#Q-;!D(l%lYX;qGqF1ton^AcSksm@KC-mNhTF zgfn{#!w-Iyuira~(3(6exc83xxcoP+W5pUKkMe`3Pf^i|{iEYd z&dl+mjeUImX9s!1`RiEO8)35CPn%fU`qT!_>@0ZiRqLn*1-Bn+@`-y-VFL@fb^1X8 zEUE=u|4VDAhMI3b*5XSK9Y97gMoN&u0-VOM2M6Xs?_? zgN`7mfKo`4lRR__w;tQdb*l%t*1|t{ysE?J-83AnPtmP7p9p{^6m&oMwY`c_y`pq4jwIm`eGDeT=<-;HP559bS z{w4rWYhJ;Pe{cyq24cb@<@o-GdEa0E7vFFCz+`f)Ucy`6`D)(2b191>NuJDdX!m`* z1n44T?C4W`;S*oNDofsKfi>i66+2&fHCqR|2^AFS zG-C%I=8n6bVS4qIyyeAf>Gb=y{GvbSk1iVK(SQB{Pqi~F>p5=%i9z`c(Y4|6vzN|i z&|oQwE$m#=2~$sS*8?-ewHjd*QDlZJOL*v+VYXecoR!;G65c=SxLsae#^R<1vNR*` z0*2+K)k-mXYJ}a7?q+;!f-KF*bAhpfEH`9+4zVZ%K@cHC!A~D}h&YVccJ>yhh^h@? z5K!a=fB&KP@z?MF$N~)P=Y!XLy$-cnhyTg_*I2{nKJzIi$H(Yf)Jqryo^hWeghU38 zcpHQPdFJp^tR*iB@+<>U(t_ZE7hX(nUmwjzo%jFQ+j(sF9_D82NTtaOP&yzAH64|1 zgbMuBgXA-x{%1~{oMg$sO5%#fNJV3A%JV=S?rrnj2d13DS~_Y~H^ormy5%Slu4C)) zHa`)v;J!T##1|gxm?x_GPLqF&Q)ZOyVq&O&5!&lAg$A05Wl2w!kN(P5K62Yp8kqwK zjjnL=R7$O)**DtaMXQ(bPj~HS|KTy$ZuT;|<&;0UVO?Lul5Wl4ed8pTY#88eJNoI& znr!IT>>P}-vnfMMVw!oC5B$ere(i!@er3xFOiQ@VaNOmN!7jjo=3}of^Joh=&YuK7 zN~Khr5647{rhlh3xj%muF8;Nba8CUh{`H2R@a^3*ghOZYp0~b$Wkv4rss%Tkkoxq- zft+P}0scDQ(C{2Nq4>}JBS0T#TxfiWcQ%)-31~k1B=6ii3@ZkCZJ#UsShI?u4mf$@ z04D&fAv))k-1P1XIMW{Ed*A#qpSo!ulS{Yq(T~5G-%+W{%q&1RS6_Dt%TDa(^WXR} z-`F!t*QN{j%twEj^NJMm44ZfH?!Ws@K6p_tle_NcQ{TLUuk32D^t`LN@q?GLuE@c_ zOW*xAzI@GUI!^523*Whu>+d>_S+$LKzvoSCDq5sTlcd?tRd0L^=Pc8V?tPG-KKLL{ zk7*X4aT%|A`DWzNd-(2GzseUM9tL3e;eY09U%Q1T1a0Y>61yvjp#~>)ZawB%5+Jdz z)0Ynp&>O(q$UaVKO<0MYi;xbeRH~?b_weoSe2+W!)QJL35QI)P-8#k6*;yyyqqXat zA|MO`CMPD@vu6*}Q`5AXO{WQ_G)e```#QS&E6WOOAqaHDgAYE;$rC5Zved2F#__O@ zA3MZ-_uRGM8U6Y2b$X3?`YRs#=>vTKJKy$WTCP%Q)aP7tLo1IpJGp3!CC_q-ylAUN zxU$}mWrmBddI=-L!~De`{Vqoi9wbc)ax^mNpw_*VMFXo@vHA@9m#wC6$qKT(;4|0% z8wU!eCE_1I48eIL2a(W@NI-{RgHvH913U;Zv{PN~^G}?6Z8g zzry_|>ztfy@xb0$W~OIZT+v`t1Rikolm}aO#oEKp#$}Yoljfva2nM-~(-c1QuyFAT z27#&BsrK=LVrtjdxa{NmX$gri5AoiQy@NNeUCV3jPxu(m@eVYn-z36rW6M%tuEjB> zUDp?d^{&O(fD^mNIr;JdHf~=7w>|?qH*!X&;i)GdK|&-nyL6ee7ua(jWfO^_>67 z69}b{_I6(Smw(EaF5J$$U;a&Ab%TM6U&fm@#hke3i@f0P_9B$Vm>=@Zcf5<6F5Agp zoPP(`J@|ayv^iq-@jJQjFK?%19ozes;!nBZ%8l&U^b?LfVUcTgvbs+)x9>-M?UsXX zuvcv(wExDkutfZJlC8*7 z`!0llflj)BSqpB;M1pl7da01xn5&cM02MmL&@c!nGKCa|j#|yBk``{PCJX|yBxUd3 zC#lcPk*6uv<4BnmnB3ttN=Yw~Eh+Nc;bl4`%UkT)y_-ufyV$?h(L$=#3jgvipC$-2 z=bm@Lb4vZ^M6CsJ%oxKRx8KGWuKzSzYx2Bke`c1Y^PD%W=^) z?(Z0D$O?lLijTbK-PEUNu~t*<>Z7V6R9K@xV}!=)3WWh31pLkWuP4nFwa#9exgt$0 zRvTn2=;~dJNt?9l(-@PWLnvAa*urt;v~ClZRV-cS)ITpm3TLZWwuMYvaQzoMbAxD? zkgi1bOne~#g|reQ4BeHe-Oe;vYJp~UCgVl#{R#i|XD?(?2mJB3_7Da!K~MuA$qjMf z0NFyuNb7OXhx%iI~Bc;Gl9h!HA8 z*n*pHJj}5Rx3l)l=OMoL6tBN@h<---+Bfz>5Q7fESRVY^kNDfEm5k46gt(ty`Sp7U zgOUgh*o<8xvp_#_XXhVgu^EK5n#%$FGvGL$|GQwZV363c7hsWfHxOG>9k8Y)M>Nb}rh18zbjuEYqF zx#iqXJVZf&1a?31I5X4Jn7p7~Zx93#zHA}S3xXgd(1JWSgppHRt=H!;1}c>r!zYIs zIW@x2sv+_sLr6gs1xQ)r%m4a0?!4nxe)p|^LPtmEX+f*(PnN%{&&~1izyCY#yZ4?p zO(V;_D4?*!l`6`E_(`KlRyaHxa7e|1Moa(y9{&Rf4Ps8NlvmM_3Xm>RHBt(K@&99%joxm7)Hc>sFO3r9;=LMuI0t zbAJCT2RT$^APlX-FaxZLpp_JaT@~(qy21OteuyL5LZyPR2^I-i3u%-qafK%w2Tm)D zLbwu7Bv>_H5<@pH`->0qb3L7WmY;m}EBwx`8aBw)Qo4DK@1vnZRgEzP{VhH?H^t4qx%yzl{s%s+>O*E-)+a4r2<; z<712fI~K13^CUx^RbY&h2c7d%p<_oCnL5lTzIp&@6p{iPF5@?T|CRjCxl38z5uA2| zS@&mAjeEFr_iA3TeJii|y)#K?CK(xhmM8Ap!?00p|HQ!0*a_)o26Ygil^Xz8K0#jj zf|qmo-~!Ri`Vnru@gasi*Gb^A4Aq`MC>uH&!oW%3_%RmYnfE2kt96JJ1zH3YdFpYa z3{1hq!~|ofMyW+LMox?pg)tUER#=k6wJbxek=9UH%aXnxvb-Q`HIc&kCfGu7X#Zi> z46bqDc{!2cx(B(q001BWNkl?PTd$prABv8 zFDj^U^vKhGCNzU018I@AK&ybf%$GcULJB)Sx>a_#e<2TSA+LvdV~=^BhHo8<0Hp-8 z&9vRlG*}`jnVqTgz|m&Q57 zUDwC?7o5%VRdD3)N7)mE2n+xI)ChmIWq_BSv4t~Mz|bl9=X zt(ot>+LO;9L@@tC1cm24SsO49A-LmNh`O{fQj~9fl?z@U@B91TLzz;JUcV5cnTuP1|Jq8G7r)TKw=p@Z@8qLJD{tZ;45Rtpmt+%U-p%u$% zCN0LtN6BqLni{Hc#HmvwOixeK)7Rx(ynrx_(AtR`)+!ag_4R+_>t8F7(q(oKB(0Pr&E0u0U;{-ERH$`zqobID zfaX+#+(5ILqJs)~VK7DE78`4cYc=91a_3q*4q-<}4XGfCLh?LguHM2FIi0mCOO`BW z_+)~$5~-yh{vY<28$Uu=!8!p>Cz~+@beE0{?@UpG_Y#Hn&FA8_C zWjlbOJSkPX7dA&9;{#tkjEpL%unHo;=!iImDuPT|a;>pOQz(IzDXP#2 zo%7@~lT2N@p5<2$vQ|xV&jTm1L61}KxZ@=IUwbY)UcZ7~4EvvXicEJRl|_uVm;%Ji zGkoZ4M`@+G4{R>jI5Yn|6n6e1tIXYpL zGnQ9q4Iks#p-cItHHwq>f1hhUy&t4Sw5E~Cf_8?m#9d42?FvcfCOGi$ojm5N=8W|;NHW5nESqaJ0gjTabUtcd9)($baYB}SRQ$&F#sW+UwvJFUD zEk?)2Sh{QpN!s+eg9}Vi6ku{EHW(-ulxmgO$z@AxmARXi$h87A;;zcTYbC$?SB4*?Nn-P{_dH-Z}^fqnK)~ zlQ6E*+0~7dk}!013LPloN<>j)P7y>q3WZRDv584+o)cGk$XYW90;eFOo!*$RPM=Nt zvff8EKVxh>JninO=X4?cL6;;w|J{@;vG0+QwJ4fX*jTlJwyAo`%vi#~W=1W7C6x$m z4N6ElYKq;@j&j4j&+z=gE+4!cquEWKJNt8|qvU~ZX~=}7P!e0X@~TjfTZNUDR7k8c zRK9dm`lYuRe=^W4BGDu(5kj+gJ z6bVY^Nafv>Wq`eNm;(iDJ!=y^bEmlN(b&&SOY)OHW7lyQI&&>c8DZDmF(#~$Ajs}~ zipQETc-|HKPG>nNUSLeX6>qqTYdYr1tkB7hOV<(AXE60?M4I!m%U80TI*&hi5OmBB zc8xI009UeXCw#{6iDNDlDqxGQT)GHSc(14=6~f#X04snFUPL_|?cr4mz#W1=WR2MX<#7nG7j zQAk`l#A8S6(7m1)?d%|JwP@ArG#d>XjezZI`q5^Z;b+EOHfJ64yD$b*ShB*AYfWL9 zo2xT3Tcf|sO%c8zMRxTT$ucJyW5Ud+o$@a}>uy$w_-5phyE?&g?wX4g1 zsrO_w%+9zjq0`>?8d*3pr*q@B?U`3c&uLT3+XPeVxeo$2oUTguZ{ZXyTCEmIk~sOE z!q7@m>h&hGa}AO-2ca-lQW(kd5Sh8yOs0 z!@$4_`uZ2s)7wi=UoTx<-E?$z(ACumLK4R@MPZ2Ih|ca#I(xcVJg|)AtJbh`a6Lt7x%yRzO ztJwAIQM7si)-?Im3zxE?x5B}hjGrDD=GbIHGY^@VYcMtiqcb7fH&;1hO`ntJkn`em zW%lJtNT&+mfGgn@4w&bk`I4pm-SbBL_4Ka+HG9f+42AX&gQcgcXg21kc2!upX$d2v zQye=s3{nzn_W@CN2OBr8;NbCbs&T-EHERh&$&o|DOpP^A79u}HET!Pg^{WVS%aJ1| z=Z~jIS=QG{---$fFg7J1r=z=NSmWg zL3h^?b{~gx1{KXihxu+C&>cY9sx!b zFB#-rANy_2e&_&4W)*99Y~`}mA$x1ja^q+B5%?%EaN!%-b^Ts$J=7pt{ybj3xr_Yp z1N_Z>Au`mMTYtnqUGZk#e%YJ2r*k(yJepBkwSiyWv4rNnpYWc018lL6$EP=Q)w!?W z-oM(ULwh;3{sIQhc?~b?J-~3?67;NO-KrQnd5|MfL=32A zMhoa!eHA<6X=aZeV#WtN830OSr6xxqWRBCc(kSWFPo+`>ek91$s*F7N2nQCwfOR`w z$8{?Y@$89N(x8)7t5>t62D68D^THS~lwS!Odg{xo5eT%lTal;12#>X6aG)oATLg|1wj+vX8Vrp`d&Ym95+_aGs zCyp~RI*QU&a#PT1wXnt!H_O1IL+!Nkj6wQ=bgdQ5RX+a0K9T z*3lIRnnu!Ku2Cm92BF<^0+y94RDYmn{5w!S@CK1ke{{M8O>6%?PO@lr$vi9NW)WMHDS&e5OuX&p2yy51UpAetg#+ zmR1Fz=@{rD9-U=bU&00FZ{Wo7X|lB7iWjWl(B2Uqe*7?tVpl45uk4|k7`g(@roka{ zp`2sYC*5nv>eD4Q*=NN2R-RptWX?ETDES0mj^4bj{ z+T@&g>Q4UXeRpy==s<}OX!4Qw|0knweF<;haV~$bQ<5ij_C0tDZ~M${_Uj7B{k-u# zxA4VxUd+{7xAN9AGbT>#<%U}#u6XfAx|VJsdioeL+r!QORq&!q&SKTttt^#b^A@us zPx9b{Pa~>TD%KK=?q%Pp9?o2{md$;2j?EtD>AIiY^B`{^AaD&gq?E)_fVIxvFVY&N zCDOQTGfgMC@0Qyb-Ej_^SFL925(y?JZA@_R;h(YlXhKx0k`*~J3Gqw%9`~n z=wGsw!aBNentO3f<^FCQXtF#bkRi=xlUl9D?DQ;A95PpLP_0I!X-cIMljTj~O2y?I zQZbk0ZkRplWXV7W#$=eH#oW{cr-o0^N?M4#6mb*;VMvxHZN*!c&sb{*2M1l^aM7PI zIoF_2k<(|A$^n>obpxTWg{3DDT=k-EZoFj|fAd?v#_zps8>Vn7m_i7Ya29Kb97-(B z7+NMJ#3E!opVi@3j5Z8LpG9yW* z_|+>nk>v^BzvCz|mR4(yH(axwyMMZ$?yiV)HZ9>BH$8|5Vy?O7A|CqLLG~RQp^%!s zO29RjZRO^h9;AEeGA=oh{>jT*~Mq_@BUyHjRMxLS;~cHZ{a_`e=je&bR7rw9^uKor$7kK+p(7JMg83S z=wVc6H;HvR@6uZ5*@pvIv7nT}ijYDD2veYKjtC;8gg71N+yTMP!3q^+=49o zf!2yRt~$}k!ttbZ;M{{24)11JMxN&=DG8&zE9!ZebC%u9k-;s9$5rpSr4 zFQtSaHwCkEP0~E0FgZz*QKUIw>8!@YQHYL0io#_Tl_+3zr+&1L~2U~u(% zq>hkM6IZ*4qHd>YCZLt(7z8qi$aBYcOVZSJMJXI&V4Np_wU#tb5I_`%ZBRdsoT7yB zgZp7vl6@^vAQ84eNsz+OYStMUIYpK}78HsA;l^`tc#ET46cjiYFB%190#Ye7&Ws#a+k#fjrB29_?NX)XIt zjFajtXThw~jkS7@@$Lnm2p}PWRcACu_7SY``K&4_> z+}lYrnj+l zRVxI68xl@(hcQK=CeQ)0QX!BQH-I5gD6j=-(nKrG_N`m#>+Yl@Ry_68W3=ki^!G2J zr?;Qs;bGD&BaEsnTQNvaPd8x{p|qsCyNe`AsdjZ@a>LwQosQ0`=U%$f&#AyVtuQG{ z&q+(3XWl5oU<{tU?z)1d7^hOw@#eH93`06QYVLRo&|ySJP~psN16U(zB?e1CVKs$u zVuOW&xn_pafy0+o;C&?wK^Tx_xuawlL$#wuqtPI)R>;zfj*bqhR57-o)oePoD_an# z0E{7wL-Ha=M{=BaR&(N1jtRO@s)Il_$+SR( zF)c!DrHe$mp>r83qA(=Lrn%^XZ4^RsYJ7^u>?i|$E74LA>JY0H8J%D>S{ouMsD&{V z9Uw?Sc4K73Xk9aM(phCFmDWs$M1OkjS9{g86Q!<{} zJ>RT|0%y!BrSpW$au>kj(099VP>__8xDryU)iAk4l2K%i)(}WVmL{~CEdmWaJ)JCG z+|Sg+2>pG%tiSSdwrt(O%=8?E6|5XuLr2#PaV4U&vlDP008YEj2~+m=^|55}QjB$3 zWVKqQNON*uHcBDL(gdYrgmGH)bM-l=F~MvH1KW@gS&P>d}ID=}#^rBaD#<&IpOc+(RtEz4JR zQmb_`K03_Q)C6go{Cof_RU7cF_BN32lOT&L4>Kz`eqxUEcW&Z8Z+MK)-FOeLd;SJi zE$+q?3v|@~ht1;fwZupk1(v-ZdjSSXh9D?SKj1W&>;JV)HxkbNqld78A`=CK7F6zJ ztz|(JX}Y^2TFI27RAdd7EUB>j$#KHIUbn(ZMbfnN_w*5RlzQ4i8xXB&R`jmofdeOr zd%9UvmB_S-GKRE1&Dyog$!(pPq=68EJ0CetZBZ}vhCxc`h(i(?&@cicHKBF(?g0w2 z7N$r@@_><(6P$a-YHD2pckCJ_s4T?@=|mvOC@pA(;%xwZw!mc@Uzbh*Vfo9WgSSQ5OM^JUzjQdXpj!A<5B|7*VN_ z+mco9R9mI=`t-(<`+GxpuSqK;nJox~M2LdUN|5MUAx&=55npoaE&5ETcKj1 zxTO+pX&v`Do~Wyof1mPQKWAj?qJ@>F%Xkwd&<#GK#z)id>0x z^5jX!nNpf&qv@IsQn-O}Egg2JB+4vsGRktNmt~C$emJsiquKP%O73}e&y4qK^_|T; zFF?9%uCO6lZb{REByk00Ogx8*T2D~w?R)Pu?jb;lXx3J_z;SEy+ zl}eQ~%?QJgiHUKdC?bwSD%BW)VDXY}=H_My!jML@h1P<(xj8y&RkADxA*t6>WE{~- z-96Jx3*t~f4jtWn^eyVAUZ3UY(ZfF;&xtiS|4+_P(#*IwDp zb-%okhaWl4`@eDr-+1q}%5SvYCb;1FLo|Y%J%^{cXlN~stci#^n68H$KRLx!FC5~o z`;IY}8ZLU#T5{9DzLS!zeH{!AF5!jew%D_Oj=`aBHm~d9hxbg-%354?#d^*=ui)^J zQP!;Qqp!b*M|VAqh%}jsDO65DfGHx32^d&f<5U_@WD$?;9p-IsIFI`uJHk}c5>*tL z6<8ghvx2~6^!L=b;)3lwxceY_QH2Z6S7xl(UULyY{L$kSLa}z|5J!&BaAKs1js&@*t5X<(vC3V*o)M1{Z@bTP}aE=g?a?%~%GNkJeDxpfZJLMbGQ+~(~P@&C0gv`s73&J|FJ zEYgC~!tte~BF8)0C;&&v2(@$oz19dVP+F3uDS^_SsETL9Tcot^zVx&O=_S^StWI-o z7KtS{Fnn^9W!;^qq{a03IM42VhH9mgnVCA|8FLe3OioNNuzV>|MPr4a-b|UAse^KS zsoDArGcz-E_tXf3fV{|vqR0`8ltyW%1X~hat+h@V(YVE5 znqp?EmniH;gds^L$*k)lW~pFwbc{y50TSYB6CpyBtPsRi8fi{kt)K&iRF*KRl4sV9 z4y7q!tZ6ix)H*vz(u|H;jUvzK?&_dES0@Ssnyr-FNYXr|x6``DAc83L^UAg$&vBAM zm6*(=D3dyI$im@eN`?MCAq``x^$f7C<}BQP-qb@nITyS}xm$dVHwbVSSq7FYukr2M zp5mM{2RP@2+evBgjh`LlwL4Zj62$)ocyBWyoZPP)C{+m0wiUwsPoL1<{(s8eEXK0? zzVrM1x3k=}_FmY{=F$|&7Ab1AwON)STN5Xfu^lJDAc&t5BhLXc!2ki0_#v5x1VMs9 zfCPC-GPVSJJmbh7TVqM2WQo*5Q53f(yUE_Ws=B)Ny35)B|9>9-=iaI&DUas@w{P`b z>Yh61{D0@Se3$?Gdsp~>zkd~_6onpceC6+bf~;)VJ+d5) z?-NB4RtD`Yhiusrvtug)A>Qj&FTOQ@kwO2;*oxJKK9LSmMb5XzCat1w@KX%Rnpzwy zY@Q5Ov+{A~dMyR5>T2-K^j;#`pH(Lbze^oE7b(G<9tQ#?G{Pv1(lp+-{UhBIucD)Y( z-#{mpXdQtUC>2o^7A0ePy=Bs5NMi#u$~nWq(UfAEv%hyllE%c5p~xmcM3M-M3H`02 z$T8NiySq=XJ4Blfaj!#T!!~+psT)gdLS{Ya_sFJG(j;LrosuM7T;qsM!ri;;4EueA zfc~J55T5>^OIemEWhnEKZofyKWh6;LQDme^93UBKf-P!#os^<#=BB+LH1(kMkE2y_ z2>T_R1EFIIlz5d=h=d=!allKL?_!MNkN^BC(Ler=`K`}B{&$Ny$8eSwTG1+csu@E3 z@7BQo!|z_;b%W7@%sO6tQ=B-@{Z?H{5r?ZNblDBWxymMjWjHWWYjgnIKqJ5Fih~en9WK^Nn}C+Lp(+r}lrB6~UeHN9 z^g52c-93~xbUHmQJksIfQwVp=-lHhEuF&) zLta)K9F57U5tDJSH>_PNCP~oIkK?dEs%nZh9i$1BQCSoeMa|;kDs@!{QoV+Sr2*5b zAW4(3ZALK|4sbS9Z2S9%#A%m76me?xG&?)nXswxMIcuvc93D&<^!pTLPLd?lMNOwO zpeS>?-63U>(dl%ltBNGn6lF;#O|bUExR9dldCg>JWIN~D2sDFmjs3SuGD z@QLJi|L5=WXa6|jAAIKA-zoUaZ-I2#;#E%|QvVINAH02^fAoj1a!?4of<`E$(g8KE zpb0H#8Yl6_pt{SDmRO?@X>0A|G$uBnQgEShYJG%C6}GCW8j0#g6jtC$fmac9B)+qT zj87wVMWaE`Dux<|NIg{*n%7Dx%GwfjQoIw0cB0oP4N;Fsb}$;cvE%cfev~UWCzPTS zGKO}j5^5ohFfl4M=-wh$bx=CN`X zJR!IwF;*y?vqS@hZCtL408vuq2~XxR>8bldMFxGMP?tpv8I7<8d4n>L{j$5FS) za;;TM2|Ctw`o$So+q5T46=%9p0`MyI-DoAK5dzZ!9B0nwGb7xY_1cU|6{Lwz1j$+N z&58NMZze7fL{faKuN8QRaTGHgYW5Efh@yy#Pdvfs=#banc!TxZ>qsw2k`8z8+~v&q zvz$45hDLx@5qVkTrN&x^t!vP*x4*||G-5iP(ChW+cDhU^v0v8{DlB{;@?2gIuhW*0=w4$nm##|hyftJ3qa((XDRot`u&@YT zuz#@6G%L98cNq?cq=`dH!_m=%IF2dGF-e-zG#;Z9n#!WJ3FW_qg0fY$(jNk3ow>}+ zn)nasg0+gR-eY9wg9OP}1v0{Vi#D3y`JbNWzx$6q&VTzKe*A9@KC@Zm9ECsA#GRkS z{#erILvH`{uixRH{MqY_8XG`=?e;tA@YaHigRPbjC=;=Cv zP;I;t2(4Qs1Vb$vB4zl(7eB?;`Z_LR1iWN!ds zsD;Joh}xEvzQAdP_YG2nebKmCzt|x| zquI79y++UMwgP)ZsrFoM|3;~1Dh8r836X))C1qPe3N)>KTI&@#$4m<_O5t5grnZha zPT1Morz|U$Ivv(G?qXfTxwEGkA5HNsv?H75AXV!CZ+Q2{O`5i^+*lXrYgLW2ma}Ki z29;C@*f?!4B1{k)7X|^epj}iuT5%3=#70qT$?D27zx2zWV|n!<-g)mj<7tI9JxtO? zMIDN=#Ck!Q7sN_{RybedTutqRS7j81b(5wY_V#wjrW0mUlTN3@?(Q~Kl~a^CAARmw zbW7WUV0+d`!DKpNd1;ZVtS}~`EKAa~OTP}5ZrOB-mIjGpX?Y1}bFyiP)QY;C5+{a* zg&}pF2YGWBj%ij_LC^n0bects6G5xZ!o-P;taYjp%7StsP)LW97AtC`7C2!+)cnDp zzRa)x5C4k8ygZJD@4L_G5AEZzCDUvIb^Lhpewfw#XaCm^`A1*>G5eE4>T1f&kiuKV z%n91hueM;~gg4*YWn*uOFew&+m4Fsl>2X-3)WOBZDumZ)onlmi5f)WvU>khWA2AGx zWtd7y6DT=8d|#+cbZ~uArv1N|OLNom5NA>+4moFg2@&vqiFB;>4E-of_<+Fc6SDws z5kk%bhni<&t;W2PZBUzKX1+Z)LLxY`N)xoQ(QS~LWn42EXsIM}79f>sE&oK&D{E`7 z0JR7Rbt#SwBlJAr3X(V`i4(L|G*!WjkLa9dGRpYrE3abWh*M|I@Z85g&hpAK)>?Xl z9-sWgCwStCC-6YrNqG1Ab*^5!PSWWId{nFI5b#o-g@px*JjdFmRcL7c4lRk}xFxg) zAxGC5zdGkIIvBz(Eidw=FMWyCl@;#azsF=e#+Zm(cWyHpPcZGm*E&W?jdel&v@8m& z3&Ry9gPT)iBH|<=N&+z1TT4~s^m`qgZD{J6y`3H2y>cb!i8;%3IwmhN1TdY9$cq9c z6^Hu=7;SK_AxYCfCsdmC^$oH-rzlFK)J!Kiw()G<+hlw+W^Z>NDGXIxS|SW-+M}-Q z2Lsq#P2qu{@n8@O^Cm+>Pm%s2hT2_HpA~o8ZRyBb3${n=0txiItUe$P};mW7L zN`aFRwN=Q}5v7K@h9WP5W_eNb*cr*kF2&TP#i|Zo2&}Jg!cbd*vL(_7JrhAtBAp?Q zB_b@mu$O~EhR`T4&~0R^g`n^;E?LIP6hVz6ltRAsy$qR-#v6?l21`p`_XOTof|%tz z;EJ&DwF#MDn$Aeyq2(ZzI-#H|<{pW%Rd&@%(o`k+G($^?YaDgeFj!dNTi*wFMKe7$=Q`vwt84IQ(H0PE((wuOB&Q2kQk*gB1O~^<=c-*g;6PS)I-Z2 z|J%3TW%0lG=lsFHc#GS+(|_y0_4=Jd{>MLmi(mVL@9=+o`x<3w(Y3`lfgL$^>7DLCs?~9?PPM^IhEi6_cBtZlomy2_{Mk3Y!JYNHB;5|3evc$g(2>C;5e~tPn>YE+ z3okI9WLO_0u#MJqJ6)6%p*I;)G6aOiJ;(ZOLd*mNLguP<2-35C=d9(?M;>Q+X%%Oo zsw_oO((Cnb)*+mu$R_OX-lr<2_@*LF!hVb6m`ubYzI*m~-bI;;pydWM}t2X(!_BnKhP| zhd9@8_wF4w*6)zEc5mHImpG0Yk0O-e~;~*Jq`{g)U`*551B$TGaz_>28L@x zU8|cVf&?Jt2shdTBu*J3mEs#uo$aFq)ZXD`N|biV^OFDmk6z-ReCf5r95(K$fT&)J<2#L9JlWu@#f8Y{OJ$hfmu~GOUr)LV@edh>S?Glwc zeD>MT^P?Ybuz9qN_NNh5jmx$n7F1P&9CR_-1iX+5nNX;wBq$5E^%wB2^-&CgObFLz zJgyBW0b?YE4Vj(PNUPftuigC;5UtHrn_0+qD&_@vA4CTm+XQPlq4Cu1G1MSxtZ0v? z_bnX3&oeM-D^xW`)syghZH2TY!j(unLp?Vr-ymEWO0cHDd4=>2(PW`yw;mf+eCxVI z+8nJEMP-TOm?#QPPg)yHOLGB8(-eRtNl4SQ?Y*S)*JeL2Ed}h);^HD{ny|RENI;;+ z51428z}n*&X-L4qow#|x>i|-fA~aeh5^rS4RcBHzQUoin?L{@QBymzD(6L2q~#*i${@myGSX}I+|ypS{s_G zK`KFG8)mxpq0^$Utqz-OO=E1hMJRSkLa^9;?f1Xkj><9)X8W9FxR` zgM(cpiigggWom1*7Qvy(TMiD#?Cy;iEF>ryvctU0@equG>#8li19#OZg{>N@EJKSx z8lPqvRTZS9mseI89gev8k&9e?_cA~J@k@O1SH8&Ok3Pmnp1jEY?JY*51Kxe_Dvv$( z2;EMCcb4IB!20@K_Vy3B`1oTO9kac&O+Ky2rWM*uczCJ%VRAaNEA$M(JS!_^k04}* z$`5(&!Wz#$)yJELyGM#2{CFMX9KZSNml*Z~IPUhk=9O1BQPT10=LY1XjHfRxaiB*0 zug|~5PhY;nFMZ+>e*3d$7>y5j`Q{;S+-x}2xAfzL=RP@PDW4`yJ5ke&3J%eF~$Ikb;{Q5eHSs>MpbLZf# zYg3d+IK3)JQblbQspzxX?{INVVm^D0rIik{m|(o*OP~5Ek3QDLlkn3w?z5XWIMGL_ zfRLV#`lW4gI_;!Pv~Jf@AOi&fPoT<&XG5{E*ka!ueL6SgTMzor!^ZdC* zT}zLn!Olu7Y$z$EXpM10CLK-IiKZLGlTCyz(A5NK%fB6dJnK`=rg{&IU;uAJICKuF zC3WeMuEDGDj;gBKiK4*SfTL1MfADKWn5H##(;_2|HLqMNB|Nj+3a|;unKNhT_j)L; zSY2HuNfH*9mk?Tz#z`Q7Yt#0LB(VvW^~)r!79xOh(w^-DA8(gDcL6R0$11E z-?~pz*KHYHW1V8q>oe#|$};2D?Heo)2PmVcUBhHLAuCHP1Qk;PNxjqQp^XZdr!*$d zb4KG4LI%XYRNx6%HDy{^bP=rDT&q{+!pVSAisj`~C~2r`k2Z!puUS}FW}1~$Wfgdm z-qJ~8R@Y8*{kjBWOwI2dwbiguB=iP zC5ee>(qN$6R1L0nD5+bQsL)%B(}cJz@!s;$OHc8_w_o7x*WO@daf#KH70#Smvzqr z)W9rbXvei$DBLvXQzx`Xk#2^0A-{4(Jq7^;g@YOGVl+E>RetzSS z!9!~h#fU1wVaT%ypZUlF`!_82cK7($r3JqFg@@SKe4WwskY}HHjvIGh=X4}6-2tz^ zvCflEcX(%WkIT2FTw1L7)z4nyU;bc=zk2B|Pk(fgFMs(0|Kcxxj!6d42vD-+Z?=n$ zR_niQK!@gUaD9fE40C`72*8U3S&l<+5Fw~3rEx&x+v%JFV4~Ekqh$!ZnThjyt|Nj0yySuy8b;Db4U8dXZ^2~G3;+>satK~(G z$FsV+%5<6`1pMZ2{yUsnJw-k(Njg2GX*1|HSj?^xLV=Nn?d=`5HttbbC|yln<(O2G z^ar3Fsc;PADA0vmka>>Nl%3IpNnTJ|fz*aBj&3B#r$=;qDJIfPCr4bndV|L=UO>wT zY=aTOBw4DUHem@iWK~n+M3CF@7I1>4#WjY*F5_uQ-2@(^jyhxqV|Morkt$4y7Y03) zfV#@LdE*MtKKoHdlL>iIVo@9(jzPt&Z*5{aJr)NG6yq_IgB_ZB#AK?do07c9k=}B6 zu#3auwWP2$LKuWdD9WG$E48B2P4V7w;ju?~==5psymyUvSJ(LLmwttF=gx8Ejmu09 zkJ!As&d1N3MTj~~ERz&xEeHF1bh{nSKYWhs*RQj*G-S{VJ_sK!XgE*D+mqN!+A}gV z`jUu`f9g^G*`Ix%?W{)=r)=Ke@3T`{j2>Wofz*;|o|BI>Pd<8{ zjeA!)e`=ZObi%`@mbv=gCQC!d-@I6J;i*1(U9+<{W;B7Vt&HvMoR6)iw9LkVA~i9N8l*$CJhl0Hm9yR0!Xjp`v~UD5Be%CIAZ^vyzAI?b zhsrO2MFX(7)yEYAT1_bDXC?pa+f^GD9P#8HOE4c{Ws?wwy{j66QophI^FrUdGC4movZx* z@Bimqym%4oEP0k;y(NuYfPNr5Uia#&EDaJM=m@J?`8oaQFaMk{YEwN(EI3jKF!66c--3z{ZVRT)*}nk3an+ zOH0f2yIqcU_gKGkmx~|0M8CVhXf#GCMI49h^zh(-<<(WX-5$HUyIi_-325FAqxf*> z#H=SKq@rmW&Yn7jR5AN?1N{NPv{mqtN6)f-Zy!ttk!V!UP}DJ1UNT%TjEahlsYkAy zhIAQAk2nUpHV|*4MTi&CX~LbYZFce_(go0_W^2dO>vizb5~s^--#g&^>X1~*FfnAv z3qQQhum1W+`49fVv-FiGasneAQWkV#!|j{5Sy_^tT^Z8t^!VAEcR6?Z3=glRh^AtE zZIoW<r}?%Tzv5Ey`P&rq-h7O zRd9KpP3+oi^lM-HI@2s8O**Wuo#OnthZ!y`^3d6bSzA3#Rn|mNLK4SBkwHgcfMBEw z;)Oz!L@|-n*t+4`^_#>=hoY!R(hdv5MUphAkLE>*(wa2w5=9ZJ&HN4z_Q}R$%BmoV z3{hl=jHc5zs`vNz15w+0j>Z#4<0<1wLDKDk)HF8i2V*4O+jc4%L>2JClx}g1$CFJa?C$KKwPs;)F+e1YLF<^Nb{vf+BuR?Vaj-ws5dz7|$|`A+&XrKh zx+0Du27>|4TH+)L;9*>l9a4%c%P7lWN!ZNn={#s{f}NhwoI7`(#g%3D_7Ayz>o&b! zkHy6$;v{8sG~)ift@&gcn9C_mrc;WdU}eMu8V}O+unP+E=8egF&IA2p`2XG6fNblf;FSUPTHiEs_Q;1WE=# zqHjD(1R*pnJ7MBxf-G)Xl{CJ>83~<~n_DG+{HL$bjSTpLmZ0#KK&W(n_u;kLkh|TpW7EMJkHwXhnL9D^38Ye1j98;oOA+{JJ!TTy~gS0J3 zX$CiGdtPndYgU%eJqc+q67smDM9SlZKmTm|x>U!{ow(0}8MHp0QU&KDaV&|{+xjWO zRu6;$@xD8}KXlDPrZ^5zZFVkO)sk7uLCi~K0+XTrh6gjY<5F=}QlHGej!W%XU~Iqt zLvVniJwHqo1$>rjLBzA|BJ}C(<7fzj0pFIbhx_}~O^FiFR2AJ$ zhbNx6NRq@H9*mJv5hn?C-Eif~Ro-~>GH<^1He2`if_$?M5Q%`BlHq8#`_8(c>antR znkY(;BFN=LIzkA^{@xzr=>(5sI2f?F5R5mfssCkGH#39T_exvUd6`(=6l0 zwd)A$SzBAf3#jUf_1m}cHsJH>x}hjaoO6^#5yTzS4uipv?d_cp2C%u18f_`kipL4r zE<8ZTF*nxNk*4P93+KrnORUQS z6$OXzQz8_qNl_}MsVBIjgI2=YU~B|ckAnlx(;w+_cyB~CI-)LidFHt%cyHr?%7E7b zr5r*!_Vz4a``U|il;@%I3rr~x!V}3pTSpxVJK|H%J;v>A&&E+n)U!PCGTK@8Okt+r?wU^T7f?-($olT@p4w*wF}Stb^$+_Va$Thyx%B9 zt98Y3U~1_roXk$<*r!>Bb^KW&gF)!*`Prj%6`j2+4+M%6@#%s4ENlBf7AB4Z&is|O zCn^Ykr+|=k*qRy8li8&6M5#CngdYf(4+OL05_^vMIvGgk0T1S8$j5tyS>P2y^72n! z=IHRSWdoRCS*A4IUXM5qWPfD>2y~9f_q6*n7#~+v!w+7339mG}ha)V4rPVb|8rTg^ z2&{*)cI0I+{&3bY8BeL38t*My3mR7is0T2ajPTwv7z~h7VST{--P_vX_T3GB@Y2iN zyuHb!s2NQ&CRs+F7a&5`g$pf&H0`mxdJ5}8sXZA_v5h6mChYF*ptWRSVSzYF5K@w7 zIeC_0j3Mo$RCPVqBr~l-M1MFWiW2T`-y=4PLBCI)XVhgGl$DDD=W5Ebpl&L(QgqTT zP2(uaGT`-eAjFHdn)BXcn;IQOoIM}>EjKnc+1lD-ZEZDxb8W-^&MuSjBuqJ_!Z&t) zK97!$$g(L*OG|C0_kJ?>ybPkfs<)kwRuy7~XR;o?`@Jjt)>ohA@iSK`;~1q+@vZN? z&DCr7`TgJf6mMR>jEwtSdh&6;^_{mlX!_W=j~CncssSw_j>u&XX=2`9U+1~ct}wO_ zVXb293?_=vNy@i>c$we*osaRK^gUaf2R!lkbCgG8UVC-S%K0?oeB$ZDPx`$K^w#^`dIZRtZ&exMXew>%& zCsyI{5okZ#Mw1ie`>fQPm1;Aq_!%Nx%8(&D=jRt4?>(LUD*^T(PJYKPm^Zf1&tmWF z?I(Yje^Q)yw%sNrA?>7LBI#QZ!g7N*X5PF-pe_7Zw?hkHVBS z>_vo%X}sX>y={hrK4;bzNRtSZ2m*v6OiZ11^!h2Cvn#i;)1WjF6#BoAi9H23DI(y38%aUH2(n(Ur(|x*~0sU^5rfSHi zBdo1RJ44c>gZGZnXiTp!F>#Hx4(BYolOnvQY66~dVR?nY;sQHc_u06!&c!D$vaqzs z_VzY)T~p)*onDuwX-Ja$h?a$5*)Y)G0ENaQpf$ZZPEepWkC^zu?rFC#dU+KmMyX+1Rd$yJz|5e|?i_9YbWm zN#40zv$eH@SvbviU)y1~T1EHHapl?}_a-GSU89gO1SJf^sy9`ta0_u4&}WaOlN=>J(AS((kll{rXC?u zgh&C4r)hgx5^qD`m+#LgPWpwN$V@!$INP;u9`J(rf@fxMH_z(kB~#!hDy2bG?XnG^ z%V@lTcweyku=aY}!TPYU_93^E+aGXlc!!oABPBlQF9#55o3+gnuVZfO2OIc8%=XcP z!RZ6vE=~ruu-)o?@Ab34QwXkKzs7I;#%~0`rwb*G6fKBW1idqDg8zf_j>bB=os=j^ zdE@e%eD{U#a(nY0lfx;_OR{Ok!)s^g4i~xh-g`WE>1mo`%KpxM4kuFvQP}&!L$BK* zw-#GBpfySgvTTYJl2fNnQI{2yX+~ok8W&VIoKRS=P%6O*LvAI~iNF!`VKQy&8ZRWn z#buHt#d*o-V2pJklRP>+0x_dy1z5y*G@`Z*l@&N2yjYb66UTJB9h$mgQXF#n>_V_Z ztE*PS-jd}Rb=@GPpwsQLySqbK7Dx}q1kUj+8J=Be8|%okj7}008I5Z^LJ87-m&K)J z_V4d<^V&6@dio=*tgW%Tw?kbN;?<-pS_o3-@c2IHNwP*{*b(`*xYHb zacc}~5{|NxsTZiELqo)?Z%sgWWE?XYS>m`Gu%^j?BWro_XA@9kgcPWB4XZR>)?D9r zbUTl7eRs_ZSgkUir*=WuezN z>y5Rj_*QnA6IG>ek@X??1v*X0{MzgciOF{#Sk%8L6!{a6VxFbF|6LDeII|zaBo*o+ z`r&#jHsCrSM?S!r?nM2P1nHcZT(6Y$=9?*>6d zDQFsxkSf3mqzvS5>kuN)jI0P2WCsU(y!!fUTz>O4va;ap`SaY9yIj9JgaFi8Xxpf<-G}mw4WN-VB3y(ZP zRWO+j&WWyEiLwFO69vW9{Q=F$a4&V;xyF{&#LW4#d6_d93>k0lQ`Z%T2ZvN;L97hIBp9PHTGL5W z78VBVZtXA{9fEgsyWK$6E=s0Zj)@YyAGBF?I3EM;N#nf7#0g8wD{PvZ?Coqb9#2?V zTgF`181)xXUSO396p30QBY{>Why-Q&6gCgk50_HQ2J3uC>LNo#Ohttvhh7rAKx~7F zJi*U4P;P{d=noSra)eO0LZZE+(KCD?JZy%OYX-YGVnQ0Bv?Rndsqar>65>2Rw8<;JVVVgP&`3B;yCckWA#Za*@;Ltn_bS^ekZ>6 zWWbwk>q*du_rG}ZnPnMSHl^3=2X1A%--6Obc#mw$Z>A=M_~|kmn(Ib$eZe3;ffvsi~Vl+IAkArk+!il1_}klXg1n?Cp@1 z8F6<=RTdl`9L$5*{@yNCU0~}9>lzjohjcm}_76sYq;ZZs&*_vM5Q3tt=ykhzYq3Jo z>Ge2s<}|muUH13)xVN>z!s-f1lu(PD$z+NUif-EFXnaJ|G&t|EO@niuX*Q+X>q6iI zJ$OdWrdso>ypV_%2H=GV^cEsK8CF+#DKW}oX>ihDrKGN=fqo$*O%q&*m2gA?6ji%` zYoNkAk0uEl(v*0i(K-kkdIu32*#w9HjmKz%kcw0(`ohx_24zdUo1(nOps~ImPH0sJ z;HS_eQBWeqi+~y?=z|kgloWU=iJ}-(jWhzOEkYI)-jU-$2j?WMEtsIZQ3_9m#Zx1E z89%2p}d+=b)=MByY?R6fARYq z93C*5Ot|pqW8B-`;q7bJP*F^Oahd(2Bdm9H`yGah3oNay@XT}1@k^ikJe^*T$uuLc zN)C=D+_%FXsit)k4gnSGo>l&ilVY)Rl~Gw zXb{vs1i3g)N#c~IvD8&bUKD_2@8BS0JI)d%CdflIHDz6su^!4 zy``)wgpdpt7U&HI)K$gC<|a!^i!3YzGJIW^;2mk2l4m(tmZ4?vDDZgltoQ|L6m7{8 zu9^}hHF8$=w6(eP9$ja|zQETRHXCD)j8OheSu|8OqYyDuXQ-{mOGRZ2wE;PrqQ(XJ zWI{C_5srDl%qZtD0=z9rEJQ7RM|g|zHCmTAUt?W_@(EHJDygWWU;!p=j1&#ZRCqDQ zxg2eSqDHAwoG=JcQ|MMpz71wxM0l^z&SSMkMG3vA1HKN%qqcfq^l@!qkU>3Fcp}|S zgl8d4ydQPdo{;mvaWZ(cSvn5aR0wD1yu#42n@wS7nbrw*!Ut+d@xa4}M6CxtcXCsF z+jp6L?|kk%9~KDK*EjKAwmN1YrEaI}5-9`DYJL40FTebK%4&ocHH#|?>>nKPqnBS{ z?esYs8POT`$?J?$r-wZCdGQMu`O&&5>7386fF=Uf5S_)iMlaHqqlPpMr3x$j$WE#;_HB_D? z?UO7mAY;wp{w@;FaA|?YLs4aTVObasFj8a70%vQ43`m2#teEBn@L^NP85U_?PlP71 zZ$X+KL8LuRw#!$(aEWIg>l4>G>yuUfH9wR{(BmUkePxG-ShPY{sP!X4}U*ktV z-=ok&Y+Pf7q6zsjN;zl>PAx=y;^R;8{PQ>QTH&?9VNpnoZBSN_Ai!8EYpHF(f|afe zr10X9fA?c&x%70O{iehi!~L=5`JeCNtVGH#R(dK?puEIdiLf2Kh_M1HU!kHX`1I-w zC0+F~ikw6Hn*Pudb?7brK9^opK5I7P_SA(rls=-?kWU||G)uE{nbcTJD&#{fe zRM|Xm%;mtnn+F~xU~ypB*{_eONhj*a59VOA;X(Uq3zLv|aCQ!-zy$!~OsH^%={i~b z9iMYz-qQ;0i<98i_XoP;qP0~B3t9Auv8g}tEhj&jW%>MEp5eu2rFzgPtGRsnO?G#8 z7*EH+v#=`p*(T2#T^GpH3Mrte_CoWyyFv z4*Gz-G)NpphCI)3wIxXshKox?Ny6d5K2=rm$YYQ4%1>Tl|8Soyn~ZaRwa{Z1`OYa1DoN#T9mi*94l|OrGe0jys&)rbIAxc#sBPs;761Y;~#tv7t@-w2Ma9NnXOhVQmeN0tCUIw#HqZM^A z;ggT8QXOXe&G+Bo?aLed`llY{?|=T|_{M>D*k(*UE%4T&L`3akre1M>FUOl0YipGE zP*>E`1G?l4RYQ5S#pj>t^3cE`^9iw#L5xNLuHdPsR@vVj^WsbI@#CNF^3K&Q8XG`+ z2uD_BfWj$(HHvZJs0xqw4N7QK6zl|R=>0Kd7JWiI^Pd0npZ+gAeE$3iSi^~))U1~$kAu^L+0=&xtH14bqP#rW zL-Qv$PdxCL$Jxxqt6I)9IA)cuZYX>}+o%5Iptt(T7S1mj&H!%F^NjX%tcBS-?}}C3Rh) zr6fv{UNg50->bk+S#vZ=anFB)qOGxS_V9$~k9UmnTQ5=Qxt+9;8Bg(Rx zmw`!imuHa@I1LOpr=2olZG8*e8k%Wm%F<3p$-HNt$qf`#wdHG0igavZ6m2 zvM^YntSZW?BAbq>n=0@(>oWAMtfQ$Lx}7c{$cmgePFP%6L`q3fR2&{1a%$}~Nu08O zcu1b-4Eh7&Bn?U#buc1Mk{DxVo&X=v18V`6Etv24{GE}LTP1=f=Znvs=X-zkCf7F{ zx9U^8etW+i&uT}w;kX7`8r?w#=AWI+$zeC(UTD$KP~yf z#XcAQf6m@C$hPaM^Zf1M%y-J+4SLd(tjX4dEDOoTwy=$@!W5?3WhwwecLNdCO+`gF zABd=~Afkqd>W}@UyP_(HXjeszAWR7`1{#AcgYkrC*_x-P;pt78?`7tl&$NgBu+P1j z?@4x;Iv+A`=DqjabNAVM?X~`Et^Yp(KsW z7l_3L-g1NFZ8s`ZQ6lxO#oW{%lSBe< zZ7^2eb$k?#ERmhck63|K2t0b#cDRO-#1WY3D25egM(_|UAAb0QeC2Px#6SDz|C~X; z!ys{MZ|!I@;%Wo)1I*M_IMxv(x5nY#3=2E-(vBLp%a^Zo)h8hXtW*@#p*#pA2a^fA zS1z-d%{bT}Q!SS?RmEFwx{2-WZM+Ya>s3=T+8E+GVcZoKwRdn3D$(m29~HDJW^cYg z#1UDqAS-fCoIDOV@SgoEyJ#t}ZA%nIC?(gFLvb9F65Qfcofldu0{_1v%`%kI#7RO~){MuKz*ONvX+}|Gfs21SAx{&e z@a*sHVU1xh7;)o`H&K;KY)A9s5cG-xX_8V`O9UQg0yAq}mCPnVF3xvkiBc)zBxbn? zp=EzC=v2NN4)zbIn-zbVWjdRara4KHlBPLI2SE?hG~g|5vjpCtO4J#!RY|r##6d(i z*+b3Il1o=++;Pt-{_5FX6g5$yXl#Ua4X2K6@k>AV6FA}7ICTeKe*AI1^o?Em#eiS@ z*xMP|C@_(}{}i8ixJn!oqs_mK+=y&hlt?pdO`=70F=q-i%qy*&g)x*A8mDyUfQw_8$K9s~5PmGvn0I@b35A$0z^f2_AaK2KU`_iZ6cRi;M?3g)xlB zC6QJP`dOGvTCrFL93d=X%htw#`J!1aXy7zxPT0 z&A<775FLTwRR-xA!*s|v`sQBP8$Gl`;C@x|u`2&q&C{dUzJ~xhcZclSp;myOl$zb0 zU8a*s_}N++zH_?%%ZVheQ66=^aNf=MZI3Uk62Eze6JG)4wP&&axDK!c! zpg$Utk8=ES&T=uQ5E>*zk)o|COxscna=cO$SwfNpwQ^@Ik=D$Np{#4%=8$S$0*=T* z(T{Lm(zJ%Us2v&V|M2}>*c~&imz?b9sJ7wOTLygdiHrQn=U$*~68_OI z{uu9m*SmQ1Q=j36^ zc=5$^{MSdmNt6xP*gC-{|Lj>Vync?MSnwPF_?I~T-OI$e;M8r`^IO05RamzCx8HUh58ScEv(KI5>`R)rzT-6WgEQQ4Y{C29bvOUvzkHG9>oeT`l8sTy z#vo!gtI4xI<4MJIyda8#V5`Kjxiz4wTB^n%RhOYXTJF%z4i8<}A8;ojJkq~Wzw;M< z;p2SdBR|8x{kQ*`&wcK(!_tUricsIoXuWA$(N)hMnXgwDuyGa6w#NV9%KjcG)%Ems ztgJ$zq{J)FbUx+W`E#5&ae``5QkE6hpFT}lS8Sg+#@^mO`v(VXZ*SlUR6a=(qjW@^ zX2fyKWIV&Ph9uI+IA(iez@k}D^ivkqgfxmtQN&79I~TYwokuH8;~h?j(D&#ZNQDE+ zYC)Ri7}HYL6;i-LNK9H#pf0o z_$b3k9T-eK;7hdfY;K-nuzf3|Q}-f@TbSD+Qwv{w;u)%J8=oKJ;)OBIe8K(qZ1Apk z-A0x`R7fg3Pd|By=>!&O!I`r!^XfC_dHq6(-rD4~%a%+vY(-=4zIl`V{W165v&}p2 zEfC9n-f`D)UU=?xZoRI=mt$_d=@{Sp<_o;#_%XaIx#89kPd>NLk3IMR-~8rN?A99G z0<>nnXh`D>-LZ+x%Mzp}1W%5wQAS(0%;ptzB!gEKF|5lHR%UEvIYJ|TTUBo`G620^ zkKg>wf5s<1@$dM_pZv+I&v{iid98u^VX?5oa~+1fR|l7?zshCV@$z^4_($e8z`LkWG2SztP8f~` z#IYhtBJOzWZ43rI`n`f`S)!2)dOajTU^h(@JQfuxk|d@omsDj%nkJ#Npo4Nu+ai@l zM=3fEOd4KIuirmkD87vy=t=Jqj0!x3o~_`2rv33XMm zxiMnCn6a2oF-=R}>(O7~Ty;fREkgTInz6BYjK!>EKAobqL@O0|h6R|WW;`CVn9Xr6 z7*cC(_-!l#$zU)*NzG!hq}S_(`{IMsl*BRCTC~>m`vW4SsOAgmYKiaID6Yvu2EsVM zN_l%9-0gLyC-h)hX;2nKw#9#Y>|`*CK*<%?Iax~0K_YPmQQw0S|bXh{1@(saPB_x~s&_C(@l9)G@OT!PaX-+TUm zzxv+uG`8aWdC&ItCdNx}F-A4i&LVP6Ny4#>EqtD0mB7U@^9G1BstS~MC{aRWu`&2A z<5@e4QU=>Jp*Yn_jMIGeTd(lP-#&}jI8LSogJQsn#~sn+;_(@9(wRCT;9Dv zJ()o@Lu-LUvM6W7c}%Gae7s;*mXt1|Z8AnS!U#xmO=ByzPF}}WK0;zCQp>lWyUgnc zhBWJQ=S>BhgArf*_TTW{haTXL8w-rryt=#OefJBu^dmTO#n+$lk5 z-Q@?_DDS(Dh9CMk5`w}Jvd6=PEVltWV@+&XX8}u2CMl6;KT4RW_yi?iU{8gbK& z*RgZuJjZUjfzfEd!TC#6WrY+$?WhL4ceK`_tRd41p+i?k)nP?hnlLYyc<=C1Pk^MeNJVcjBFp=jCNz0lXRx-#dqY)~;jytaZ3`ZBq%o~Q zDUA^hYui9$q&3sYWSwZhds@>XmBMyo+aL5Pih?VbcWJ7Uv}-(nLo3nBCHI|>hxc~9 zn>jD=!XsH=Tf@>R(yiO6ti)KJpU}v9~kk z5B}_F>~zeBK6IMfuZ!?PPytKjuu;LH?epR*d;HlSeix3PM*1dH0YqS9#o1lQljj84 z#&M#Jf>sMe49OrxFGdujj7d3TG&0PZIdz;-%9vT*&>BJ(h#uZbBGq948bRg0FiAx1 zp)?wFiuVpFJW-TkL=TT3N)*Xp3ppC0+ZoE%P+5cti#bjWANcX(eCCh8#q+OP;6qlKP(EN?XrEb>6|M1X zZI8ITw^%1})=^mJ-5kZK*2cmE&f=YY!*g$Ty!+kn;oa|k51;zfr+DO%M_4Y)BNY&b z^`xyRpvF zHZ2<)BVIoH8q?{Fx4!i*2K^pYy$l^2BCMAdC3)T>iXu$gQX50-9JcM$kyN0PX}e<1!v=nbLSvhjIL^rP9AQ1q zILfwUHk&b<%>toe9tZWJSfF%_cOE4*%SB1nlaytNHx=8Po1OMT4BlgG%XqwxsVb5@ zChzwU9_F(p#u%360xv=r&S+zZ77>&2ECednceGcM*>u8kxuk6^^n ze7Bl6&XC%gJ8nG5b}sSNgzHbI+Xx}H9$*0a`Yt(6|l7QlZ;#L zyp^B(nfDPj5z24Tk24Y@N%aQb_{MoY^y6>gmV0g{Py5_*^9{V`!8=j0MQ5RMxi>h$ zvF#ffZ1h;Pf-~oK`Kh0IC%wp#HZ6DG+~cm>Z{q1EULq1LzOi5gMWRW(LK%aSIf#rn zOYklS(PMLKn>f-WIwemEFkrQYJb^d^s}Pk#v@Ono%o3U?!)S$4F{u(n)NJ(xKmMK{ z<(?mT3)ZxtHCp$GY(vjXh=nIgGBkoAC4E_vrkZJ`Ie&4%|MU+YWUJ@s#g@D7xs|uP z?RKnhdFAW@?|IjKyncR8B}SazDR|!lxAN)>uh8rDc;e|7xc`A4;l|?{-!@2Z>Gx8W zWr<(mKLkj?3qWi3rWM9Zwzqph700i_xT{0QL(6p-t9fg?QjH(}_}Irj#-oou%CG&} z|9bSK-xt6?(DkKV6_j2TLLO!&1;GOgWsc#EQi($nNrIs~cKkT6z5Y6_b!=^J zvs^5&*7EGL&vER;39h^DI9ZlMLqxt&U8f5H`e8qUJLmxXp9h zPu<6SmXT!#eC{hR@#6Vi;;j=rd8I_@6w%Bf@toN)Orl%(gTH#2|M8bT#7%eJ!D4Zl z&wuq9=8J@h4kZe;E67sEnX?!9lgA_<|M-LK?WOec2``?xM2zIcor?3*mI_Oa!zqY| zn#aC&mY;a<_5A8DK7g4?;$q4F_mvlTZfBq2MvoVFB{R|E`71M~Ist-Lbha5W+i{HY z4Zi)P;R7GMk&`zJ_`+YmNTyP>sBuNa(^m{<7ap%`BDnw|Svq+3@`8yiNB}i&_}bSF z_{c{erdnvOTz-|``RvmO5BvK|7HLYF^boP;av70bwn$Y6H5em!{z66EJI$vady>EZ zQ}5s({qj#Soqe}gkSmOuN- zB|iRl?&2@Ltguh==0&TO`0ZP9cdf~y6IN2Se8^(OB5v-*HAY#d4EWj7wE?5L_s+qArKF?ygABvPs#9(xSythqh z9E%&6mtTDurxSD%v%7PdBui1QqOyiR_@gH|Hhh`Q zBIm+h!$LIpWW<#N%jdteL)JUSryqMBoe$Bm#u>p&7b@yAd-VE!UV8n2D}VAV)`E&s zoR>sNMo-23`Cq@a` zIj_Aq$IF&DAK^sHg#*XA%NI#{2?EJ}S@Y*#co7keXfZtUM^A9`@pGg}!o~eLt#BlH z!K4v9`WG)Dy&~3)(*YZ*G)bwC$EUKLITBNps%zP=l=A~-^9iP@ z&~b`$g3-n{S&=iFO<61#A<7VfI7x|Pu#Lo9Lt`tdvZSeMln@L@1CV|V&f`M?ZW_nT zXEV08Pmm-rv)PR4bV8n{fkn1$Nwp>~3eqfNQhpyo!=u&sLP~_|3K9V!1=a~_HN^J{ zE*r)d*9WAk-X&q4<(>jGGM#!KK=#W%WAbKf# zZNu(vL)t$@Yb~ve5mAcqlG+h4LM%}lV^Kju41pC5My3cL9SUCEozd$7NsbeWxfLK} z5Y6@=;y7?MiMUfpPpBOv#fX`SFtra{lqzCHi?oiZuCh5{!7D8f`wBUdiCk51cdMp-yd(q=Voa?X^{ObCT704#mbl)pucT`WHs%x@5X|0{izdyrY6l1Ui00@zr%CSzre{8CxZ}4C(P?SY;A7`FTHBm><>5? z&)MHQAkTBG7l@uBNi*uU4VC>a$e}fLL!76mEJ15c+q8HskxmjvF-;v3CRvu_@oOb; z9mi-DIOVLdEEWr#kevuGWLZJe1h7`>7~3pq8$(r9xp)SQ{X*~#`Kx?d*NG!1+q|Q}F zrXuj>2;N@YrLI zy}^JT_DOcX2}z_QmDRAmxF?pzY$|EX$cqW~d~hNMn5G^`>!5k>x~Dgx7}J zIwsQz2L}_Zbrf+NN-vzCR}@U<6?Glvvv+~zB1wCsnL$S>aTHNkEwja(@xcV8f|$vm zNI4jfnM|g*jy}uzfZIi}#+ZufWIvqSd2||~w4_?LR8@(yhNcZQbI#dNdXmHphC>9Q zX+4e;Y8~`4#*+!XUO}(lXXo)Md9ltHjHQYxgo+lELf>ZT=5G|tp$ zVNqTYEKyia&V{xNsWehL5HTJRb~No#Dh?dz$PhBPU{Iy#_`;RIJ4j-1ZG#fvrNr1n zPwA>)tTP6y?A{77@J9?rxb0$H)qE5@Uu6P?52Qf;O^R55m}Ai?S%3P|pJusSUX^Y9 zfz|jcBi4PFV9%~?6*z1k2fB?lY<`Na62F_xS_q6WOlMP;WyxqX;`&pkICu7S&R@8| zlTSR!_Nims@wT_Iy}jLeXO|cbHo5oSA0f*Nc6WCvtBSg5h~pS*3`vsGw1HG$e=@@p z;D;zp5hB#3VLc#ej3pM5x-|?oHUevGn$jOi_O6VvreR}yE6`lGEyJuwzbLS6+i}AO zrr9`(iHgvtS+}OE&R>SjRluO%$JiN&h|xyDbhZElRk_65mc7fnOeS--w*pUp+f>Y^ zW6E-g6oNQTu+{|$x29oyut#0jSZi?JpH8mTqcow}YEUVNFVYQowktYOoJBI_th&~cyxza|Um*WQX-_sDgI%^z0j zuf!v)3xKY*o%Wjp*S1LKLyeX9NY^5*Lo2yHUw9t~;n6}6DG?SW9xXy$j1oQwG3XG| zI`41-gc8UIie5^RX}ok;VKLs~l)&JbFH7dLDf8)sW--SsLk*4bEzTR9X=tmGx>};7 zBvP6<(hLTDMjIOxML`lt`u&1_uTNSeh{z+f$4iTs77>NVP8fs&OAF3oP1_08x=yxU z;GIJ$h$Df-c8nYztU-8#zy>i`;m}evBaJ8}O-sjc^YSoM#ZQeU73i!Z>x`OX|>jD1@YLf*5RB*I4h_ zK6WfL881uz;17NuYb*~w@F0&r{y5J)|2+5HeGey2o*>Iok|YT#(n*4Mp7Fr}bSgSk z-7=XiKt^nAAIFKX!3W;0hN^97o#EzNZecJOB9$bLV~`4KEt6^B%8#O;DcO`2ZQWAj zIla6VS=D#~|J`8FXE+$pG&Qfj ze1=F%ilT>9n#p8Lxm=)?>^3%u(wbhsPZB3wxxB-2F(cBe=6H$lVXjtHMOBq+ZAW*c z!cgmoPGFuSN!K&0sT-DMNq;aPP7~^;2@-NrBV|M!B}8dL)+;D_y>PCpZ}TBsFIKy- zIHZ(; zYhD>%CkREr!WxtmwAa4$`y5X^@dTgv#Q)1Hue|zw3su*3h<;_%-e?^Ckw;V^JI{qn7a4Ai&`Qwn_wdVxrJOODFY!{cSWNLP zh*Wd>#v6I%rB_f0j17juSW8vcR8_^OH(GnB&RT}OKBK{q$V=L$=`wPjEX^s3g6V7? z){wE3WkuOIq)PA}@@%EV6otxvXPM6?OvVQ+7Bh+>!#YD0YYz4fa4y_krGiFfo+hF7 zsH+LXd5S!vH4ZHV)<(hMa5i{msL+(&hBA*VT^ai+QcBW1LupN(=gg~`4pCZ@WN%W)8jAf6Yhwg&X23d9I2n2+y>Q@H0N&vo3RBA===2Ob z9{8Z#E;~ce85OyjZif@lx$vCqu0aymT!r^I=PAp&^U69BJJHd^5I#eCiL@T!JPwIb zKG69|f${?7EZ6`xIswkN;hHR1(;}pyT`dD85k7>%!V82C#gJA67Sd2h1Wv@kFbhw+ z>JyX_EhSE5S8=lICJIX7^_#(q3 z!#l^a^UhM0v0PMq=}TW?G#D`~29!-rROF~QrRepzc<$mF^tR4ZR}~w>5qQsRIwejL zil|tFPYyYc_+KDGBh*@A{Pvs^McB@U5!!{ z;%a0#nJ!9V?Lkr zpa08$e3JYyJDbNf&8q;{pe8?Md$PeZ&v`3 z4(Z(GvZOVkoTRB6`u#rr{(!yRUA%+IbV^YaY;SFI@zSM0casT>SrR8Plku37*Ih@F zBz*Vr?{eMfI5eRsYEe}@`_waN54}O3@#V`b>WbDmvM4A5IV?KTESF1EmSNkL)_JBK zLxa{);P0v{s%6Q>XcUY>mSL@pMQj^3nI*M=v5!pc|xe(-ReBhPcvEMr+M(OR*0u*cityXf`$EaoLjY5GNh@X$1& zcsz?>rT`&KL4khQsdZRu1p2MrZ`g#PxfXOa{9YE%wk|U*LynldgLm!{>ElH#qj`|qW zvcI>-&ZQmVEM_)a1VCI#l=7ISq+V7bRGTm8_X}dJ5mJ!%dNg&#rI&YUjA790Q&u&` zhD=)1wCF6RH4RaiE!3ugC8#9EN=d)pCogimv$S2*kRWGtW};ETbrT z7-N`BXVg_ml;%hoHVq{eN!G*Iz~-{7O7bM4sVjDNE;64@7>x!YQP4D@g;4mw#-bvG zP-Iy~UKG?-gZF_}CyFDiYr%y?nC&?2S8Ci!DWWJ29#~^A9hJ2b5@S8FjLKnscXfxpQp6&A4f zLA93v^oK>o+8dL$4WWe;*e=9S9<-HM8|aIbj*v3KdV_QV?SnDI)FG4T!mi;7y?*Ot ztPk3ON~+GQ>_Bb>_>RTa2i5~EgQ$tH9nvQWVI{6J-XT;(c%)Zg!`KKB_@Dr^)SZXx zkf;!{(_uKBw`4>}v0K9Z3uYxk>0S{0=#G__5+X*w4t=j)?S}?Wc#y&e1*W6nnR6%~ zCV9BqhsW2y{&oK4zxWqixx7o3r^HE&buDFSQ8M)Ttvo9w)p~PWGr4x3k)~;vEp=V? z&93)R?^i0?a&6RtQR>X;wPC0boH%|W(C2iYA1O(sV!ZWC_r}CtPM*0@h)|87msXR%d6#L6L3u_rq##m!W<23Mgl@+N_ zXqk}2ElXLmvDGIfL84ixm_{iY?`i9bJc&8BIShS~(-K!1j*m7e@|>n^QIRHzA|}%@ z)jWXhLI{S#0&5K_ig4ayou@H|v6EFa(;IM;?|a12d7N9hxRt_P2B4qFAr3LU2;d4}*3Ep$lA5jqeO9Z@eUbdsQ> zK1v=SSu#7gLOGo?>J1PCLdPUeN%Dkc73jAkrMl9tYYkYJUiT|d*+ZfkLf+0aEtg%NNci)NQ%Jl^D9d;B9KnK`&F{7{o--Tp;<*9Xuxpymp2tnumbqg`P z#yN{TQf}>6uH9;Jc2aS&TNo?3FClceKJS7N>1?PH!2uQPg|NbTf`@k~O3{rID=~~C z;$%LAxz>vysRkhfwJITT?#QB(>jm8Jg8u*jAOJ~3K~#6Nyn*gJ21B*V%sIL=akvH_ z!hY9{ZxGV;o%Ef+M)}pY39-hkR*#Q9d-Pa`Y5vf-(A^#B1MYb=Q~0&N`5OP{zxr3a z_`-|iMb?FZw)23)XBlgd&f>byl~S#Zm)23|6|D+PSJ_R8*1;Qf&UL>J$I5gx%c9#1 z!~4US%1*#m2*`^Jr0a$@WCNolVo@!aHA|v?hTW@}9L(4~f024#GRTI^59VCn-{GzA zxSO79Sj=afpUyBSL~j$BSjuXLayI2uH3MlerK6rLDJS#bp%{aZf+S9;stOrLB&xuh zB@u#No-ures38~2q5w$_#G3{*FsYl9OkZP*9A@3KFK2GHjlZ!k)}d!2Vj z&a?h?6+9l^v-XTuCNlzmr&2}{<&TD#2z+|Nw+qMleoK2f-LJ%%966GDSADss-(4s zB#!Ye0OVPgVT_?M4a>5^7=yKzJTEBvBQEbv!?++=R27Aa5GtW6ORO=(k;Ga??v!@M8LI>9S?g4@;ezEL1jBQyc31>tIEUmWeE^2 zbSDuo_!Uq88rE?f!aTk+I6fFrIn6X}I_%=z&UEM%9X>u(hGuQN zRvy4gY`{4OR)l`9m6hpmw4>OKb3v;xtY^ReJ7oW^Zl*s9ev6}EweaiDKD<7GQ|aLt zcK3Jf?OkQA-uzhKft8K(o%dzUHB6Xd{TlC~X&U1An!T|bFk?-ZS*G(qSMLjOg|!ab zhQj9+q2?;|)SdG9%FBX|T>_0#o+zTLSq$UoyzO|ZELtnhoH;|5pigTW(ZE;?bM1j6}xVc4^ z4?>nPQcTACOlJpSekpLq;T%CoBu}udLq~z}RS3^wIj3AMSQT%}Ba3Jy`RA;mv7w#M zx&Q%Gbwyb<^sOh#5_|{O;awMKhNT>1t(9Qps8!> zrlG1zhNG}KzX_qCKN2#9DrGB!N3>c13XgLJg+p3LoQR;tUJNP)ARH_|CocSsIG$#pmvGGm>g@Lk3exvtt4 zsw>?PD7zz#_58K}50k|mu6W;JQLFQ21!vB@$c;Ci=G?gpoO|gt?z`_DWP=`;FJD1gPqn|tUAI2K&;QI%^U!w4q_$3F0I{>OeZ^2_%Gd)lp^X&IxcqSl1!2ZG*AqP=TsjYtDI^rp34b zy~Ih1b%x1oLO)L#jW(Fi=PVZsTGLYW3N|)JT-n>_(uE6bZ*4Lh4v2Kf)((dw;7!;l zRyTY#)1{O+;nuhq-s74Et%K{?EGp8dkF-q?=9FQV^$4Ok56(dwK=mvQ^&pF?!bwSz z#26QL-nv;S2FKKGjTaC_8l=Ew6>+?XZ-zYx6i#S%mi?vvRHQ#I?o(I1=`VRp0PB^jU>J>yTG;Rr>xg%u-!5 zaND+PVU4buB}#=0CjS}-N-HxqWF1-9Qo7>y#Y@bq!sY1^!ojPefiK! z8zm9SJ9c+2vRup=4idbz7#D7S7fYusg1OJ$F1{GRnFs4O#OHpJjr}H&% zYHimzF2Fd~Wqj2dIv5Ock|bulzlUkkK9HG`<_t zFx>zODDN^WeO`OqHhS3m+;1Ok6a^uEj zdc7XsKHS4Q%X@d;W;{A!a(0Br@$P%?b8s@^)$s{wQ6RB=@9ir*c<_v-opI^HHcDxp z@4m!&=nZ-}V`y7XmIRETsY|lFz&OiCAKc*EZ=TUs9=sz<6$vmKP0(qA_hB|rrW#!o zXq8e{b>z*+H?p6udHHZw4Bd`WzFjMuJ-pq#3c1^aNB^+JFOA}Af^Fqc^#1pKS<%SMUTp*#s?Wl$GZ zQgQL(MF4*A(TDuWpZ+PI{r1;<{P8P{Q4~AWMsIs zS+l-A0DxHn+C9bm-^Ze;U9zTAF)-vLSB2I!xOdC}$l9YbG zAMR^YGo4O=Fkzwzv&dCl;jE!G4NX(yoFz$1!?iWMbsQfb(^M6kTbuNXKGXRO8U6p>C?NwcDe`?pkRA@ZUi^P!xw@Tl zdNg9^`UO7t;5z@upZ_KAT+8v(3rHbQs-`F$M}^|uySKTpwZ)g8z2wHtZN}4*jXa@D z1a7Uz>10fnCH&##w*gIKxdAZduNR1F7i~u4REnDqLg|q zt72gwy2PYH2Jl8O@gA);X_B5_io(&AH_Hrcg`}xgf@b`;+gX)TAr)Two>)gigI1|hAu6*r6%Q8Bx;*(OzmCfNh;@1*1 zrHhI}h!rcZa1LEb8kpPRcwN>N8Y|1jKzPqY9C>NkxqOLNyHBahNt|2E$%`Om{MN0v z@Tq6x!Wy^Ux=uAZ!Z$5PyZe+Xq1PLdWGVmX4}Qj0o$p{#aY>6Ov~}{37e-Q zwl80$Y-VIxL7oUkrzfFOQG&K;qlI3 z+Mth5+_a@sq*-sVAxk0^N(lPveezzx(cuK)pyH_3btO?pOCwdCE_I|3eOs#t3Y9xL*V1yHdnjyF!>Gz6o+sT6P~@x2OBa z@|?B7aOE`}9(Rs15oAUD;`dgwzb;b?p#O4}cU`(}RLjSOE~C4Sw|)^YR)beJ1Z=k6 zM!)#gGQ6ymkmo*DGNNTD5({~0Aw*E)v<49i^DgT=AHS9u;yHzh71T|{h6M{8ZJFso ztX{k9w0kZW*Y6jNn(novR4Y`PZu7ArunBnk_I1(}PEPiaLeeyrsw&yu-e&W{1*B-n za>cWkyJXUH@BRad)-aHopMLxi8=D)nub%RIm#%UBO3n|mTm0?)SA6sNCy2byTB=Y+ z@mGKGOP;Q!oE;w0R1N*2AW@3paLA2oHyMp5eErn}uHLvF3|#99gr}j#d4n=7o`l`w z31_1z$?yWLljt-78$=L{v4IR4+4j#P^XUxXJbABRQqHNXib21R$J10byL)>yRmIJl zHyKYRG~Z>b7L02}e6TwFAUgXhg%FBfzt7WW&$)Ty3eH#_eDe)I{O~;{C&v_8GCnzF zkR`15611=Q`Zr%vPENUV>n2ABhwMIkf^-$zYeSwrdPbfo21Ul`@Pt$de(xtA^5V&J zhP@uwFK#p4KO(2${uf_y=dG*wre^o)3tl~c!k_-*Kj87V54nA1?EH`Tb3Y!A-*LUpHAK2#w78dV9y-26d~a5tP0pEucbhGqh|Mmq zOGJE8%Ag_tlOKPds+@%3{Zyf~M+n1wcE;iUb2f)PMyF@ofAomcS?>AW-e9&QBF#!Fj1hi4q^o^bP`Qd2Yk$iK;;Po=H3NNvZ&0zp}oAGVj3#r=D#ymvEBxT6 zA9MfPT`tW$^STOy*xpCpTi~*E9m9^VVj>8sBKuzoh4VoPgUF!QDve+}!H>@ej*g3% z7C!J^+P1}cA6e0{TqSlXSAu|43S;de8w=SN=SsxRlvQ-3UKz%)5Ft=5)^RNV8#Lw4 zkLVwK#`yv7<$^ySyq4TK=qM{9NFBKb?+ji={@Y5%)Zukq3#0?-S3BCV7>%1F=guWu zX1E_+$8w=W(Uq?&S!NgF5zDTp_mQp>uSZJB4?g;UD_5@s09b3J@OZBfvWK&lyvRwi zAn{!E3fji8zIB0}TX*^OFF#>_X884kKjRla|2cp7;}1D|^ezAMpZ{x$VnCJ`xW>?W zPtogB8AraoPH9^1J$S%ce}GI=NHsU_-exkJGMY{~nw_EYf}^J8voF5n>wDj@b9IN_ za1AdsPxkh?e&;Sq2PKDkUL$18>iETwgpc~#O{k0*@m zXe~)J6up#<^&tRF6-dPi9%CIUNlA2$PIHtDjjqA4N2)`1JD*Jv)}y>cpzxte!~sn` zr<~6y@{De7 zRgF;!BPIXl|M?Yzd`M%#k>H}-hw$fXsV+ctpD!{bCl=X{j4Q9hw5*Nna2upcl`l|4wGMuME5}`q$1G)vRs&djn~YAFkEf?tb>b?(5g&o;g>67<@6 z{s%84o?ow5@K68qKaQDgvdGGY!<4#dgF>!S+@vvYtY1ZIe%e2K}^ZNRo`QZP?x23+g4pv#uoZ%G3O(yEhtxl2%!o8SI&?>=Li%t^qyoj5#1M6t3hRJxs=Jp2O2ZNHL-$!Q!z5bAD zHpR41mNTSOn5L!Z_1W6KKwCG=CsX$K_Nc0g!ElXgbPT+Xfpu6){3AR_MF?n-Q6Dt6 zLzyJ;G%j}dvNfLWjX)&`orl!Z){Mt9gf;Y2!Q+!-s?ss&Wzw!r)aBrg4%KZ-SyMD?uV;R9ztG%E&N_*o_i}048ELF$g*aTrv&_tDr7xyos}8 zF*gy*^jxcDhSD_>x`o?~&a4K}*ULj-QFeBLW3>bpLeMl#2!=_Y(MSJ+jZgo_Hy8VV zBo1_GRNT%&kX(6A#3Fq>zX^oh*)72KH~DLvFJmMA<|E$LozJ=LMX*pWVG-z-O@sK2 z#sBj>IKKYGfY_upZ6G~w**4DTiL#*yfhwlU1+HFN7pvYfIkvEK97zx{@!lF@9+ysmK)(%yh_Hs$#AjLpq$KK}TJ$Ta2Pl~SNW1JCMqmqpgMgc z=;pj^TpV#R3mMeBeAwx=kTk-C@g>9}_(7*WA>ZhNy2xC9ox<@tX4ZYZ`@Po##4@;r z53_ZLw3;?yFJycT3cd@z&@?ln!hd{~xv)%h3ex~0xpT-*@C2$*>N z2+ITcb1$(3`B$^I^QZg9NB8yX*RJwU{>dNlgO5IlO_PAvG*S33@hNTFP!u`ctn7dL z&;L31?tM*~XWY1XlW*?b=db_f?|8Ah$M()8ivEB{M@Q6E9Wso;03#$u8FZ4OtCS?m z@M(^*4TojR+)v4p6lVevSEWgCwoiK``GDYHT_dtST01J^7|&)56U|`IXMKG@f6%8Y zr;LtIDAxPje(M_B>qDBd#aT<5W~6Du=~>`URdr3G6DU%u#*<}3vfetq-hh68Kvv{b z)r|E)pY81}cD2Ttu*+KC;0cDkX`0fsVFPU2noc@g$p9TFCGpPUJy_dPmUEO!$kPm! z2J9`&x(0%59i7kHwk6RCwbWq%T%W^!*!Ux_zouiD*wq7MFSn7r>3xN!&ZNdXWu;J^Dpl4pZ)0{VXtn1kPLw|UHblGOZV#I%`)f>mwoZyYTFDODnF>b5wwsC3W4FMWB&kc-Fe$G89U0 zwE(Uc8-w#07cjPtgz0P;a<&lz`;P^%)%QzEc`o3c!--bPFexQwc$uT${U1n=?vb87 zA(`%xo;~^QjOScn2-&t$QDyc&7D>8mMJxiA$A{LsROdE}@4VODa~K2IcYX+Qt}N{p z1zTI2+_-U#-~HX6aQ)hq;QnKShJ0032NWR0&yDP*zn4G>K+oa|35RlUd1h+E80TUk}jEQW=NYl>X8L2Gw%#iCJWd?DTTF$x~h;;g8*Y%(k}bP zljXq(ICS|HZQF#`6Oy)R$+DDQuSe6&XB`4x*c0*LY)j`uH)w_tPJ7dOD(<&$#=} zb;RtHwarZ)?@qxsXhI43;?*hTq~(X-zr%}HFBue?pMU&5fB(x*crcl86gS|s;-?+l>|IWvZ z${A;8Q~G(3F%crDWOloUiS2bA#o4}-tQr@Pa~@|p+Cx{md5q~Yv_JyvmUU~)xsqx@ zA?VT-1Vp{G4)}I9=%yt~lSqw`7QA1~e0Bk}%h04$i$jE9*F}>UFuaf09I=}eGQBv% zMSJ0Wn(gn?4VXLUP}M2v`~V>}m=ax|g%Yrx(rZTa#gt)vh&eoDkc5#QBPA`NGq&si zE=$<1OzY+#yIw(_XXoyD7Q0nN5hfu9gFZzO`~b5oT?C(vjW9lP@!~eUUQUr0T)42! z+S(dT)1cInm>lkbh=O}z8X!qhwA7f^pknvU7>`mOXBuX885%26Ft1w;KMxIohmY+jE{I%Me~O zT;E`A{UR#uQRIDkMIYy&fAIpMQta$p=Hz&vdDD<6jdhZ|C}`W7BulC5DrT{P1s`Ti z1Fb@eh$YJ)fvt3aPh?yZWjQA!#n?IX`8>?I#*U=Y8fzRXb}|nSPjI$E%7i3=wrM## z8==#b!P*A-V2#QCE1D)qD^*oP#&@|AEp~Aq#(8usbtEJ*0iEH}4Bs1a@vS>tyZtWD z52maS3SK?k}%f2lVPhAy#cM%e093VZW-idq*I_h zWP(fAF7PLR@`wDR-~AcGjR7jrq)CBN2|~!wnT=R#+tx@Gh`ntjXl7YPp64`8jkRup z3o50S9JqKb-PczE=GEEAx(@dx1gqF!5lg8g(>7t0ONd1#k|sXP8m0-Cuk0YCqADxu zs-~@LGA+sa1+K$_=M6y?Y1D(>~8mEH6)M+@r@l-#umL@KZZ6uRz2>)78 zTM2eCTLq%y^D=Ader^$9IwY*Cf>vIy%bBS zi;)JRwT_Z1;eIQn(21t0n^QC>}V_qMZZ6wF^0NrNRynr*9*`?8>SqBS51(l?&N32Rf92( zx^2nQAz(Q>9f9x+2LsBg#9PO7K4o5(AT&j9z;JDYwCDo~Sr!a*QzbFNljoWuOWE1E z#D(o`4o}Buxtu1c>jvj+G(1+z=9chbL*{QZXD3sLLLs(GhjkvVFP0dq=O=r>a{nU%5hm&}UZ8X&OUQwUGY@hPjuE z4UDlXY7~%4!T$b~{ryjvkIoQElILrD`ppZnqDR$gUfn-J=mgc0S(ePEQ-lzaaW2Ty;K+jvZbe>r#*;Bk-O$T( zJc7gHW2)BDPZL@TQfs`hRIMY=f~>ZX0xui150-fdf!3XQt0hqaQNO>Gf2Qy-jlJx<+e> zN-``>cqo-8NpmV=Q9^TeIwg^o)>uT^r!HIaBE^YLL%hZ59OVS9aUheRL*#tmdU=7+ zI-HwxXdk*-79U-VIA88{*9d_&vIsg+``yQk$g_A8!}mq-28fh{@B%^4ij^!4Vt{+C zArJykz^$D3Sm(i8+yYo%A%m`Fb=~oNm(?v<{auL^%zWL7VM_OkEEaW_sde#CN+N78 zkgh?PDZNZ_dUnQk>PUw}+NzBTn?5S+`VhpW3^sP2*pzUKxmw{nhQ7nO5JZ%Y2E|PP zfCqyx513_HxDLc(aX70;5);NMMl7tW;KKPmn z6(|8nK~qL75jv z)fkFAU#QQv#?z_Cc7_zrgzPm-gXD5mHJqHDA(i6v7*f^v8XiBz=X8F$`UXXj#{vdlR?%z5WZI)sO=B(27`o!hnQ9SuylcT*Bm^CO08_JIes`U@l`9tA?=EhE?`{PP*J(jy zc(1nm#mdh{RRsL9IFrHT(-Rl1ASk^eLZbw+aEwNTH@cI{@gj6`qzc9+)*6KHq&fv8 zE)Ih)0Dix6-a^C-D_|5ji*Sxi1R9B5v1(JD`Yc@{=Yz3@@K~SWjbPZGvE`1So-;KK zlgoWfe;ZZqVTHsHKy75m?yzCBq&1GRb=a7hso)D2viazz=>s&0N>WlKgR{8Qq=_QY z*ko1azdLG7jLZmRr)T84wR<o!f?15%DqGdhP(hJH1qikN9Y(T z0+&k?#3ikbn4-0Db5bA`*0o4M3{H;D;?!G9-ApNGeTEwY@?4YVA=_-)hNfxptwHLL zwS{iu9N(JY>EJxm`HYQ=+iaa(qSr5Iss;vcU|@Qogy6kG+PE_dk0G3}ZCZNXG2VSj zT`RWo0ULL(apA&6CbJnuuaCuXd^%!x|BUzFdzZc4ee`C=&ZWy#^BQk0y`tdx)2H0H zd7YUveDc-3V8t$@+;5ERRtVBO$75FpME$~EOm!KL1JwnJINK706jw410dxY@anbu2 zK$g^i^W8|%aSK+7maBm-ek!C##h}!UwfMLJxEREg(pYQJIz2}YUK~@1m>|V@LK`gV ztP7%!R@m5q^os_9=sX6zUyN^f=N8UO3&}?jN3dN`u#nMUM06cO5jxJ{oHfpCglSQ> zq7a6rtZ{WkaqAK)%`vS(B>AF*mhqlDA4)7^f{ToC9!u~CknuiunU{|`>DINFwhdz| zD^k)OINxDr&N_^3Q7T185~nc@)9D;21OL!?^1O)8aNLAExF}bobhN9Bn59xGngaXf zCM5(yD&}R$WL6>sq=`l$sM?m3{e9+TAjP`Y(Tav@He+)*IUG>Ocit+CGH9kgvcmUSda!uIwhbdob3Pq5CBCMm)det?Rsh z=Nf1GuefvV3NPPfiIzq7=e;5+RWugo_T>UWDDj2gfAky9@FQOSVNI zigB(3+ZVwrzDXhD3K+=hpH6BTzr>k>Q};3%>lTR*29ohO;dPZ(^m_fE9!gLVW%U?7 z&?wrbp{^^Ms-mfDnz{}+Qftor+hH`}cjN41Jb&W(<3g$9qNxVNj4eJ;qPuJtf8MYD z8y1qnqg;iyLAs@!jS&*OF(}^#t9U_lOj^!tsw9a)JZ?b7VvN8ziE*KvaZ!XZ5M6^C zxpQF@tE#GnpyN5dm=EQlR+2=g!Qna0Vp9XkvSL0fG1kUEhNh`#nwrMc)J;W@Hwvnv z#xz)K0$S=?oHMbJ>_eARYNoRp##)@WNG+JoN={EkOy?zA+gs#$4tTVdymj*iLPA}Z z*w)}%!^U8Zjr9$@u_QY1&l0UEs|xE~0M)$@T}T@Ya@wlFwuT}r=;b|%qQ8(|>M+G5 z2^#a=q($4dOlMP?rjFhMp(5zz1*uNRvz#kCJ8W%k1qj7ivMdb&p=q!-42LVJ!H0Xf z+KKNrk=Hfw0xSToZG+sm2oncB2IZ!%f|;(dG-ZX_( zl07@nyK514NRhKE0R9T7zWPS`h+TEOFDZj*YSXs(XfW!0vjC6XA_Egk#>GnVx1d5S zK40lJ!ZHKvFtF7i90Odyz5D|A>h6_~zw`RFhuOhqcth@M+W7?SExjV6oQ$c< zYGKS9x}gHEB+kUmMM!4zDj2g`FoXc6R5vRrFt(F#2?B%Cdm10IwyLTZpl;XP2n0xh zR4KL%oUdN57w?cnsf4--W)e*u6c3sO!$K;G zG(l)Z)mX-(;NE><`w}l-yx{2Yi0jv`lIIye{Lv5j_y6|aFq({Ln+DUgT)BObY`Dg& zSFcEQ2wqu{Q_dP1Ye+=MVuVy7X)s~hMN5g2is{)DZ7scZg(QIR-TM^)`2db96-IFm zr>C5rjhRlTG(IKG*I3_DOlLKR2M26#ZnL$y$>!!J*g3Kt^ZfDG3%=H@gc8{prhFiCGkei$Q@|!2zzIBqtNluF}oGm*byj$W65Ie3@Nt{iL!^R>I z8oO_^2v$p$d3Fh(tq6QrMewO?f}Z^A z0Zhj7&vnP{KEz6}>OlNhs(HT>ykaSL?)-dr8SzeuC2qH%Z^Y7b*|`K~!L<#Utm)Yb zKcA7N8i~VJGurtK*#%1<8X{fa_W9`J@6*q7s`;ExKKUin>6qzw z0yd1|JbU^Sr&ALORHuxa)FzMWI$_)6rQ$iFed1Ixd?$s9dOn8YyvJ|k;a(CfO(b% zzMpLxdc8jL*(j1*19-o;`-&g`1Q`wn#jWkM~JbwB+A zRZ5a)5d#w7ElH}Wn-ZByvOHi$f#jGhb_5qY7&4LtMeKwLr2}=sbFO>$I!P6=)TLit z)M7Po2*~r$HC-LJ?mB%^%0*_^vA|WL84Lzgb&C>?*0upG77L;L#cMB*8<_K5vb12{ z+sMObdoa~kGcQoK1atV6zP!3c*e=;3Af&Ui^Ibs$|5IGipDwi_YY&{ zZI*kG0I3y|(TKKg*xcGANrNM|AOsEPK@f)g1B+ep{K-?S^|XzpswyxR7u9XGR!pZ; z+P1}e7nCWq1|gZxOOhm|zqZDU-9x_o?dSaLXTQ(2E0;LfKjP%%5WK-Qg6GelMSZ%E zIn`B3-s^`hv=1e|F@`J)%B(sv?R}ir4S1yp&v;vd2)g%5s_?u=J+``>b9k`N#nWT9 zlZ%nHuU6gz&uliM$fA>z50!$ohNn*+^U=pYV7NBq#fz7`|G|4~Z*6mUupi#L)rZ;I zHgut!S(K1cfR{_gy7w*!`bU!mEk$UVsx&M@;b^07mU9Vt-d}X{@C6ZJp)K!JfGrSM@k#~+HOG6DUUlSYj0fPz)JUU(nL~4Okfj{@JTR>vV z4&~wuT__`^QsjBgd>%5fRnbA;H4a43`L;GJ%+`cD9vJ}P1?Q{F3YT|*SadD{~p+rdF%E~cFwL)6d8j-pSHEpmoc>6tc|YYKD6zT zA@dFkCpu%rIlPWP6yNei*4?zt!e_vFgG2{byB2h&Ct7RNaGkmiSX&rBlGK%_ZY)CO zq`3wo`TRHEu)eXz^A~%Z9G{UVS(qoB9@3bG2M_MEzP`q#?XA!$ZW<<|8EKN!`U%!q z(juoOdN(#Lr-w%*i6-r3A^UeOOgyv(trV$J^wNU;m%E%CpM?(cx}qowG=jWXLnjI2 z@r1H0(ONG?%bfQdot#qDHCZ0AxHM6WPfvNZ_mT@2E+aggoSjk5CNxdWcsypUC?ZxF z44$P3_ufLpzQX#l)&|a=_vfA!?=4B9@qn=b&uiNjAv9SQ%ybn3YvSPg!h|NgexBzf zU2~(hq%lKvZHsMNPEU>*jmB(mZt&&TUvhGM#M*Gk%NH-+3}DU&)d?>G8XmA5ftL;| zLq}3siF1M574W8@m#<>y1~iDEnJ!g^hQixEt4Puy+R)2(gROF5+w=Vpu}N?CgBDh>x{Ww@{;BLCiJjIQk;K zzVH@j#p1ezR3JL@5Ebu57d``_Qpn)7=zW0qT@-IjRg11#+OuQwrliO()3z0^snD@u z;H<@Z8@ikEmP)M<*3mSUqSxc?x9{@a`#}|UKA&-Ne2jCBL4Qb|XJlC#y3BFPBZ&*f znBd&gkzGT!5zf7H9TFlm1;TBzWZ9B>p>?!dlbR$UQYYl1dp4O&0m;Vt7S6Q@nNYXj zh2-hem;Bw|e!|aw@Av5U)_C{s_o$l+YhgN_QneL>L7yvEc9>13BvPaDKKrkZsLC32 z#$-07U*tF>u4!2t4zYE^>G25{^aXmo93>=8-302ASM;(T#|MYJ+Ito7-l)b~6a|Tp z^m_eR`r4?2AEqGif%8^YRkR) zC-CXg_#BEDv?Au}!}FeHIbkHr(6)hGjQ3<&5{T|`H*qmJ=&;ASs%UM^>B$MV?%W~I zb5xw?&5N9(7koNrvk6%$NHZPdL&!8or>E@f?C|SPKjp=Xm;CVKk62${2adjDlt>G- z7C5g_UWWN}85W3gGGsj}1L09F2D#Yb>#~auf9mwqyFw+9Lsv$1q=+1*t{e#6JK1Fn zNYX41#J406?vSDEkSZ|Ab?oHGcszsy85qo~V7u(R2p9R!5*IoL#M_`-FI*V24f9=Y z;TGNN^_b0O=PF9U*#+RJ2D`|}mgl%M z-0cqEO$02nGASd*(!CdpY$YssFGIb$8qA4APkb2dsVAq*5B9imbpvZ#W@QOYO`d2B zLE4yDLWbQVy1FZcjI3&{6E@e^S>IU0dl-$z%*r`O$HyqG$%}#{&FJMBxiW|}S&RjB z!8}QVFQIA8f=eg5V-cR2P9|{ zqfkx5px>viDkh@|rfn#Cy`cQ-p(uJBAD-~+$uknIBDShXv<|xV5}frkb;F<^Hcx9p zr#Z_~#(NXaMq`|V>2$(;K4WujjoGYZKAZ9Fx8HE%<}He%U_3fufBzLaNwCJz)}bj9 zGOX~NNF}hQ6YO*g*ra>rRdnL+p3Pu-O`N3+ytX9LU&^_~8_(Hz%-QHHRwmIgT_+11 zY(71ssiQ=d3~RBfYMwuT##?W{&DwCtqlXXq{s-@~y}b?o^#GQHG*%>m2PC~jdV>*u zQLZT`aZxfOr1BxlaSj&kbO8KsF_NkH6(kk+Qb7#>wQ2p@QAL zU9J_7_OdWW0JP6OK<$an_S)MUi;c zhl60IDgrN2C*9~&fG1SPw5Mxa1kchu;xwJMTA;o}XK&S21##w62&6JtYnYdgBG2#y z!(o+VJbwBD=M$d2c*WUh%+G%IBdlqe&8DnxtRX~Dqc}V|#2ZhRX4JC=)7XH&B?;@B zTeNZ4$nuQYXo5;J2K|1Z2$X@IH0TfL7d>7+d%@nzUHW+uC<%aVTgs}6Hw?YIXO9{X)TBnaxZff5X% z%c&EMkjo8HDS_4@^JS$ymOiI@O4uU6?j*vlW17r zCK^HN1sZ{nf*gfvJtC;S1d=NjuPjc~cri!H3NIW|X#@%>G{Pq+GK9$RBzUKAEg&@B zhjd>j8jGcoj#fBYYl6f~*?>0B`vbg+V0M-;h(J742`VwD@iUU~D|U7+GHncIKIVrXzRQ35&;Dz~rK=pwYmVENMoN^>;2qXm ztP1y5;}EvRv`yeqseny2%^Yk?o@;Ksb%pQUxy7aJbrLBUj|~qV9q{DI0sDtjPDeA! zs$n#pVzB5;f-oS=;=QYzIo8%V-y(!3&r^~#=vhe>N@yWv0H5)+)*!VA(*|^q2^eY& zb0+f#1_ToK+1ZGu z4qZYmHFeb>QD8eOI%pcp@yQ64%%$IrG^e&P*|Fg_jbmQYMX|tlLFH zB~c015Hl~yf^MR^q@eRLjhm~K@m>;Po*-W>gut{xnbiZ;vj!y(=kX9NnlOoK%8HZ~v zsSF)RVH&gwU6{5F;&6gwSvEyTyh~q}YMv{Y*UAp@28P8lyOA=?Z*@CQ=kSdXk?#dX zQ81g$Xsr#qOa$G#MbTwM9f04J$Xy1pddyCg@H{W8qe!@ACK(?fV$kt1i(6cI2l{sn z0};-pBiTlu_jrFoQH@`YB}oCwwbY|yw*G(G-s8!#Bs=r_x%*X5hK@+BDob@&HyYIq zpkW{eY8EpC3Y#(GaLd&gX~utmD=xVq&A1uvxdHzG&JdU(4QQx=YBU<%=<2G>5~(6Z z=y>WX7hD{_@4d__s0E`eEV4qphM^ zo`3d$KmPF#d3boptS#y3f-Fx-lT6G^twRMZgj?rj{7dTy8+dGEDO66DC+zNRG2R$5 zn>I|QmzcVfnxe>Yejs>RmMzQUBuPP;$og*u!1r-;=?))^b9<898h~3}<0y`+%yP@#DY#DOEFLHoN5Rots>_y31R4ZqhV0 z+gp2l|IdF2%8+F_3nwE?{f!YQxfh8x^ot(7G{aUkp$(k8I_Aa8mn4a(2G=n#L8SA9 znAJyiymNtav7oAJ8R@Ye??jtUvM=EtE|fGWrqdat(U{H6EvkCKd@_}S;5^7G&QCC1|+&kmpS{@1_p$=6d{GNz?tZdm7!Fy3Ph-Gf*O4AT| zWD)Q0(7i4|hOP+_h-I=`eNM&UZBz_6(wNZ%jIFSXDf>HH)QeI`h_~+08}xYo;*e3I zdF!3Gxb?x;_|Jaj*Z7O?|A7DWr+?1j$#eSFib6?GjD~&dgfr$mt+fL1YM~6YwiTkU zQkYbeWDQrZZL+^VrYtMY&Mr7Rn^W|Ll%=C6dK5iNo@oZXo~#3%NMk6;M2smaO1{x`o#t>pC6OxoDd8}nvf~O;$lM9>&b!PEcJZObY3x^%&AHdM3iz_$}&;x zSRJ^5KwUSqzKy&>MdND0M-xNUw3Ky?Hb(F^4QVF$Wn&$S#hfh584Lz7=mg3|i;5#j zGO{BM_0k-OK?%R6ROt&ZU2-nQ0KRt*Y`wT}6G z5rcjP18D1(;b=tg3v4u>)>_lrmZMk43J7>q>3OlgB_Tdo{jVL0gV z$tMpOj{3CK0*!EYnx=uer8nr)wk6g&ilUEJ4X*VJ@`OcGQBNHvEyztu-8O_IC1@>a zs#B#sJsF(AW57tZ=L@ z^LulFbir%c!bV8O>!Tc9lcEc$5>&tJH`!%v0b#v&V?H2V(=PaX=a#+7q@K}B0$EU; zygCwhnC&f`w`6&S51tptC$uJEdwZ9E{a^n#{PTbDU+|Yd_yNE7z3=hhiwD?K%X~Vg zTvP<>@J&PGqJwtQDSOH|QrkMvp4KjKz9vmG@*-t>XA`ATYzy;QNz*K_E!2ggb;R); zLy}|yRTv3MUMV_GAko=L2BlRbtV$!mdl~g=8%Hpplwq-`NQ{gqS=Z7u8t*MlEiTv2 zwWL`_o*P~q9&>&+#WjlAtVXGn-~!&aeEgH2;1SVG8$|uVTSul7@+6DmiD~p$lu@Il z*J4BqfPipNodIC>JLBT=l6!aWa&&Ua)2C0_zVmnK zfps8#_g}XWy<>5?;9z@)^7M>RqIm1-7JEB8JbCt$-;8yvkV`TWz* zc<;^)dc7Mwe)gCfckZIIKA(K{h{K~wPPxeLmJF-|Y}Hp^S_~SU#&`F*^-QSKyaxd{ zUkCnqjR>ifaDA$35qWOwzdOA4vrDoltAN@Co38uTm5W-hevdICp4VAhz5dRZ{yr7w zBwx$?Vn;v(2xG9vZBWqgqZ+#IiYd zHM=uTs|1pO3lM^0HWfLVG*k479%GT#h?F>Uav<{^s!AV z9lTmPrioU95fTW-kZ9@FxwZuzsG25b>aVNq8m%R9h+RsB$n2Emg1W9yq|y+Il|Y)L z^h`q4wB)&nK9==@$>dz7BC-M>8V3E8=TE<2F`q~GtPq1+N}5W5j_r|U!0P0OI+&xI z$xIT-9FsJWW|~Ry!NkK~8d*)#P}U_qm9V+FP0=e*Cc)^Gwra=!7_Q2xWmbRR+J?f$Dm`4vL6g2FO4e9k=Hv5Ko zwctPeyFcN(-~Bcld%Jx6;~$YF8@zREgYB_lIu{G98E8P5?%i~v! zdIfv?`zWnAKRIPM=%E#4S~|KWNikjo3{Or@P)c$A+BNRpy+hMfBnhNC!{|f;O;mnu z>yk9f@U16R!aqyM@wMQtuJO{iXd7(1!04QQ-;n18n>!mEot$ubdcu4*C(Bc8+foz- ziP0oUpjYJ5xg%zrib#h^p+?$Qr2OX+GQFD&f%>>VV0aNy>@_gCN0JobbusXEf=i~)9IY~V!_5} z7w;>abF_`jcQ$p4(V8O9xtvTfN;qR>wIEG}FnV@=#`)P9#u)NEUt+i2WJ!`FINQ=O z4BEC`j(2tYrWMx!y09(@rrbwy(>N5{vQB;nT0TfBUA1cZM~2G(T~nsQ##RF)f8cX;s8 zBi^}pz|q+&&Mzk%Tsz=rf9`FZ(_Eg;A&5Rxk|o@_eU-;gAG5!+$y;}Cp|$7a)d^qw z#=HE*Uw*``JNsO_zDJU!OlN_r28F{1Ls`#w`eK4Q3Jk|18mq8Dq>4etXl(0bAXJ5A z^jAu~7R0*uE|_%>uOmvXmtgBP|C>SVwOge+x`JP(;@yMqn8!-3zsBpq@6F#U60oml zSL?hl`I}a>iq-e}CF`8^AWWBhsTHqGY3a}*Cwp)*VUcUdY{}&KIZZj^U}u}Xy?rL< z=S zRXr-F2^M2D#)2}Mwk&D#Ia#7nD$v%Jq!@8^e~(eWPY9mbe9mM#=VCGwX_?VL^!$xr zTt%LfeQt9~12U-yGjK*P|29;r3&+h&KMQ@17(x~ZYcyOOhm$5v1uLY;G`}%{V#s zgbVj3GGtTF~rP?3;fF-5n3>FJ z_jdp8z81pzqKf|x0$O(w?zNYX7+Cj?QbLFfj#MRN1l-~RTTK}Da)!eZpqNZ9m|vcw zLo1s1d5%d8S<%Qs#b8W}PDKFEI*0cy&N`;8Xz@QkdfQ^kYP1ABYnQ(S?#*0@c191=#Ln)SSRe*EK6g<#>Y$~ zkmO=wfe#U56sa7AqMPCDZ2j<^+JiiA+Z~d~{ICk1y0kR8=gyt`?C)LW)vFWk+!@Co zUme2JY0YS~y_DMtO4BqIi*iPu_W;A`*$J&}C_=jIFuACD+RZk)DB~<&bIUcp4reU0 z{{WGB7(sj;HSanTTWJiKG^5w+ljS)eln(+@4o5ms>nxj_TMRcg=;ayLn_C1tODd}VMIR4<0{?B zKTKBr;Ot6*Hv#w6LRq~|7nnNitSe2O z>!fVlYUIPOXNan+3I)s#-Sh3nn7Z*N88tF7z_zXB^!PcMuNaMn;x!lo$45sjj*qc* zMN>J3{Q*gy&~tsVEJy1&d)SC*p!XKMC>wa|MNZhuA#nWiglAO=c(yjjT)lFYjg1kT zI~xo~15BzI_Y3OQQa3HGZkb=qQO2;bF@~%qIEw+AYK{+ztmtvDf533G!STr{i$%rR z`HbnTVmRnC?B`Nm8c__juBNpO{k%XYhN@iVghP&bbA%kx(}E1O`vHkN@-3{PkH|0IX7-xm&$HEfczcN;42m8H2V;&-PC1`7WJOAUv&UpMqeyak<38iQ=B>N?Jbp3d<)PKP zaXDEqy__%}5AjN~SWHQilq@osTQ9csO}oH0R)E|nRF}kZqir1~O++=;BMUP|n)NcX z8%FK|pIT-_UC`?Aru&F@wQ?wy8ux)p^Rr0&4@+VnH$L)7Y9`Z-6lgO36YE2zN<% zNn#V%Gz|nVR`yCr%k$|aKYe=0izkP?{my-wYQl6_U{pfUA7ZU%F|U}H6?G%6_}lkx zbLZW=Bzc0jEm_fznv<{R%_qnA4#{^T>#+OfCS!#l;%@iF^5 zTl9K4XQve-)o`|$@xlGuoLpXVdhwEL`+EcnM=wr!=gvJA(=+bx4%wvO=%Oa=WuRd& z9`NAPNA&v{w{Gt+y_~U_%sJTEqit($Zf#Om74rtJZxoo|s2WFqyvx(WBigdzTfa1< zr$_u>|M#D8=&-`?|$d|y!ZAsPG7y^w1oHX9k7^BIXyb(&Xp@@0#BYCa%FGG z#??)ZUraI81@GRv&hwWSv>{>R>NZEGb7~g|+DKVIh!}^D|61W(#>m2u(!a~;A`eRm zzS!X=>sgmJlFlb4AWRD{G6Su`wTbsL|4mK{15;Af5-p)KmCs!zIaZS=Y*h1`US($kj?R!EX_qZ z7f4J(o@EgzHzLQR14d~U<($dIgJ^MhSe#B74Tg+# z#xNW3;^ZZN_NTwc=LZLT^Ot^+pZ&$}Fx(u`I7~Xd<2t(MqOD<<~6b&20 zjEA!YhwV!qKYh%#n^*bTyYEw^Il)Y*Y%R1Rm5PdSVo0?{drv)^6Y7>!E7BwqctwAZ zB=4cLr<~8ovSe90f?f`8OO+tFUXrA7jT;(kWt1>De6@(!ssuCZA|1+P;1kj`$At!^ z18op8`uX{UrfE6Y+eckdm?WdD7o@$6t!#_lD92=)=Z7zt&ubQC!|BO{8{@wx16xfe zh9%CF8pZ7FoVPzX;HjH)ZEwU|clWUk+}sK5Ub({I%S*0p=CGKv_0AQ7_FTDhjl-jw zx8C03um18G1vN=iqC&-@tQqEp8(+W6*~N^!$Y|P@UwH2=a$~T~f}j2RH4dMjFy6b$ z$3K0*m0`yIom~#kT6VVgX=W4h-T`yxX{r&QKY79YvgX>&UA9LV2iqe;ozXX%twF(+ zckVIs6Vj}Q8}-puMPCQrxqp?7tYm9*A8$SHUEkyUbjonp=hltus66Adr$@ZBjVROx zN5^6p7(-ItF3tAd)9dx5om`f$1-6cx)deh;_xg2QY)MLuW#4>0$2k}A1R^^+7W^Sd z#pgex-{be$!sJEC*w7mvB8LgRIT;QU)X|E{oD9$ERe)7qu zJbUqyL9b7d7i39JsuQ#_Y;Wyw|LyyfWyPmI{e(qb^3895i>tS<#c70iZAw&9G#;&^ zdWnKTl=7+ShLf{1CKs1fRYQ`bT)A?Uvx`fLV#vH4Vt#)Prnv$k1n9nbo5uhwvfcg3k#P;y{5ZB1k2tg?wlL2aPd>(TG`aY4+JRU-J;baKwY?!L$b zr5bG&b=zXJXS_M4KN>I^jd}j;6|-5zbUJ}I1K8h&fk_1^?fN`3oV_~Y&o9sU?swj& zU*uezO(7-bujO;9dlm^z+6 z`UG1wj5jwpownRKxWSWWF9@#T@uR1F^BW(aJsduN$@b0$^I6I6jZH$`=cB)Q%Erbv zyW=q`1nSA0w{P9%;m3!3`tVc!*>Cm8pifK^qsIvqna>y0={m(B}_zozhkiiQnc z08n88L z^Dg7jkU#wWKj7Zod%Sc1ZNB&W-$QxG^Nhv(Qncx-n)!6fY&PZc{F37$_dcrt03ZNK zL_t*Jmz+!{6nR0gmM1Td$xhE{+m@ZJZL~JnrU9?m-PvV-Z;y?GefIYD+1)?j=;aH> z+hdY`N=V|^R*=o_l_J#|+t!kenhfO~MV4^m>J{dT1?T6NEM^nZG-1#mP%akqdP8=1 zc6oL37@hW(Ww)FQZxDp(8YEq}TDogW%P5YCjjuEji@2(;;wjfknXQr~fNga2&5Xj9 ztAzkfEhX%W=Z9=>?r`(gO+NYb2`W{*cy+{$YZsJFOJ4LS@`5zY(TTygJ_EH|WC!i}3(>G%4)cz(p9oB@B2v8`+# z|5{7FX&bKY?lbPEoX={`F6Sgh@#=hz=~=RTgiHENtwMQ2Re65q=f6oY-s0)27ZQC< zAL|s(Z1ST|U-Hw(k9g;6?=kU)>Ee`oH?J@le2p)jK4l{}eE8uv+20%S*;&b~Nw|IU zD!l|s8<@A6g*8~GP?e=s8MAqXoiEU)$AgCt_~3*0dG_c9y)@(cja!_Yo-&)alx;wn zf^uOQ4hqJjg!$~8rc4=+hJ5g~cgRx1lV>j(j5D4*Ij8o0@;t*w%t?3ojgrjA#Ru7) zP@U-l2$!fvB%8aDp7oU)Vs}$WrxI}VnxI@a5il4GmZzVNAG5}c#0 z8-DWOAs;+>%5XTudCzETi|xH#27LjBt3@e-f@R6+=?TC6@BclI4-YA_jBwVHM&pZ< z=|aHoy1}+B;j>Q}_WNuMN8CBM#`_<9jijG3+8lBJ{dcHCOVb6FIMW-PB{+)@K3aX* zSV<&|`aODCLSwgBlqJ=C!R5SSb2I10^=o|e$zz%8jfYI=(u-w@|2nNjsi;$?z&k~2 zOPmX2naEx@t%V@kYgs1BqbALz5wuK@yXH}hTuRnY-PAZIN)*++=2w61SJ~M4nBV<_ z-{sRUKIQ&fZ%fc>9C_X&%X*+RWm!qti{Z~0ew%&B=4qExV;A7|K=ZrVDDe{a$rRX#lI3dVHfVB-GQkr5?k$Zpn z@;PayxRTvODREG;wxMlX@;sx+b9VPOan3QBOo8ejLS$X*YN-G^VbU5l21C9$nsW5w zjN5niFrxw4GA7MU4v&v${G3wf{NR&Avap~o19$G;AH(4Qljj8GsawmVXV0kTr{tN5UXCfJ7ZW~v`1$fWlO(}t%^&^YA20tdZ^d<} zBl8M|6!}(JA}&7OGpidZ$z~-+YqU|=)}+o>ljUzrIdBaVo_4$hJHSvKNwOjCQN5jHWqWCxHxHq)U{_g9N?X!-|w@#=g4vc zO#fj_{Pj&KY~Y3;{p1n-qK{5{eEje!c{ax6xr}6_hRViGo8|oU;VaTill6vFt;3`} zw92@g%}Fzbc80C(O{&&o4II9l;{7?jypP`8z>a$S)uU$|&l`L?L^;ooAG{z zJbN)=?oxjI@CcP8=rkqhM7#ubRCdrEUeRS$uczJXS&&wGsj=@mPFlpvI+ClrfNYpf z#X(MTw;bc>aET>G5#5qI4JNHS)r^2f#w^kFHb%Vv-hC9F)>bHt5Hy!^;qlpODOXkG_4)4902H3QpYdP)m;X8c z_TT>RcpqeDGZpe_*Qv$F?yv*V$Wt*m#DGaB`=qem;e#hJn!~4$@hE=b=RaiFPkHg| z6%R`f*%+e|+Q!n>4&Mfv+M?5hTet7Bw{w+VuTRnMQ8x{BQ^&uBC5aUz+iGnaMMGCv zSO)2Sw4HK7cv13d!QMx!k7y0Y)ri<%J4q&Y`ZRd-r@O6%e+)P zKYB?q7(-B)D7!P%2BS5uUXZwe)&XZ1^iod}EZg~juibu!k3au{@kXELCubzRAt87k zKb!E`qf=R2y&f$_E-dY%f~V0U2a^PZ7N8Pzq9K&%q>ojQ5NN%|shq@E($rv;#_5cp z61=MA@9pnljAq`R@YkO{f{@9{nf5Wc@THtmA`^_5xdzp#Y5AyDvsSXL1^@1?8}jbT zNf$?1y5eLB-iJUm30S7;P18iZ@zv*+;J!|x#+M>V)7bX+uQg@5PO^`MuMQ3sguj=D z8dF|kT*Gi<6O$!0ZG%>c-1lg%id8u6L20xF7yN72C)W~0fQ(2fFza8AfuA6O5YgyT zkyIN&mnHV9brMTi5zTw{;uYJ8p*I}xi@*NM{ICDp|H9KJPuV`$MMW->kHJa;qFE~9 zc9~q4q{*)fw9P^~b_NKRd-ra#y*uXkbcXdFr6Ex%);G%os^i8e)e)RS#6Lyex+zP3 z?bm*V-}9~8cRy;CF)7X~82U4AJ_~Z+YUKuue zDQ;`TeA>`7C3QKYE=%T<2}VI)ahdp#6`e|+5NraGTZ!py(0~>TbC1R= z^BT4z7n&m8(E%S6RpUgEu9sm{LEAKfOT=KcQXPx^LKRk$LtWrm;!tXdJF#{jyP%e3 z8O?eS(=zE0+k+^zS|H9zTHl>^9UFQj^DEg9aY((}oXa4`syTpO3p6MhFm6gzIU!G@ zH=wg!NF`0gF(`@Gp?z$*y4ZbHa`I}WmzZ79p)*a29HFjL8W*k(QUhsp19;@m5F$XXTy+ z5rFLV1{~~fb98b6h!A6I{SwXZf>wxYk7ed9heVoctZle@^?(mQ{E*-I?cb665@`v` zERL?rsa6|q4QG>QB*f#^irJ3$PMnjR75M7f{Fm}QCES;DO!&_0&hN_7XW=&t$T zDT+M0M#%(EAkHf*MP1j-rgM6|K7-+iv$IzOGJ1V6^PSJjXaeKWx<%)rT+#0r%xCSF z1K5)N9c70*Kv|(62+LTjfU+%*A3Wu~d$$R`=IHR8&Hj+xYdg%!ia-BPf5C8+u|3|P zN&9^I@N<$h;hnp;==Ti|KmMHe-@nhJFFvBJX8ihheu2l2KIfvev>E~pCMjeXHc3Gx z;x&iIE8)aDx{vaJ4S}ExUKx_mVnU54LC$t@sc|8Q#((fA<oSvN~==FXe}~Mx+tOwF42`-PUdAG53;Va#DIgQZm<@V zPPu;l3V-#ZpJH?ov!Rt#(R!&LV%Jl!vWRI$si0o3;KOf!i{JU}-zG6}DmylNmO(7& zwJce(u~k#Y$1F{l`NqgRWw0&ymdpea)l&2es#!_nCY+slcDDA}-y2buBVHbfKK^ua zf$|>f>L`7qmJ}b8CTmcKr-=upiie4gxEO>;Sbkl@PA!91^mf&ns%n@{XXM#HG{XYy zY;Uo-xrsuggwiylDr*uYLX|!QX0s`_wOAiGJ3VJ_cbDLiVgDqJqBGJA_)-Ats1uTH zyxtk>07@S`CQo>AHev7T0V=dSe|bUH8{?Hmn;zOEU<{`h4G9KJipR4k8y-J<#dp5* zHD-$vtrc0(r`E7gFmo-N{fyGKBuRnJBr?}`qd1L_v#3)om z8XYDWoDxzlS^}|gl9m!OS<8AMLD~;wMvWR}w20xc%APvMYvm>L()hS|qryNJyw>L= zu;) zIb?_g*Hk%NIYDD7dIcVq3ZGe;@MnMe1H7v!dO5BY+{1Pm<8r&HW#B>ufpnq|KvxQd zcsLS7&N?VB2O^OM90GLrGWtvf0$2905WL1@8E?PyF57*>`D}vIl3gvzIVLmsT4C~x zUaz+V@*Og$9+V~o9m_!p6kW#9w3P%tBYIZGXx@73E@|=y1Sib^yo=Ym%BmwwxojhL zIh1uRo4r0t!_Ax5(5Vb73m(W?AdK0TV##Hb5_DxkBVUvtX3_#3O1yHIM5CHOuq|29 zqnBt}Utw#<$#Koz-c@#Yhd95%$(dy~Et$^F<*-qrCY(ktnYArV(?SSQQ;bN5kY_1= z4IL~Z@Ik;W@85DpnC@^2B#EYJYLrSCkGGi4XFPfOl%M~lUqUHG)3nr8LtU5ji#|!B z84d*`Y-KMjw_;Q`NfQ}w<%K#Fi zi9(TdY<#8A5q$6WSHQk#e- zXEQ6)Csmqa@sfcq+1cB{^+wp}3X`TeUwrWeAN}Aj<a9H1vrkS{-dvHeMmDs^qXK5YypixPWkAC`)$P;256Nvsvi2#3^rpsroU z{lOR;Jay9$kiD!EO*NSiXz{*bI-8QESyTkcrO{&@S|`!8Sy5Lte%MDJkJ;)%MZ3eje)TmK!d5)7!- z5&+QA>yd~xEe%0bmtmO|R)lnxv|5oWi9f>X_AuVIk#`!W@BfU>FKjLPJ&DyC?%zMhbM)Vl1I0=me=3iU%HLD_WdCq z3QC67lv+8>gaAHRtZm7%jJm$SI?rS_$7C60SrVKj&obJ!rN~q8p2cD&ILyM(>-R}? z8VB7CI?*)oo@s4ps!G&cmEz^gV?O@)0k4kF`PrZSMQ&Wb!SSmL=~&x@;F@?4bfy04 zaOiNn4!7Fd+o#Agc6T<}-Pz#q`HWtY$gVP44nQkeX;_wxA^x3GzIPq&5VNu_GYwjv zpO5(Cyew(Tl3;SYlgeYUs5v@5!v@X9<~CWDF&c~*4hG8%J}A+O>-b%&lZ{#%+Gg$9 zc1jZ+CcBiVGIGjmB`VHIV&dQ7@Xk^-4Z}i_W{DiGX^Qop#)=tn+tlLy*)+7RrKuYU zx?1Fa*|; zn<&tMtQe3cDM~@Hp{1MP9K~=;6cwB$%?#EDiX_4LK+{?oE>$5aFL<)N5Z$OCUX>xb{;W17F$)V3>sqH# zbU)qkYV_LIR$MN5LEE-0%5u3miorlsEutc3k|bDbsUoWxttAG;ET#)s-5~gDjTqnk z&7gxLbv45*Wq)Urba9TykVG{Er8GBh-R2uV^RxWX|MLi)CgAOIZRq&BRrmVq0hu+a zp}4HpRcyQOm7pKjnqN^ce9X+0(oCmQcJ{B}yo*|E1Ik59QS=G6#AuOYuIh?3%Q30O zBneFeP1#2JfuR`XqTJCb8u>t$rewW7-~aw!GMz0*5)lVDJvrw6_uuEw{`3c!q*%%n zEpe`8S-iGy;!_TI#^W*5>6ERlP43>g&BM?BjPcmhdL^byyahb+rumKm1!0TlCjO_uiP4@RU}PMRiI@2Q%Krm3jPxp*2XO%l7au5H0v zj8+(dHX)^zVkL$uO84ZdiWq~sMqh4n1ph%ARy~*u~@|WySg50?NUF#;~#d{oy5S@ zRRkU8>%Ck{+qM#5jbU?Zll}dD27>|C3NN!)^cj!Gj5jvv5(DoYXJ@BWl}uvHrZdX2 zB+F8gG$qM$to33V%|Cz#w*D4SC>?N=fT9f=rD_rlp|$uR>Iqu6sGup5fVa(Zqq;}| z5HW^;(F&VHQen}fbsp<1+9ZU?Pg}xWd_sCuFIV%0aC*+ne`f zz4Z91%xwLdJ8W>BnzB52Vz$$?4ZU8EJjCbBa7;GHZk!8}TXm zlNDOO9>i9dqhdH3F&OkXKRe>;m3;>N0)j{Dbm>#+oQsuB*Qbq*khSO4!4xunwo>(V z&fy&-iGdhE@>C#<+FFA599+4^+xPA<7>=1ur<}}A304d@Mxzm@=NI$`eTJhUS`!J; zs}AeBaA8NMSh}P~xgF=kcU7TKQFqT6MXCkz$g+&8s%Ywl(Rf1+#pp$`SS(QSHFTVz z^d3UAQ@eBfHWwEc93DPnQ7+ir7}M+but8*|rJ(*tyvf<<&}IUp z@;=BWj|;JzTU!T}|NnUFI9Tf+{~SC$9Pa^RfTU&ppGLb9>B!E8EXv1ml|JxOKYyR~A<8^Y2% zGD!_ed3>m;>lxKz!eTL%**aS@ozJjdMqS#rW>L+VOfLzx=E}h?|MWM0g@5`Rzrya$ zCQVb(aW~hWS$ECra^YP@l%^@(JL2LP1RJx|ZM)1slSp-tMvN%2beLHO35ouGpss2zFT^P+ z&vVME;&L*f=oMVKa)se=MDT%&%L#4kDCZUPxhT8*qXJk!=FN0t>9>wS+mf~(<%OG} zQ;ky~62}zdW zB4IU6(`DJ%1-0etX|>z|QhKcYO-g7cqNpH-85x0|uh7*c!_4sF`EyQBPpHZTZEM-u z-eNQ!)9Vjb)^e%?t0l;ORiNrh*!AGPeyy+Hvo`{JSK0>&Yyuctog>`}HyrgMiwwU2vg9*l`x;puvR8X%CcrS z9Md24>GucJRZCSi4ElW%t@-@HL;mCs|Cp+*xPJXQMNxnk6<3pGSoakrX_wdf{CqvrH#z$0VaY0og=s= zfVU8WkPL$(NkpAefI>^_g;<+q8K5x=g4PkFmqw-5>!;*8@c#Pe*YT>a3P5lEdwub) zzkSsv{rg_?%U@g7zujqH6a`Jw(3P2Qwz9iLuDpt5)pZOn@VjDB000)8NklimSsq~yk(x9Am7p4eGhtI@ut^_H#+pki0Cvw;g;>DtL~FYoK> zdY1R4%ecCd7PW*FFG?Fu_mrhw7;I}h zZS01typTN4iQ_tc5MT_9h9d^U5!pDU5!aZRo8yf)UMC%oY0u7(=NX;d4jb!h2)B7| zZf`L&-y*I@l{Ua3dSK!ppl>Q>=G1Nx8o@)+Ht(0Okr#$rH9>JcryCk}#^-qPs$!g# zjQbgJ9H5lXc${0N0g`5;PT_6{#q?>!|AE;2s3VuxGiL@~jRSwI2b(uKVMZCxh7jv=dvnNij z62}3(ZkN$;KpflOUOH(}t+CyLw83a;Yh8_NBI^g_rQzX+AK}SA{W_07{zrWLXMU20 zfBX!|poIk!S?{oaInwn z@nalWT%en1lnOv9L{YruUbENC&XDFvtFZ^pJ!*U zN4wdY)XmP%&Jo2id7hIbBa%_VXf(2-fDSyArF9QI&tsg}CNE(e{fL*4Pu#?VR&2J; z)V92fqJW~zF&s3E_5(>e9y1sYCp|k$Z7D#y)Fk6E?N*CMy@67;L(*QSL#^K6)~#D) zdCuyIRnja)YlEjevZAm`vTwO{?ts8#6<{nUFil@!3bIerC=MEXlm{h9U}0x9Z;n4yp(C({-5B9iU^M|6KO54h1*{x7 zLfCAw(dn_cIFG>X_}WkuCH?&YLdXODnlqAB`N*_8B@mO?jzLo?#8yagIyNbUaGbmY zCOegjh9v|Sg{EGQ@RiRf86%}fGEPaxDNz(VZlAq+xRS-9v{e$NHk5^=)ok;J|NW0y zJ#`jTn}7W~pXUe9KF?E6eTOf6;d3l5HlfG~{0i}Vq}h=9g&CHY7rFfE4L8Zcp-$~K zb%Q`pB)#p1@3FD9%j5s!k2!z#C`Xr%vAnXv>d95MUbu=^i{A1Z4}5ZqxHRUV6wA%) z1o650P8)Ey*EB5(Jekvo>&*KRIaaT~*=|y+HSzrbTnDRhYLjZc{T`#yh#-v6m0rIw z)+*I5|Vz(5#91iptTD&(&xbc(sf1?J{wDO~)^ z_dL*s(QwFSmNC4T!P=HP)ockjetgkRTr-vt7cXMcX(0%TJx+bC)kM&LqG3k5BWpCvS53wIL6l zkX(3Rm5VQLu)NY{Z>!|g={6giBi^{V&O?tL=h6>1Idflwg=UT2jfBrUvdpbFhJ50o zNBQ0V_6*xaKxuq1C5jSha*WiJ(gr$(!AjFgIn|&*PIis=Iu46(y_a)MpW`s3W;eHL z^KeDv+E#uFEM-IMf;3NwqL5^mQKnWVDRD*qnTFIz z@-#yR0YMzmY`1AP+hm1iYipPF%}sW9b}jjJG_tj<+HQb(W=X+X7q;>sOEFG@Da{07 z5!eo6p?A>CLs(IPD6r)}MtF?JnUnMuL@FT9OLAkV&&{&1yhsrH#I*=dDMo_45;LP+QmybyMHoc9e075lo?9ZQd2C(nu;7=heBd}i^8`=+ z>0j{S`yXau$)o;bOI*HuiAOHX^RthhqSx6XJ|A=L!eA-K=v7@ zW29<1DI1%y#8`Jk8@ucJF6dZgKo2uGZ->ARi*+4ll-|v2)2`(0$5ij@3CcQP&}*Y@ z>B(DAa%Hfp&v1`a24u=$0=|?8;h{~2SES4ckGc?SZ*H@5eS_xQQBK~|AQ=f{5HlQ< zbbI@Z`d#9<#b~r`iK|Z4!w9QChB{~#Tompmo+!dH5m~HI2RJv@!6hXWLU|OXL`kbJ zrpppt8gf$F%~|fh|3Ne&Qb;t9va&Oq+YKR*JDaulI1CJEuvnJ>1ADJW*W{F6@-DutvBDK*X>c{wv0&5 zL8I0nNrtvURzn=upnS&|n42tPK-!x|3qdEY@%@GO6SO}_TnzZ2{3||kZoqtQxFMGK z#`6V@pvA>kZm_&Khw^={-yG0v&*Dd#Ob;0*4SYZ5;)}2F{(I|;2ZG4+xpsApbEi+R zdVG}|*EZSTPcSHUdxBTiwphI9IGOelu7$fO3J2kBo2*g`bXiVXrW<3K>s3bV_W0AC z(9oR%{_l3Y9lE;HId4C1`tNOF^MPw-=@NI!oK}ncVBy=kaHn+OTr}IMNT7uz5G6Cd zp;3=%)?3i1fvhv??6WmYQ2q=%-5etoM;2z8X)iL|eg%yrcdn?A7Wr70t#C%GD#8}v z8X;Grf3{@HA$cJVVqd1D%xwqu)HrS*intze>eOk@pT9t_*XQeh{%1V!;KMXqH3X8q zy{~QJj%WSM~&}ua3bW_H8fv3d8MXct2dLD%_lenN%KHHsL(zU(~t7scf7RtsTYxS5k zFBunxd^9Az{yOWM8_dnkk*2#SG@gXhCsr|@VtxGWVBwdA2#P(IrtB(r&kDG#eCY&cfU*=F|zU z=3}m3eVOg;ZT9;;7x)v@>rIXwJx0CJV6@*OsztQwb&514@&bx+2L5{xG&I$XCp0=3 z(hFvh!3u5J0Xzbe()J)KN~F=;+8N;aGxRUMiRUSltTVr$S>L=xs~z*u$A5|!uCB4$ zsdMqk7x~nu9^u)`d+c^I^jyk!|JM~Bdhj%@m2-Ul@n<-`y2SN0!^0%^sOb#<5hZ~o}jo*7c?oQvw8e6cz(gTz>Eqr&74RdiQ z`(YfU`z2c2Op$a6nL=1)%-G~a$$*;Y(TG~))X_wYdjq=N5ytlsY8GjHOzE?*bPQ9R z$K?A+7Z=ke!v=tDX;`TZd46yMShBQzBAmNrsyI)nosN`t@e)B0#6)3CyVYQEex8Me z1+*@C{<-HkdTf<*=gy!!xc1r`99{kZ-EPkX?}hEBh>!9;!bso?AEQI!aE8Yo`%V7- zKl}$=z4jWfyz~-F3kyVkh$lVPHZ~XyPXmI%U`Xf(_)1Z)#f-Crq9{0dYL%6vOI&^J z243J}BNA>NoIYHIl!O7wF*EHtrp)-(x4zDU54@kh_2`HB$&WVZ?0u2H{O)u3VGZp9 z=Qgo&P@)4CbyuFGHnv!LzR_ZSzHNz~Mleoooot$o8D|Met|^f;W@b=Qa^t8Nwb8#y&byUuItKes}l|~%Led}%2K2%d80fp*w|W|G%A^$ zZ6SpqFD(Jv^KBcpFbr(RFBOtxW70ISO0AwE8T4t@8nn+G=ho}5^5%`JC{J*FWfrLv z$tYv_$TG)|AEVi7)7k5=zu&b)cyhkKyT!M^^Otk;)fK%$5WE3ntl@Qbb(G`#H2vAihEVT z@52n)I~k$r8qq$#Gfh3-;Gq_2qLn6l`R<(fi+=X<<#>1AGj{S7W$xR+L=iSK#rb@%A? zI_&Q5u-n-o&uqhtqR3r#xe^ADltm@kG!?g$g3!0_`r5`CMi}mU-#uhwZDoz5XRB{K zpTPI<>UC71Xf+#nN>PgfsK+G3efB%M+`MsxH0dIRp)XT<`#pNSKAX2%+;t`e5BPmB;cM4O1vlW376iWsE_M6Cu|Xp~emq86nYK-jeCPiJ^hokAEQKVUc-qq7WO zxr%)(1p|bQ$7uUSE1JaZ#^K$J+l|?s-aG91I~{iz3Og)jX8%g6PDng6EeV5X85--V$oHEI&3B_v}52}0Q{p__*wsu80Id_|x-2gZ%lpKTmpK!O6Co^< zKuUrj0<25Bcx0K#^+bKw2+ZXqkwy|^3MEU5V2n|Mf*JOU7*7;dvquYx954!@5~R_{ zJhU+inSt@3P$01xC>2vWNs(LwCI_4-oiPXzVSo}tsojMI2jOiXc|!YeE6j)k?$KM_ zvUgW}FpZif=e{kAISu)zYZBk-xWf?Mj~X;4?$va_*Gwf@>@f;s%F5AqSu8pA8SWg$ zDo51xfS|ulK?i9{YH=Ms91+F}liThzrAaZ;%F)ENkm0yXI?M??OH|DB1nKAzd7dL> z2EvjVkqYIxDgo)^g$<7)#iym`QI$eFZ0mD zKhCfH#;Sh8*s%Q< zvkc$!+*}#5G;`~(TEB3>LU3xk&Zr6p#SB#m6|AkTvD4`?H@Cpz!XiRg1n4QnI4zJt zNF$D^#{r>&&8=O&@}IxRcfR%Klx2qRTQqL48ez6`x&0!7Drr=r5h$aO6qLoterIEh zIdS3ypZ)A-x#ymH-qp>0cibI!$KCNaVF+W4`O=rZbk}&@9e2mw@&DZr=Dh@l?vA_T f?zlVt295s*OL)_z)3B@<00000NkvXXu0mjfRf_TO literal 0 HcmV?d00001 diff --git a/docs/documentation/docs/controls/PropertyEditor.md b/docs/documentation/docs/controls/PropertyEditor.md new file mode 100644 index 00000000..e4ffd891 --- /dev/null +++ b/docs/documentation/docs/controls/PropertyEditor.md @@ -0,0 +1,49 @@ +# PropertyEditor control + +This control allows the user to edit the webpart properties in JSON. It can also be used to export properties of a webpart and later import them again to a similar webpart on a different page. If the user clicks 'export' a file named 'webpartproperties.json' is presented for download. The same file can be uploaded to a new instance of the same webpart on for instance another site or page. + +**PropertyEditor rendering in property pane** + +![PropertyEditor rendering](../assets/propertyeditorinpane.png) + + +**PropertyEditor rendering when expanded** + +![PropertyEditor rendering](../assets/propertyeditorexpanded.png) + +## How to use this control in your solutions + +1. Check that you installed the `@pnp/spfx-property-controls` dependency. Check out The [getting started](../#getting-started) page for more information about installing the dependency. +2. Import the following modules to your component: + +```TypeScript +import { PropertyWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyEditor'; +``` + +3. Create a new property for your web part, for example: + +```TypeScript +export interface IPropertyControlsTestWebPartProps { + toggleInfoHeaderValue: boolean; +} +``` + +4. Add the custom property control to the `groupFields` of the web part property pane configuration: + +```TypeScript + PropertyEditor({ + webpart: this, + key: 'propertyEditor' + }) +``` + +## Implementation + +The `PropertyEditor` control has the following properties: + +| Property | Type | Required | Description | +| ---- | ---- | ---- | ---- | +| webpart | BaseClientSideWebPart | yes | The webpart, which is in principle the current webpart, of which you want to be able to edit the properties from | + + +![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyEditor) diff --git a/docs/documentation/docs/controls/PropertyWebPartInformation.md b/docs/documentation/docs/controls/PropertyWebPartInformation.md new file mode 100644 index 00000000..90ecf839 --- /dev/null +++ b/docs/documentation/docs/controls/PropertyWebPartInformation.md @@ -0,0 +1,63 @@ +# PropertyWebPartInformation control + +This control allows you to specify a description, a 'read more' link, and an optional embedded video + +**PropertyWebPartInformation rendering** + +![WebPart Information](../assets/webpartinformation.png) + + +## How to use this control in your solutions + +1. Check that you installed the `@pnp/spfx-property-controls` dependency. Check out The [getting started](../#getting-started) page for more information about installing the dependency. +2. Import the following modules to your component: + +```TypeScript +import { PropertyWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyWebPartInformation'; +``` + +3. Create a new property for your web part, for example: + +```TypeScript +export interface IPropertyControlsTestWebPartProps { + toggleInfoHeaderValue: boolean; +} +``` + +4. Add the custom property control to the `groupFields` of the web part property pane configuration: + +```TypeScript + PropertyWebPartInformation({ + description: `This is a demo webpart, used to demonstrate all the PnP property controls`, + moreInfoLink: `https://sharepoint.github.io/sp-dev-fx-property-controls/`, + videoProperties: { + embedLink: `https://www.youtube.com/embed/d_9o3tQ90zo`, + properties: { allowFullScreen: true} + }, + key: 'webPartInfoId' + }) +``` + +## Implementation + +The `PropertyWebPartInformation` control has the following properties: + +| Property | Type | Required | Description | +| ---- | ---- | ---- | ---- | +| description | string | yes | Description content - any HTML | +| moreInfoLink | string | no | A URL providing optional additional information | +| moreInfoLinkTarget | string | no | An optional target for the link. Defaults to '_blank' | +| videoProperties | IVideoEmbedProperties | no | A video properties object specifying an optionally embedded video | + +Class `IVideoEmbedProperties` + +| Property | Type | Required | Description | +| ---- | ---- | ---- | ---- | +| embedLink | string | yes | A link to an embeddable video. The video will be embedded in an iframe. See the example above for details | +| width | number | no | optional width of the iframe | +| height | number | no | optional height of the iframe | +| properties | object | no | additional properties to set on the iframe element | + + + +![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyWebPartInformation) diff --git a/docs/documentation/docs/index.md b/docs/documentation/docs/index.md index ccd0693e..0376fde7 100644 --- a/docs/documentation/docs/index.md +++ b/docs/documentation/docs/index.md @@ -40,7 +40,8 @@ The following controls are currently available: - [PropertyFieldTermPicker](./controls/PropertyFieldTermPicker) (Property pane managed metadata term selector) - [PropertyFieldMultiSelect](./controls/PropertyFieldMultiSelect) (Property pane field which allows multi-value selection) - [PropertyFieldNumber](./controls/PropertyFieldNumber) (Property pane field which allows only number values) - +- [PropertyWebPartInformation](./controls/PropertyWebPartInformation) (Property pane webpart information panel) +- [PropertyEditor](./controls/PropertyEditor) (Property pane control that allows raw editing, export and import of webpart properties) The following controls are extended controls that show a callout next to the label - [PropertyFieldButtonWithCallout](./controls/PropertyFieldButtonWithCallout) (Property button field with callout) From 28a92e3287ee4d742eeb152a670bde88248d3967 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Oct 2018 21:12:15 +0100 Subject: [PATCH 23/34] Added localization --- src/loc/en-us.js | 4 ++++ src/loc/fr-fr.js | 4 ++++ src/loc/mystrings.d.ts | 8 ++++++++ src/loc/nl-nl.js | 4 ++++ 4 files changed, 20 insertions(+) diff --git a/src/loc/en-us.js b/src/loc/en-us.js index aa502236..eea01444 100644 --- a/src/loc/en-us.js +++ b/src/loc/en-us.js @@ -1,5 +1,9 @@ define([], function() { return { + ApplyButtonLabel: "Apply", + ImportButtonLabel: "Import", + ExportButtonLabel: "Export", + JsonFileRequiredMessage: "Please upload a json file", SaveButtonLabel: "Save", CancelButtonLabel: "Cancel", PeoplePickerSuggestedContacts: "Suggested people", diff --git a/src/loc/fr-fr.js b/src/loc/fr-fr.js index 128828d4..a8e69e83 100644 --- a/src/loc/fr-fr.js +++ b/src/loc/fr-fr.js @@ -1,5 +1,9 @@ define([], function() { return { + ApplyButtonLabel: "Apply", + ImportButtonLabel: "Import", + ExportButtonLabel: "Export", + JsonFileRequiredMessage: "Please upload a json file", SaveButtonLabel: "Sauvegarder", CancelButtonLabel: "Annuler", PeoplePickerSuggestedContacts: "Personnes suggérées", diff --git a/src/loc/mystrings.d.ts b/src/loc/mystrings.d.ts index a7f1644c..740a0da9 100644 --- a/src/loc/mystrings.d.ts +++ b/src/loc/mystrings.d.ts @@ -1,5 +1,7 @@ declare interface IPropertyControlStrings { + + DescriptionLabel: string; MoreInfoLabel: string; @@ -87,6 +89,12 @@ declare interface IPropertyControlStrings { CollectionDataItemShowErrorsLabel: string; CollectionDataItemFieldRequiredLabel: string; InvalidUrlError: string; + + // Property Editor + ApplyButtonLabel: string; + ImportButtonLabel: string; + ExportButtonLabel: string; + JsonFileRequiredMessage: string; } declare module 'PropertyControlStrings' { diff --git a/src/loc/nl-nl.js b/src/loc/nl-nl.js index 2e884579..69a49d6b 100644 --- a/src/loc/nl-nl.js +++ b/src/loc/nl-nl.js @@ -1,5 +1,9 @@ define([], function() { return { + ApplyButtonLabel: "Bevestig", + ImportButtonLabel: "Importeer", + ExportButtonLabel: "Exporteer", + JsonFileRequiredMessage: "Alleen JSON files toegestaan", SaveButtonLabel: "Opslaan", CancelButtonLabel: "Annuleren", PeoplePickerSuggestedContacts: "Voorgestelde personen", From b2e24ac1c85917498f365cb1761d5ab5ab350f58 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Oct 2018 21:13:00 +0100 Subject: [PATCH 24/34] Added property editor control --- src/PropertyEditor.ts | 1 + .../propertyEditor/IPropertyEditor.ts | 21 +++ .../propertyEditor/IPropertyEditorHost.ts | 15 ++ .../propertyEditor/PropertyEditor.ts | 53 ++++++ .../PropertyEditorHost.module.scss | 5 + .../propertyEditor/PropertyEditorHost.tsx | 177 ++++++++++++++++++ src/propertyFields/propertyEditor/index.ts | 4 + 7 files changed, 276 insertions(+) create mode 100644 src/PropertyEditor.ts create mode 100644 src/propertyFields/propertyEditor/IPropertyEditor.ts create mode 100644 src/propertyFields/propertyEditor/IPropertyEditorHost.ts create mode 100644 src/propertyFields/propertyEditor/PropertyEditor.ts create mode 100644 src/propertyFields/propertyEditor/PropertyEditorHost.module.scss create mode 100644 src/propertyFields/propertyEditor/PropertyEditorHost.tsx create mode 100644 src/propertyFields/propertyEditor/index.ts diff --git a/src/PropertyEditor.ts b/src/PropertyEditor.ts new file mode 100644 index 00000000..75aefc11 --- /dev/null +++ b/src/PropertyEditor.ts @@ -0,0 +1 @@ +export * from './propertyFields/propertyEditor'; diff --git a/src/propertyFields/propertyEditor/IPropertyEditor.ts b/src/propertyFields/propertyEditor/IPropertyEditor.ts new file mode 100644 index 00000000..c70693d5 --- /dev/null +++ b/src/propertyFields/propertyEditor/IPropertyEditor.ts @@ -0,0 +1,21 @@ +import { IPropertyPaneCustomFieldProps, BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; + +/** + * Public properties of the PropertyFieldSpinButton custom field + */ +export interface IPropertyEditorProps { + + /** + * This current webpart. Usually 'this'. + */ + webpart: any; + + /** + * An UNIQUE key indicates the identity of this control + */ + key: string; +} + + +export interface IPropertyEditorPropsInternal extends IPropertyEditorProps, IPropertyPaneCustomFieldProps { +} \ No newline at end of file diff --git a/src/propertyFields/propertyEditor/IPropertyEditorHost.ts b/src/propertyFields/propertyEditor/IPropertyEditorHost.ts new file mode 100644 index 00000000..be925abd --- /dev/null +++ b/src/propertyFields/propertyEditor/IPropertyEditorHost.ts @@ -0,0 +1,15 @@ +/** + * PropertyFieldColorPickerHost properties interface + */ +export interface IPropertyEditorHostProps { + webpart: any; +} + +/** + * PropertyFieldColorPickerHost state interface + */ +export interface IPropertyEditorHostState { + errorMessage?: string; + openPanel? : boolean; + propertiesJson?: string; +} diff --git a/src/propertyFields/propertyEditor/PropertyEditor.ts b/src/propertyFields/propertyEditor/PropertyEditor.ts new file mode 100644 index 00000000..a0634204 --- /dev/null +++ b/src/propertyFields/propertyEditor/PropertyEditor.ts @@ -0,0 +1,53 @@ +import * as React from 'react'; +import * as ReactDom from 'react-dom'; +import { + IPropertyPaneField, + PropertyPaneFieldType +} from '@microsoft/sp-webpart-base'; +import { + IPropertyEditorProps, + IPropertyEditorPropsInternal +} from './IPropertyEditor'; +import { IPropertyEditorHostProps } from './IPropertyEditorHost'; +import PropertyEditorHost from './PropertyEditorHost'; + +class PropertyEditorBuilder implements IPropertyPaneField { + + //Properties defined by IPropertyPaneField + public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; + public targetProperty: string; + public properties: IPropertyEditorPropsInternal; + + private elem: HTMLElement; + + public constructor(_properties: IPropertyEditorProps) { + this.properties = { + key: _properties.key, + webpart: _properties.webpart, + onRender: this.onRender.bind(this) + }; + } + + public render(): void { + if (!this.elem) { + return; + } + + this.onRender(this.elem); + } + + private onRender(elem: HTMLElement, ctx?: any, changeCallback?: (targetProperty?: string, newValue?: any) => void): void { + if (!this.elem) { + this.elem = elem; + } + + const element: React.ReactElement = React.createElement(PropertyEditorHost, { + webpart: this.properties.webpart + }); + ReactDom.render(element, elem); + } +} + +export function PropertyEditor(properties: IPropertyEditorProps): IPropertyPaneField { + return new PropertyEditorBuilder(properties); +} diff --git a/src/propertyFields/propertyEditor/PropertyEditorHost.module.scss b/src/propertyFields/propertyEditor/PropertyEditorHost.module.scss new file mode 100644 index 00000000..a504d99e --- /dev/null +++ b/src/propertyFields/propertyEditor/PropertyEditorHost.module.scss @@ -0,0 +1,5 @@ +.actions { + button:first-child { + margin-right: 16px; + } +} \ No newline at end of file diff --git a/src/propertyFields/propertyEditor/PropertyEditorHost.tsx b/src/propertyFields/propertyEditor/PropertyEditorHost.tsx new file mode 100644 index 00000000..aab4b935 --- /dev/null +++ b/src/propertyFields/propertyEditor/PropertyEditorHost.tsx @@ -0,0 +1,177 @@ +import * as React from 'react'; +import { IPropertyEditorHostProps, IPropertyEditorHostState } from './IPropertyEditorHost'; +import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel'; +import { PrimaryButton, DefaultButton, IButtonProps, IconButton } from 'office-ui-fabric-react/lib/Button'; +import AceEditor from 'react-ace'; +import { set } from '@microsoft/sp-lodash-subset'; +import * as telemetry from '../../common/telemetry'; +import styles from './PropertyEditorHost.module.scss'; +import * as strings from 'PropertyControlStrings'; + + +export default class PropertyEditorHost extends React.Component { + + private previousValue: string; + private cancel: boolean = true; + private fileRef: HTMLInputElement = null; + + constructor(props: IPropertyEditorHostProps, state: IPropertyEditorHostState) { + super(props); + + telemetry.track('PropertyWebPartInformation', {}); + + this.state = { + propertiesJson: this.getProperties(), + errorMessage: undefined, + }; + + this.onOpenPanel = this.onOpenPanel.bind(this); + this.onClosePanel = this.onClosePanel.bind(this); + } + + private setFileRef = (element: HTMLInputElement) => { + this.fileRef = element; + } + + private getProperties = (): string => { + let props = {}; + props = this.props.webpart.properties; + return JSON.stringify(props); + } + + /** + * Called when the save button gets clicked + */ + private onSave = (): void => { + const newProperties = JSON.parse(this.state.propertiesJson); + for (let propName in newProperties) { + set(this.props.webpart.properties, propName, newProperties[propName]); + if (typeof this.props.webpart.properties[propName].onChange !== 'undefined' && this.props.webpart.properties[propName].onChange !== null) { + this.props.webpart.properties[propName].onChange(propName, newProperties[propName]); + } + } + this.props.webpart.render(); + this.props.webpart.context.propertyPane.refresh(); + this.setState((current) => ({ ...current, openPanel: false })); + } + + /** + * Called when the properties editor changes + */ + private onChange = (newValue: string, event?: any): void => { + this.setState((current) => ({ ...current, propertiesJson: newValue })); + } + + /** + * Called to open the editor panel + */ + private onOpenPanel(): void { + + // Store the current code value + this.previousValue = JSON.stringify(this.props.webpart.properties, null, '\t'); + this.setState((current) => ({ ...current, propertiesJson: this.previousValue })); + this.cancel = true; + + this.setState({ + openPanel: true, + }); + } + + /** + * Close the panel + */ + private onClosePanel(): void { + this.setState((crntState: IPropertyEditorHostState) => { + const newState: IPropertyEditorHostState = { + openPanel: false, + }; + + // Check if the property has to be reset + if (this.cancel) { + newState.propertiesJson = this.previousValue; + } + + return newState; + }); + } + + /** + * Called when clicking 'Download' + */ + private onDownload = (): void => { + + const a = document.createElement("a"); + document.body.appendChild(a); + a.setAttribute("style", "display: none"); + const json = JSON.stringify(JSON.parse(this.state.propertiesJson), null, '\t'); // remove indentation + const blob = new Blob([json], { type: "octet/stream" }); + const url = window.URL.createObjectURL(blob); + a.href = url; + a.download = "webpartproperties.json"; + a.click(); + window.URL.revokeObjectURL(url); + } + + /** + * Called when the changed event occurs on the file upload control + */ + private onUpload = (): void => { + if (this.fileRef.files.length > 0 && this.fileRef.files[0].type === "application/json") { + let fileReader: FileReader = new FileReader(); + fileReader.readAsText(this.fileRef.files[0]); + fileReader.onload = () => { + let jsonString = fileReader.result as string; + let json = JSON.parse(jsonString); // normalize as an object + jsonString = JSON.stringify(json, null, '\t'); // and format as an indented string again + this.setState((current) => ({ ...current, propertiesJson: jsonString })); + }; + } else { + alert(strings.JsonFileRequiredMessage); + } + } + + public render(): JSX.Element { + return ( +
+ Edit Properties + ( +
+
+
+
+ + + +
+
+ + + + + { this.fileRef.click(); }} /> +
+
+
+
+ )}> + + +
+
+ ); + } +} diff --git a/src/propertyFields/propertyEditor/index.ts b/src/propertyFields/propertyEditor/index.ts new file mode 100644 index 00000000..7f389097 --- /dev/null +++ b/src/propertyFields/propertyEditor/index.ts @@ -0,0 +1,4 @@ +export * from './IPropertyEditor'; +export * from './PropertyEditor'; +export * from './IPropertyEditorHost'; +export * from './PropertyEditorHost'; \ No newline at end of file From a8f1cef643bc34a2d038fddc61f6967cee412dec Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Oct 2018 21:13:28 +0100 Subject: [PATCH 25/34] simplified constructed and removed unneeded targetproperty parameter --- .../webPartInformation/PropertyWebPartInformation.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts b/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts index 8a61d737..cebf2708 100644 --- a/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts +++ b/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts @@ -10,17 +10,14 @@ import { IPropertyWebPartInformationHostProps } from './IPropertyWebPartInformat import PropertyWebPartInformationHost from './PropertyWebPartInformationHost'; class PropertyWebPartInformationBuilder implements IPropertyPaneField { - //Properties defined by IPropertyPaneField - public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; public targetProperty: string; + public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; public properties: IPropertyWebPartInformationPropsInternal; private elem: HTMLElement; - - public constructor(_targetProperty: string, _properties: IPropertyWebPartInformationProps) { - this.targetProperty = _targetProperty; + public constructor(_properties: IPropertyWebPartInformationProps) { this.properties = { key: _properties.key, moreInfoLink: _properties.moreInfoLink, @@ -53,6 +50,6 @@ class PropertyWebPartInformationBuilder implements IPropertyPaneField { - return new PropertyWebPartInformationBuilder(targetProperty, properties); +export function PropertyWebPartInformation(properties: IPropertyWebPartInformationProps): IPropertyPaneField { + return new PropertyWebPartInformationBuilder(properties); } From a94cb662ac8fb96417ee10094de3928f838be309 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Oct 2018 21:14:07 +0100 Subject: [PATCH 26/34] Added property editor to property pane --- .../propertyControlsTest/PropertyControlsTestWebPart.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index 1aed0591..1d27ac42 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -36,7 +36,7 @@ import { PropertyFieldOrder } from '../../PropertyFieldOrder'; import { orderedItem } from './components/OrderedItem'; import { PropertyFieldSwatchColorPicker, PropertyFieldSwatchColorPickerStyle } from '../../PropertyFieldSwatchColorPicker'; import { PropertyWebPartInformation } from '../../propertyFields/webPartInformation'; -import { RawPropertyEditor } from '../../propertyFields/rawPropertyEditor/RawPropertyEditor'; +import { PropertyEditor } from '../../propertyFields/propertyEditor/PropertyEditor'; /** * Web part that can be used to test out the various property controls @@ -133,7 +133,7 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPartdemo webpart, used to demonstrate all the PnP property controls`, moreInfoLink: `https://sharepoint.github.io/sp-dev-fx-property-controls/`, videoProperties: { @@ -535,10 +535,9 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart Date: Wed, 31 Oct 2018 16:03:56 +0100 Subject: [PATCH 27/34] Renamed to better reflect it's usage --- ...ditor.md => PropertyPanePropertyEditor.md} | 14 ++--- ...n.md => PropertyPaneWebPartInformation.md} | 12 ++--- docs/documentation/docs/index.md | 4 +- ...itor.ts => IPropertyPanePropertyEditor.ts} | 4 +- ....ts => IPropertyPanePropertyEditorHost.ts} | 4 +- .../propertyEditor/PropertyEditor.ts | 53 ------------------- .../PropertyPanePropertyEditor.ts | 53 +++++++++++++++++++ ...ropertyPanePropertyEditorHost.module.scss} | 0 ...tsx => PropertyPanePropertyEditorHost.tsx} | 12 ++--- src/propertyFields/propertyEditor/index.ts | 8 +-- ....ts => IPropertyPaneWebPartInformation.ts} | 4 +- ...=> IPropertyPaneWebPartInformationHost.ts} | 4 +- ...n.ts => PropertyPaneWebPartInformation.ts} | 16 +++--- ...=> PropertyPaneWebPartInformationHost.tsx} | 6 +-- .../webPartInformation/index.ts | 8 +-- .../PropertyControlsTestWebPart.ts | 8 +-- 16 files changed, 105 insertions(+), 105 deletions(-) rename docs/documentation/docs/controls/{PropertyEditor.md => PropertyPanePropertyEditor.md} (80%) rename docs/documentation/docs/controls/{PropertyWebPartInformation.md => PropertyPaneWebPartInformation.md} (88%) rename src/propertyFields/propertyEditor/{IPropertyEditor.ts => IPropertyPanePropertyEditor.ts} (64%) rename src/propertyFields/propertyEditor/{IPropertyEditorHost.ts => IPropertyPanePropertyEditorHost.ts} (65%) delete mode 100644 src/propertyFields/propertyEditor/PropertyEditor.ts create mode 100644 src/propertyFields/propertyEditor/PropertyPanePropertyEditor.ts rename src/propertyFields/propertyEditor/{PropertyEditorHost.module.scss => PropertyPanePropertyEditorHost.module.scss} (100%) rename src/propertyFields/propertyEditor/{PropertyEditorHost.tsx => PropertyPanePropertyEditorHost.tsx} (91%) rename src/propertyFields/webPartInformation/{IPropertyWebPartInformation.ts => IPropertyPaneWebPartInformation.ts} (89%) rename src/propertyFields/webPartInformation/{IPropertyWebPartInformationHost.ts => IPropertyPaneWebPartInformationHost.ts} (57%) rename src/propertyFields/webPartInformation/{PropertyWebPartInformation.ts => PropertyPaneWebPartInformation.ts} (59%) rename src/propertyFields/webPartInformation/{PropertyWebPartInformationHost.tsx => PropertyPaneWebPartInformationHost.tsx} (83%) diff --git a/docs/documentation/docs/controls/PropertyEditor.md b/docs/documentation/docs/controls/PropertyPanePropertyEditor.md similarity index 80% rename from docs/documentation/docs/controls/PropertyEditor.md rename to docs/documentation/docs/controls/PropertyPanePropertyEditor.md index e4ffd891..e88b53ec 100644 --- a/docs/documentation/docs/controls/PropertyEditor.md +++ b/docs/documentation/docs/controls/PropertyPanePropertyEditor.md @@ -1,15 +1,15 @@ -# PropertyEditor control +# PropertyPanePropertyEditor control This control allows the user to edit the webpart properties in JSON. It can also be used to export properties of a webpart and later import them again to a similar webpart on a different page. If the user clicks 'export' a file named 'webpartproperties.json' is presented for download. The same file can be uploaded to a new instance of the same webpart on for instance another site or page. -**PropertyEditor rendering in property pane** +**PropertyPanePropertyEditor rendering in property pane** -![PropertyEditor rendering](../assets/propertyeditorinpane.png) +![PropertyPanePropertyEditor rendering](../assets/propertyeditorinpane.png) -**PropertyEditor rendering when expanded** +**PropertyPanePropertyEditor rendering when expanded** -![PropertyEditor rendering](../assets/propertyeditorexpanded.png) +![PropertyPanePropertyEditor rendering](../assets/propertyeditorexpanded.png) ## How to use this control in your solutions @@ -17,7 +17,7 @@ This control allows the user to edit the webpart properties in JSON. It can also 2. Import the following modules to your component: ```TypeScript -import { PropertyWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyEditor'; +import { PropertyWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyPanePropertyEditor'; ``` 3. Create a new property for your web part, for example: @@ -31,7 +31,7 @@ export interface IPropertyControlsTestWebPartProps { 4. Add the custom property control to the `groupFields` of the web part property pane configuration: ```TypeScript - PropertyEditor({ + PropertyPanePropertyEditor({ webpart: this, key: 'propertyEditor' }) diff --git a/docs/documentation/docs/controls/PropertyWebPartInformation.md b/docs/documentation/docs/controls/PropertyPaneWebPartInformation.md similarity index 88% rename from docs/documentation/docs/controls/PropertyWebPartInformation.md rename to docs/documentation/docs/controls/PropertyPaneWebPartInformation.md index 90ecf839..59f49d96 100644 --- a/docs/documentation/docs/controls/PropertyWebPartInformation.md +++ b/docs/documentation/docs/controls/PropertyPaneWebPartInformation.md @@ -1,8 +1,8 @@ -# PropertyWebPartInformation control +# PropertyPaneWebPartInformation control This control allows you to specify a description, a 'read more' link, and an optional embedded video -**PropertyWebPartInformation rendering** +**PropertyPaneWebPartInformation rendering** ![WebPart Information](../assets/webpartinformation.png) @@ -13,7 +13,7 @@ This control allows you to specify a description, a 'read more' link, and an opt 2. Import the following modules to your component: ```TypeScript -import { PropertyWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyWebPartInformation'; +import { PropertyWebPartInformation } from '@pnp/spfx-property-controls/lib/PropertyPaneWebPartInformation'; ``` 3. Create a new property for your web part, for example: @@ -27,7 +27,7 @@ export interface IPropertyControlsTestWebPartProps { 4. Add the custom property control to the `groupFields` of the web part property pane configuration: ```TypeScript - PropertyWebPartInformation({ + PropertyPaneWebPartInformation({ description: `This is a demo webpart, used to demonstrate all the PnP property controls`, moreInfoLink: `https://sharepoint.github.io/sp-dev-fx-property-controls/`, videoProperties: { @@ -40,7 +40,7 @@ export interface IPropertyControlsTestWebPartProps { ## Implementation -The `PropertyWebPartInformation` control has the following properties: +The `PropertyPaneWebPartInformation` control has the following properties: | Property | Type | Required | Description | | ---- | ---- | ---- | ---- | @@ -60,4 +60,4 @@ Class `IVideoEmbedProperties` -![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyWebPartInformation) +![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyPaneWebPartInformation) diff --git a/docs/documentation/docs/index.md b/docs/documentation/docs/index.md index 0376fde7..669d1cfc 100644 --- a/docs/documentation/docs/index.md +++ b/docs/documentation/docs/index.md @@ -40,8 +40,8 @@ The following controls are currently available: - [PropertyFieldTermPicker](./controls/PropertyFieldTermPicker) (Property pane managed metadata term selector) - [PropertyFieldMultiSelect](./controls/PropertyFieldMultiSelect) (Property pane field which allows multi-value selection) - [PropertyFieldNumber](./controls/PropertyFieldNumber) (Property pane field which allows only number values) -- [PropertyWebPartInformation](./controls/PropertyWebPartInformation) (Property pane webpart information panel) -- [PropertyEditor](./controls/PropertyEditor) (Property pane control that allows raw editing, export and import of webpart properties) +- [PropertyPaneWebPartInformation](./controls/PropertyPaneWebPartInformation) (Property pane webpart information panel) +- [PropertyPanePropertyEditor](./controls/PropertyPanePropertyEditor) (Property pane control that allows raw editing, export and import of webpart properties) The following controls are extended controls that show a callout next to the label - [PropertyFieldButtonWithCallout](./controls/PropertyFieldButtonWithCallout) (Property button field with callout) diff --git a/src/propertyFields/propertyEditor/IPropertyEditor.ts b/src/propertyFields/propertyEditor/IPropertyPanePropertyEditor.ts similarity index 64% rename from src/propertyFields/propertyEditor/IPropertyEditor.ts rename to src/propertyFields/propertyEditor/IPropertyPanePropertyEditor.ts index c70693d5..e7e76091 100644 --- a/src/propertyFields/propertyEditor/IPropertyEditor.ts +++ b/src/propertyFields/propertyEditor/IPropertyPanePropertyEditor.ts @@ -3,7 +3,7 @@ import { IPropertyPaneCustomFieldProps, BaseClientSideWebPart } from '@microsoft /** * Public properties of the PropertyFieldSpinButton custom field */ -export interface IPropertyEditorProps { +export interface IPropertyPanePropertyEditorProps { /** * This current webpart. Usually 'this'. @@ -17,5 +17,5 @@ export interface IPropertyEditorProps { } -export interface IPropertyEditorPropsInternal extends IPropertyEditorProps, IPropertyPaneCustomFieldProps { +export interface IPropertyPanePropertyEditorPropsInternal extends IPropertyPanePropertyEditorProps, IPropertyPaneCustomFieldProps { } \ No newline at end of file diff --git a/src/propertyFields/propertyEditor/IPropertyEditorHost.ts b/src/propertyFields/propertyEditor/IPropertyPanePropertyEditorHost.ts similarity index 65% rename from src/propertyFields/propertyEditor/IPropertyEditorHost.ts rename to src/propertyFields/propertyEditor/IPropertyPanePropertyEditorHost.ts index be925abd..3c282554 100644 --- a/src/propertyFields/propertyEditor/IPropertyEditorHost.ts +++ b/src/propertyFields/propertyEditor/IPropertyPanePropertyEditorHost.ts @@ -1,14 +1,14 @@ /** * PropertyFieldColorPickerHost properties interface */ -export interface IPropertyEditorHostProps { +export interface IPropertyPanePropertyEditorHostProps { webpart: any; } /** * PropertyFieldColorPickerHost state interface */ -export interface IPropertyEditorHostState { +export interface IPropertyPanePropertyEditorHostState { errorMessage?: string; openPanel? : boolean; propertiesJson?: string; diff --git a/src/propertyFields/propertyEditor/PropertyEditor.ts b/src/propertyFields/propertyEditor/PropertyEditor.ts deleted file mode 100644 index a0634204..00000000 --- a/src/propertyFields/propertyEditor/PropertyEditor.ts +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react'; -import * as ReactDom from 'react-dom'; -import { - IPropertyPaneField, - PropertyPaneFieldType -} from '@microsoft/sp-webpart-base'; -import { - IPropertyEditorProps, - IPropertyEditorPropsInternal -} from './IPropertyEditor'; -import { IPropertyEditorHostProps } from './IPropertyEditorHost'; -import PropertyEditorHost from './PropertyEditorHost'; - -class PropertyEditorBuilder implements IPropertyPaneField { - - //Properties defined by IPropertyPaneField - public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; - public targetProperty: string; - public properties: IPropertyEditorPropsInternal; - - private elem: HTMLElement; - - public constructor(_properties: IPropertyEditorProps) { - this.properties = { - key: _properties.key, - webpart: _properties.webpart, - onRender: this.onRender.bind(this) - }; - } - - public render(): void { - if (!this.elem) { - return; - } - - this.onRender(this.elem); - } - - private onRender(elem: HTMLElement, ctx?: any, changeCallback?: (targetProperty?: string, newValue?: any) => void): void { - if (!this.elem) { - this.elem = elem; - } - - const element: React.ReactElement = React.createElement(PropertyEditorHost, { - webpart: this.properties.webpart - }); - ReactDom.render(element, elem); - } -} - -export function PropertyEditor(properties: IPropertyEditorProps): IPropertyPaneField { - return new PropertyEditorBuilder(properties); -} diff --git a/src/propertyFields/propertyEditor/PropertyPanePropertyEditor.ts b/src/propertyFields/propertyEditor/PropertyPanePropertyEditor.ts new file mode 100644 index 00000000..6e70188e --- /dev/null +++ b/src/propertyFields/propertyEditor/PropertyPanePropertyEditor.ts @@ -0,0 +1,53 @@ +import * as React from 'react'; +import * as ReactDom from 'react-dom'; +import { + IPropertyPaneField, + PropertyPaneFieldType +} from '@microsoft/sp-webpart-base'; +import { + IPropertyPanePropertyEditorProps, + IPropertyPanePropertyEditorPropsInternal +} from './IPropertyPanePropertyEditor'; +import { IPropertyPanePropertyEditorHostProps } from './IPropertyPanePropertyEditorHost'; +import PropertyPanePropertyEditorHost from './PropertyPanePropertyEditorHost'; + +class PropertyPanePropertyEditorBuilder implements IPropertyPaneField { + + //Properties defined by IPropertyPaneField + public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; + public targetProperty: string; + public properties: IPropertyPanePropertyEditorPropsInternal; + + private elem: HTMLElement; + + public constructor(_properties: IPropertyPanePropertyEditorProps) { + this.properties = { + key: _properties.key, + webpart: _properties.webpart, + onRender: this.onRender.bind(this) + }; + } + + public render(): void { + if (!this.elem) { + return; + } + + this.onRender(this.elem); + } + + private onRender(elem: HTMLElement, ctx?: any, changeCallback?: (targetProperty?: string, newValue?: any) => void): void { + if (!this.elem) { + this.elem = elem; + } + + const element: React.ReactElement = React.createElement(PropertyPanePropertyEditorHost, { + webpart: this.properties.webpart + }); + ReactDom.render(element, elem); + } +} + +export function PropertyPanePropertyEditor(properties: IPropertyPanePropertyEditorProps): IPropertyPaneField { + return new PropertyPanePropertyEditorBuilder(properties); +} diff --git a/src/propertyFields/propertyEditor/PropertyEditorHost.module.scss b/src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.module.scss similarity index 100% rename from src/propertyFields/propertyEditor/PropertyEditorHost.module.scss rename to src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.module.scss diff --git a/src/propertyFields/propertyEditor/PropertyEditorHost.tsx b/src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.tsx similarity index 91% rename from src/propertyFields/propertyEditor/PropertyEditorHost.tsx rename to src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.tsx index aab4b935..eda12e53 100644 --- a/src/propertyFields/propertyEditor/PropertyEditorHost.tsx +++ b/src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.tsx @@ -1,21 +1,21 @@ import * as React from 'react'; -import { IPropertyEditorHostProps, IPropertyEditorHostState } from './IPropertyEditorHost'; +import { IPropertyPanePropertyEditorHostProps, IPropertyPanePropertyEditorHostState } from './IPropertyPanePropertyEditorHost'; import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel'; import { PrimaryButton, DefaultButton, IButtonProps, IconButton } from 'office-ui-fabric-react/lib/Button'; import AceEditor from 'react-ace'; import { set } from '@microsoft/sp-lodash-subset'; import * as telemetry from '../../common/telemetry'; -import styles from './PropertyEditorHost.module.scss'; +import styles from './PropertyPanePropertyEditorHost.module.scss'; import * as strings from 'PropertyControlStrings'; -export default class PropertyEditorHost extends React.Component { +export default class PropertyPanePropertyEditorHost extends React.Component { private previousValue: string; private cancel: boolean = true; private fileRef: HTMLInputElement = null; - constructor(props: IPropertyEditorHostProps, state: IPropertyEditorHostState) { + constructor(props: IPropertyPanePropertyEditorHostProps, state: IPropertyPanePropertyEditorHostState) { super(props); telemetry.track('PropertyWebPartInformation', {}); @@ -81,8 +81,8 @@ export default class PropertyEditorHost extends React.Component { - const newState: IPropertyEditorHostState = { + this.setState((crntState: IPropertyPanePropertyEditorHostState) => { + const newState: IPropertyPanePropertyEditorHostState = { openPanel: false, }; diff --git a/src/propertyFields/propertyEditor/index.ts b/src/propertyFields/propertyEditor/index.ts index 7f389097..9901c1b1 100644 --- a/src/propertyFields/propertyEditor/index.ts +++ b/src/propertyFields/propertyEditor/index.ts @@ -1,4 +1,4 @@ -export * from './IPropertyEditor'; -export * from './PropertyEditor'; -export * from './IPropertyEditorHost'; -export * from './PropertyEditorHost'; \ No newline at end of file +export * from './IPropertyPanePropertyEditor'; +export * from './PropertyPanePropertyEditor'; +export * from './IPropertyPanePropertyEditorHost'; +export * from './PropertyPanePropertyEditorHost'; \ No newline at end of file diff --git a/src/propertyFields/webPartInformation/IPropertyWebPartInformation.ts b/src/propertyFields/webPartInformation/IPropertyPaneWebPartInformation.ts similarity index 89% rename from src/propertyFields/webPartInformation/IPropertyWebPartInformation.ts rename to src/propertyFields/webPartInformation/IPropertyPaneWebPartInformation.ts index 0b1b43ff..65f389b0 100644 --- a/src/propertyFields/webPartInformation/IPropertyWebPartInformation.ts +++ b/src/propertyFields/webPartInformation/IPropertyPaneWebPartInformation.ts @@ -4,7 +4,7 @@ import { IPropertyPaneCustomFieldProps, BaseClientSideWebPart } from '@microsoft /** * Public properties of the PropertyFieldSpinButton custom field */ -export interface IPropertyWebPartInformationProps { +export interface IPropertyPaneWebPartInformationProps { /** * A link pointing to an external source for more information @@ -28,7 +28,7 @@ export interface IPropertyWebPartInformationProps { key: string; } -export interface IPropertyWebPartInformationPropsInternal extends IPropertyWebPartInformationProps, IPropertyPaneCustomFieldProps { +export interface IPropertyWebPartInformationPropsInternal extends IPropertyPaneWebPartInformationProps, IPropertyPaneCustomFieldProps { } export interface IVideoEmbedProperties { diff --git a/src/propertyFields/webPartInformation/IPropertyWebPartInformationHost.ts b/src/propertyFields/webPartInformation/IPropertyPaneWebPartInformationHost.ts similarity index 57% rename from src/propertyFields/webPartInformation/IPropertyWebPartInformationHost.ts rename to src/propertyFields/webPartInformation/IPropertyPaneWebPartInformationHost.ts index 695a5f44..45b69bc1 100644 --- a/src/propertyFields/webPartInformation/IPropertyWebPartInformationHost.ts +++ b/src/propertyFields/webPartInformation/IPropertyPaneWebPartInformationHost.ts @@ -1,9 +1,9 @@ -import { IVideoEmbedProperties } from "./IPropertyWebPartInformation"; +import { IVideoEmbedProperties } from "./IPropertyPaneWebPartInformation"; /** * PropertyFieldColorPickerHost properties interface */ -export interface IPropertyWebPartInformationHostProps { +export interface IPropertyPaneWebPartInformationHostProps { videoProperties?: IVideoEmbedProperties; moreInfoLink?: string; moreInfoLinkTarget?: string; diff --git a/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts b/src/propertyFields/webPartInformation/PropertyPaneWebPartInformation.ts similarity index 59% rename from src/propertyFields/webPartInformation/PropertyWebPartInformation.ts rename to src/propertyFields/webPartInformation/PropertyPaneWebPartInformation.ts index cebf2708..3f96afd5 100644 --- a/src/propertyFields/webPartInformation/PropertyWebPartInformation.ts +++ b/src/propertyFields/webPartInformation/PropertyPaneWebPartInformation.ts @@ -5,11 +5,11 @@ import { PropertyPaneFieldType } from '@microsoft/sp-webpart-base'; -import { IPropertyWebPartInformationProps, IPropertyWebPartInformationPropsInternal } from "./IPropertyWebPartInformation"; -import { IPropertyWebPartInformationHostProps } from './IPropertyWebPartInformationHost'; -import PropertyWebPartInformationHost from './PropertyWebPartInformationHost'; +import { IPropertyPaneWebPartInformationProps, IPropertyWebPartInformationPropsInternal } from "./IPropertyPaneWebPartInformation"; +import { IPropertyPaneWebPartInformationHostProps } from './IPropertyPaneWebPartInformationHost'; +import PropertyPaneWebPartInformationHost from './PropertyPaneWebPartInformationHost'; -class PropertyWebPartInformationBuilder implements IPropertyPaneField { +class PropertyPaneWebPartInformationBuilder implements IPropertyPaneField { //Properties defined by IPropertyPaneField public targetProperty: string; public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; @@ -17,7 +17,7 @@ class PropertyWebPartInformationBuilder implements IPropertyPaneField = React.createElement(PropertyWebPartInformationHost, { + const element: React.ReactElement = React.createElement(PropertyPaneWebPartInformationHost, { moreInfoLink: this.properties.moreInfoLink, moreInfoLinkTarget: this.properties.moreInfoLinkTarget, description: this.properties.description, @@ -50,6 +50,6 @@ class PropertyWebPartInformationBuilder implements IPropertyPaneField { - return new PropertyWebPartInformationBuilder(properties); +export function PropertyPaneWebPartInformation(properties: IPropertyPaneWebPartInformationProps): IPropertyPaneField { + return new PropertyPaneWebPartInformationBuilder(properties); } diff --git a/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx b/src/propertyFields/webPartInformation/PropertyPaneWebPartInformationHost.tsx similarity index 83% rename from src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx rename to src/propertyFields/webPartInformation/PropertyPaneWebPartInformationHost.tsx index 15f1b99c..028c95d9 100644 --- a/src/propertyFields/webPartInformation/PropertyWebPartInformationHost.tsx +++ b/src/propertyFields/webPartInformation/PropertyPaneWebPartInformationHost.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import * as strings from 'PropertyControlStrings'; -import { IPropertyWebPartInformationHostProps } from './IPropertyWebPartInformationHost'; +import { IPropertyPaneWebPartInformationHostProps } from './IPropertyPaneWebPartInformationHost'; import PropertyFieldHeader from '../../common/propertyFieldHeader/PropertyFieldHeader'; import * as telemetry from '../../common/telemetry'; -export default class PropertyWebPartInformationHost extends React.Component { +export default class PropertyPaneWebPartInformationHost extends React.Component { - constructor(props: IPropertyWebPartInformationHostProps) { + constructor(props: IPropertyPaneWebPartInformationHostProps) { super(props); telemetry.track('PropertyWebPartInformation', {}); diff --git a/src/propertyFields/webPartInformation/index.ts b/src/propertyFields/webPartInformation/index.ts index c5cdfa5a..be116e0b 100644 --- a/src/propertyFields/webPartInformation/index.ts +++ b/src/propertyFields/webPartInformation/index.ts @@ -1,4 +1,4 @@ -export * from './IPropertyWebPartInformation'; -export * from './PropertyWebPartInformation'; -export * from './IPropertyWebPartInformationHost'; -export * from './PropertyWebPartInformationHost'; +export * from './IPropertyPaneWebPartInformation'; +export * from './PropertyPaneWebPartInformation'; +export * from './IPropertyPaneWebPartInformationHost'; +export * from './PropertyPaneWebPartInformationHost'; diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index 1d27ac42..5be31e0a 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -35,8 +35,8 @@ import { PropertyFieldCollectionData, CustomCollectionFieldType } from '../../Pr import { PropertyFieldOrder } from '../../PropertyFieldOrder'; import { orderedItem } from './components/OrderedItem'; import { PropertyFieldSwatchColorPicker, PropertyFieldSwatchColorPickerStyle } from '../../PropertyFieldSwatchColorPicker'; -import { PropertyWebPartInformation } from '../../propertyFields/webPartInformation'; -import { PropertyEditor } from '../../propertyFields/propertyEditor/PropertyEditor'; +import { PropertyPaneWebPartInformation } from '../../propertyFields/webPartInformation'; +import { PropertyPanePropertyEditor } from '../../propertyFields/propertyEditor/PropertyPanePropertyEditor'; /** * Web part that can be used to test out the various property controls @@ -133,7 +133,7 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPartdemo webpart, used to demonstrate all the PnP property controls`, moreInfoLink: `https://sharepoint.github.io/sp-dev-fx-property-controls/`, videoProperties: { @@ -535,7 +535,7 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart Date: Thu, 1 Nov 2018 11:54:13 +0100 Subject: [PATCH 28/34] rename files --- src/{PropertyEditor.ts => PropertyPanePropertyEditor.ts} | 0 ...rtyWebPartInformation.ts => PropertyPaneWebPartInformation.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{PropertyEditor.ts => PropertyPanePropertyEditor.ts} (100%) rename src/{PropertyWebPartInformation.ts => PropertyPaneWebPartInformation.ts} (100%) diff --git a/src/PropertyEditor.ts b/src/PropertyPanePropertyEditor.ts similarity index 100% rename from src/PropertyEditor.ts rename to src/PropertyPanePropertyEditor.ts diff --git a/src/PropertyWebPartInformation.ts b/src/PropertyPaneWebPartInformation.ts similarity index 100% rename from src/PropertyWebPartInformation.ts rename to src/PropertyPaneWebPartInformation.ts From 512b6632ff2e51896d69a014ca67a3b6bff35812 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Thu, 1 Nov 2018 11:57:07 +0100 Subject: [PATCH 29/34] updated index --- src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 07d12da0..250f5921 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,4 +16,5 @@ export * from './PropertyFieldLinkWithCallout'; export * from './PropertyFieldSliderWithCallout'; export * from './PropertyFieldTextWithCallout'; export * from './PropertyFieldToggleWithCallout'; -export * from './PropertyWebPartInformation'; +export * from './PropertyPaneWebPartInformation'; +export * from './PropertyPanePropertyEditor'; From 333991e8becbad3deaf36922ee7ccf9069a5767a Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Mon, 5 Nov 2018 13:55:32 +0100 Subject: [PATCH 30/34] Changelog updates + other small documentation changes --- CHANGELOG.json | 3 ++- CHANGELOG.md | 3 ++- docs/documentation/docs/about/release-notes.md | 3 ++- .../controls/PropertyPanePropertyEditor.md | 12 ++++++------ .../controls/PropertyPaneWebPartInformation.md | 18 +++++++++--------- .../PropertyPanePropertyEditorHost.tsx | 9 +++------ 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index 5e948a82..35e60e61 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -4,7 +4,8 @@ "version": "1.12.0", "changes": { "new": [ - "`PropertyWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108)" + "`PropertyPaneWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108)", + "`PropertyPanePropertyEditor`: New control that allows you to export/import property pane settings [#114](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/114)" ], "enhancements": [ "Dutch localization added [#82](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/82)", diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f1ce620..5b7d1828 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ **New control(s)** -- `PropertyWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108) +- `PropertyPaneWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108) +- `PropertyPanePropertyEditor`: New control that allows you to export/import property pane settings [#114](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/114) **Enhancements** diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index 7f1ce620..5b7d1828 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -4,7 +4,8 @@ **New control(s)** -- `PropertyWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108) +- `PropertyPaneWebPartInformation`: New control to show more information about the current web part [#108](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/108) +- `PropertyPanePropertyEditor`: New control that allows you to export/import property pane settings [#114](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/114) **Enhancements** diff --git a/docs/documentation/docs/controls/PropertyPanePropertyEditor.md b/docs/documentation/docs/controls/PropertyPanePropertyEditor.md index e88b53ec..460e548c 100644 --- a/docs/documentation/docs/controls/PropertyPanePropertyEditor.md +++ b/docs/documentation/docs/controls/PropertyPanePropertyEditor.md @@ -24,17 +24,17 @@ import { PropertyWebPartInformation } from '@pnp/spfx-property-controls/lib/Prop ```TypeScript export interface IPropertyControlsTestWebPartProps { - toggleInfoHeaderValue: boolean; + toggleInfoHeaderValue: boolean; } ``` 4. Add the custom property control to the `groupFields` of the web part property pane configuration: ```TypeScript - PropertyPanePropertyEditor({ - webpart: this, - key: 'propertyEditor' - }) +PropertyPanePropertyEditor({ + webpart: this, + key: 'propertyEditor' +}) ``` ## Implementation @@ -46,4 +46,4 @@ The `PropertyEditor` control has the following properties: | webpart | BaseClientSideWebPart | yes | The webpart, which is in principle the current webpart, of which you want to be able to edit the properties from | -![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyEditor) +![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyPanePropertyEditor) diff --git a/docs/documentation/docs/controls/PropertyPaneWebPartInformation.md b/docs/documentation/docs/controls/PropertyPaneWebPartInformation.md index 59f49d96..74624b34 100644 --- a/docs/documentation/docs/controls/PropertyPaneWebPartInformation.md +++ b/docs/documentation/docs/controls/PropertyPaneWebPartInformation.md @@ -27,15 +27,15 @@ export interface IPropertyControlsTestWebPartProps { 4. Add the custom property control to the `groupFields` of the web part property pane configuration: ```TypeScript - PropertyPaneWebPartInformation({ - description: `This is a demo webpart, used to demonstrate all the PnP property controls`, - moreInfoLink: `https://sharepoint.github.io/sp-dev-fx-property-controls/`, - videoProperties: { - embedLink: `https://www.youtube.com/embed/d_9o3tQ90zo`, - properties: { allowFullScreen: true} - }, - key: 'webPartInfoId' - }) +PropertyPaneWebPartInformation({ + description: `This is a demo webpart, used to demonstrate all the PnP property controls`, + moreInfoLink: `https://sharepoint.github.io/sp-dev-fx-property-controls/`, + videoProperties: { + embedLink: `https://www.youtube.com/embed/d_9o3tQ90zo`, + properties: { allowFullScreen: true} + }, + key: 'webPartInfoId' +}) ``` ## Implementation diff --git a/src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.tsx b/src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.tsx index eda12e53..476c31ed 100644 --- a/src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.tsx +++ b/src/propertyFields/propertyEditor/PropertyPanePropertyEditorHost.tsx @@ -24,9 +24,6 @@ export default class PropertyPanePropertyEditorHost extends React.Component { @@ -65,7 +62,7 @@ export default class PropertyPanePropertyEditorHost extends React.Component { // Store the current code value this.previousValue = JSON.stringify(this.props.webpart.properties, null, '\t'); @@ -80,7 +77,7 @@ export default class PropertyPanePropertyEditorHost extends React.Component { this.setState((crntState: IPropertyPanePropertyEditorHostState) => { const newState: IPropertyPanePropertyEditorHostState = { openPanel: false, @@ -152,7 +149,7 @@ export default class PropertyPanePropertyEditorHost extends React.Component
- + { this.fileRef.click(); }} /> From e5cddab43f05b82d620ba2eabec4a584ca33459e Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Mon, 5 Nov 2018 17:49:51 +0100 Subject: [PATCH 31/34] #109 - Enhancements to support site URL updates in ListPicker --- .../PropertyFieldListMultiPickerHost.tsx | 16 +++++++++++++++- .../listPicker/PropertyFieldListPickerHost.tsx | 8 ++++++++ .../IPropertyControlsTestWebPartProps.ts | 1 + .../PropertyControlsTestWebPart.ts | 13 ++++++++----- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/propertyFields/listPicker/PropertyFieldListMultiPickerHost.tsx b/src/propertyFields/listPicker/PropertyFieldListMultiPickerHost.tsx index d91729a7..56eddd87 100644 --- a/src/propertyFields/listPicker/PropertyFieldListMultiPickerHost.tsx +++ b/src/propertyFields/listPicker/PropertyFieldListMultiPickerHost.tsx @@ -42,16 +42,26 @@ export default class PropertyFieldListMultiPickerHost extends React.Component { response.value.forEach((list: ISPList) => { @@ -74,7 +84,11 @@ export default class PropertyFieldListMultiPickerHost extends React.Component { // Start mapping the list that are selected response.value.forEach((list: ISPList) => { diff --git a/src/webparts/propertyControlsTest/IPropertyControlsTestWebPartProps.ts b/src/webparts/propertyControlsTest/IPropertyControlsTestWebPartProps.ts index 46fedecd..2dcaba43 100644 --- a/src/webparts/propertyControlsTest/IPropertyControlsTestWebPartProps.ts +++ b/src/webparts/propertyControlsTest/IPropertyControlsTestWebPartProps.ts @@ -5,6 +5,7 @@ import { IPropertyFieldGroupOrPerson } from '../../PropertyFieldPeoplePicker'; import { IPickerTerms } from '../../PropertyFieldTermPicker'; export interface IPropertyControlsTestWebPartProps { + siteUrl: string; numberValue: number; multiSelect: string[]; people: IPropertyFieldGroupOrPerson[]; diff --git a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts index 5be31e0a..73d4e768 100644 --- a/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts +++ b/src/webparts/propertyControlsTest/PropertyControlsTestWebPart.ts @@ -130,7 +130,7 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart Date: Mon, 5 Nov 2018 17:53:04 +0100 Subject: [PATCH 32/34] Changelog updates --- CHANGELOG.json | 3 ++- CHANGELOG.md | 1 + docs/documentation/docs/about/release-notes.md | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.json b/CHANGELOG.json index 35e60e61..a7aeaf40 100644 --- a/CHANGELOG.json +++ b/CHANGELOG.json @@ -13,7 +13,8 @@ "`PropertyFieldCollectionData`: Allow the user to specify a deferred validation time for each field [#98](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/98)", "`PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102)", "`PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104)", - "Hide callout from the controls with callout if no message is provided [#107](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/107)" + "Hide callout from the controls with callout if no message is provided [#107](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/107)", + "`PropertyFieldListPicker`: Add the ability to refresh target site while pane is open [#109](https://github.com/SharePoint/sp-dev-fx-controls-react/pull/109)" ], "fixes": [ "`PropertyFieldCollectionData`: Fixed catastrophic backtracking regex issue for URL validation [#99](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/99)" diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b7d1828..3007b80b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - `PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) - Hide callout from the controls with callout if no message is provided [#107](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/107) +- `PropertyFieldListPicker`: Add the ability to refresh target site while pane is open [#109](https://github.com/SharePoint/sp-dev-fx-controls-react/pull/109) **Fixes** diff --git a/docs/documentation/docs/about/release-notes.md b/docs/documentation/docs/about/release-notes.md index 5b7d1828..3007b80b 100644 --- a/docs/documentation/docs/about/release-notes.md +++ b/docs/documentation/docs/about/release-notes.md @@ -15,6 +15,7 @@ - `PropertyFieldCollectionData`: added a onRenderOption option to allow custom option rendering [#102](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/102) - `PropertyFieldNumber`: Introduced the aria label [#104](https://github.com/SharePoint/sp-dev-fx-property-controls/pull/104) - Hide callout from the controls with callout if no message is provided [#107](https://github.com/SharePoint/sp-dev-fx-property-controls/issues/107) +- `PropertyFieldListPicker`: Add the ability to refresh target site while pane is open [#109](https://github.com/SharePoint/sp-dev-fx-controls-react/pull/109) **Fixes** From d631deb6600b7a1498503ebfe8afc338c9ba4fc5 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Tue, 13 Nov 2018 07:40:55 +0000 Subject: [PATCH 33/34] Minor fix for short date label --- src/loc/en-us.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loc/en-us.js b/src/loc/en-us.js index eea01444..15f7c3ff 100644 --- a/src/loc/en-us.js +++ b/src/loc/en-us.js @@ -42,7 +42,7 @@ define([], function() { DatePickerDayLongTuesday: "Tuesday", DatePickerDayShortTuesday: "Tue", DatePickerDayLongWednesday: "Wednesday", - DatePickerDayShortWednesday: "Web", + DatePickerDayShortWednesday: "Wed", DatePickerDayLongThursday: "Thursday", DatePickerDayShortThursday: "Thu", DatePickerDayLongFriday: "Friday", From 1ee75e9b48ca5231cc1e89b029dcec8a238316b8 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Tue, 13 Nov 2018 07:51:04 +0000 Subject: [PATCH 34/34] Update csv to contain short date fix --- spfx-locale.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spfx-locale.csv b/spfx-locale.csv index 4e8b398e..8266fe59 100644 --- a/spfx-locale.csv +++ b/spfx-locale.csv @@ -37,7 +37,7 @@ DatePickerDayShortMonday;Mon;Maa;Lun;x DatePickerDayLongTuesday;Tuesday;Dinsdag;Mardi;x DatePickerDayShortTuesday;Tue;Din;Mar;x DatePickerDayLongWednesday;Wednesday;Woensdag;Mercredi;x -DatePickerDayShortWednesday;Web;Woe;Mer;x +DatePickerDayShortWednesday;Wed;Woe;Mer;x DatePickerDayLongThursday;Thursday;Donderdag;Jeudi;x DatePickerDayShortThursday;Thu;Don;Jeu;x DatePickerDayLongFriday;Friday;Vrijdag;Vendredi;x