chore(): sync with main

This commit is contained in:
Liam DeBeasi
2022-09-16 15:24:24 -04:00
759 changed files with 13280 additions and 7837 deletions

View File

@@ -372,11 +372,11 @@ export namespace Components {
*/
"download": string | undefined;
/**
* Set to `"block"` for a full-width button or to `"full"` for a full-width button without left and right borders.
* Set to `"block"` for a full-width button or to `"full"` for a full-width button with square corners and no left or right borders.
*/
"expand"?: 'full' | 'block';
/**
* Set to `"clear"` for a transparent button, to `"outline"` for a transparent button with a border, or to `"solid"`. The default style is `"solid"` except inside of a toolbar, where the default is `"clear"`.
* Set to `"clear"` for a transparent button that resembles a flat button, to `"outline"` for a transparent button with a border, or to `"solid"` for a button with a filled background. The default fill is `"solid"` except inside of a toolbar, where the default is `"clear"`.
*/
"fill"?: 'clear' | 'outline' | 'solid' | 'default';
/**
@@ -400,11 +400,11 @@ export namespace Components {
*/
"routerDirection": RouterDirection;
/**
* The button shape.
* Set to `"round"` for a button with more rounded corners.
*/
"shape"?: 'round';
/**
* The button size.
* Set to `"small"` for a button with less height and padding, to `"default"` for a button with the default height and padding, or to `"large"` for a button with more height and padding. By default the size is unset, unless the button is inside of an item, where the size is `"small"` by default. Set the size to `"default"` inside of an item to make it a standard size button.
*/
"size"?: 'small' | 'default' | 'large';
/**
@@ -4336,11 +4336,11 @@ declare namespace LocalJSX {
*/
"download"?: string | undefined;
/**
* Set to `"block"` for a full-width button or to `"full"` for a full-width button without left and right borders.
* Set to `"block"` for a full-width button or to `"full"` for a full-width button with square corners and no left or right borders.
*/
"expand"?: 'full' | 'block';
/**
* Set to `"clear"` for a transparent button, to `"outline"` for a transparent button with a border, or to `"solid"`. The default style is `"solid"` except inside of a toolbar, where the default is `"clear"`.
* Set to `"clear"` for a transparent button that resembles a flat button, to `"outline"` for a transparent button with a border, or to `"solid"` for a button with a filled background. The default fill is `"solid"` except inside of a toolbar, where the default is `"clear"`.
*/
"fill"?: 'clear' | 'outline' | 'solid' | 'default';
/**
@@ -4372,11 +4372,11 @@ declare namespace LocalJSX {
*/
"routerDirection"?: RouterDirection;
/**
* The button shape.
* Set to `"round"` for a button with more rounded corners.
*/
"shape"?: 'round';
/**
* The button size.
* Set to `"small"` for a button with less height and padding, to `"default"` for a button with the default height and padding, or to `"large"` for a button with more height and padding. By default the size is unset, unless the button is inside of an item, where the size is `"small"` by default. Set the size to `"default"` inside of an item to make it a standard size button.
*/
"size"?: 'small' | 'default' | 'large';
/**

View File

@@ -239,16 +239,18 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
}
render() {
const { htmlAttributes } = this;
const { header, htmlAttributes, overlayIndex } = this;
const mode = getIonMode(this);
const allButtons = this.getButtons();
const cancelButton = allButtons.find((b) => b.role === 'cancel');
const buttons = allButtons.filter((b) => b.role !== 'cancel');
const headerID = `action-sheet-${overlayIndex}-header`;
return (
<Host
role="dialog"
aria-modal="true"
aria-labelledby={header !== undefined ? headerID : null}
tabindex="-1"
{...(htmlAttributes as any)}
style={{
@@ -256,7 +258,6 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
}}
class={{
[mode]: true,
...getClassMap(this.cssClass),
'overlay-hidden': true,
'action-sheet-translucent': this.translucent,
@@ -268,17 +269,18 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
<div tabindex="0"></div>
<div class="action-sheet-wrapper ion-overlay-wrapper" role="dialog" ref={(el) => (this.wrapperEl = el)}>
<div class="action-sheet-wrapper ion-overlay-wrapper" ref={(el) => (this.wrapperEl = el)}>
<div class="action-sheet-container">
<div class="action-sheet-group" ref={(el) => (this.groupEl = el)}>
{this.header !== undefined && (
{header !== undefined && (
<div
id={headerID}
class={{
'action-sheet-title': true,
'action-sheet-has-sub-title': this.subHeader !== undefined,
}}
>
{this.header}
{header}
{this.subHeader && <div class="action-sheet-sub-title">{this.subHeader}</div>}
</div>
)}

View File

@@ -0,0 +1,57 @@
import AxeBuilder from '@axe-core/playwright';
import { expect } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { test } from '@utils/test/playwright';
const testAria = async (page: E2EPage, buttonID: string, expectedAriaLabelledBy: string | null) => {
const didPresent = await page.spyOnEvent('ionActionSheetDidPresent');
const button = page.locator(`#${buttonID}`);
await button.click();
await didPresent.next();
const alert = page.locator('ion-action-sheet');
/**
* expect().toHaveAttribute() can't check for a null value, so grab and check
* the value manually instead.
*/
const ariaLabelledBy = await alert.getAttribute('aria-labelledby');
expect(ariaLabelledBy).toBe(expectedAriaLabelledBy);
};
test.describe('action-sheet: a11y', () => {
test.beforeEach(async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/action-sheet/test/a11y`);
});
test('should not have accessibility violations when header is defined', async ({ page }) => {
const button = page.locator('#bothHeaders');
const didPresent = await page.spyOnEvent('ionActionSheetDidPresent');
await button.click();
await didPresent.next();
/**
* action-sheet overlays the entire screen, so
* Axe will be unable to verify color contrast
* on elements under the backdrop.
*/
const results = await new AxeBuilder({ page }).disableRules('color-contrast').analyze();
expect(results.violations).toEqual([]);
});
test('should have aria-labelledby when header is set', async ({ page }) => {
await testAria(page, 'bothHeaders', 'action-sheet-1-header');
});
test('should not have aria-labelledby when header is not set', async ({ page }) => {
await testAria(page, 'noHeaders', null);
});
test('should allow for manually specifying aria attributes', async ({ page }) => {
await testAria(page, 'customAria', 'Custom title');
});
});

View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Action Sheet - A11y</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<script type="module">
import { actionSheetController } from '../../../../dist/ionic/index.esm.js';
window.actionSheetController = actionSheetController;
</script>
<body>
<main class="ion-padding">
<h1>Action Sheet - A11y</h1>
<ion-button id="bothHeaders" expand="block" onclick="presentBothHeaders()">Both Headers</ion-button>
<ion-button id="subHeaderOnly" expand="block" onclick="presentSubHeaderOnly()">Subheader Only</ion-button>
<ion-button id="noHeaders" expand="block" onclick="presentNoHeaders()">No Headers</ion-button>
<ion-button id="customAria" expand="block" onclick="presentCustomAria()">Custom Aria</ion-button>
</main>
<script>
async function openActionSheet(opts) {
const actionSheet = await actionSheetController.create(opts);
await actionSheet.present();
}
function presentBothHeaders() {
openActionSheet({
header: 'Header',
subHeader: 'Subtitle',
buttons: ['Confirm'],
});
}
function presentSubHeaderOnly() {
openActionSheet({
subHeader: 'Subtitle',
buttons: ['Confirm'],
});
}
function presentNoHeaders() {
openActionSheet({
buttons: ['Confirm'],
});
}
function presentCustomAria() {
openActionSheet({
header: 'Header',
subHeader: 'Subtitle',
buttons: ['Confirm'],
htmlAttributes: {
'aria-labelledby': 'Custom title',
'aria-describedby': 'Custom description',
},
});
}
</script>
</body>
</html>

View File

@@ -578,20 +578,26 @@ export class Alert implements ComponentInterface, OverlayInterface {
}
render() {
const { overlayIndex, header, subHeader, htmlAttributes } = this;
const { overlayIndex, header, subHeader, message, htmlAttributes } = this;
const mode = getIonMode(this);
const hdrId = `alert-${overlayIndex}-hdr`;
const subHdrId = `alert-${overlayIndex}-sub-hdr`;
const msgId = `alert-${overlayIndex}-msg`;
const role = this.inputs.length > 0 || this.buttons.length > 0 ? 'alertdialog' : 'alert';
const defaultAriaLabel = header || subHeader || 'Alert';
/**
* If the header is defined, use that. Otherwise, fall back to the subHeader.
* If neither is defined, don't set aria-labelledby.
*/
const ariaLabelledBy = header ? hdrId : subHeader ? subHdrId : null;
return (
<Host
role={role}
aria-modal="true"
aria-labelledby={ariaLabelledBy}
aria-describedby={message ? msgId : null}
tabindex="-1"
aria-label={defaultAriaLabel}
{...(htmlAttributes as any)}
style={{
zIndex: `${20000 + overlayIndex}`,
@@ -623,7 +629,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
)}
</div>
<div id={msgId} class="alert-message" innerHTML={sanitizeDOMString(this.message)}></div>
<div id={msgId} class="alert-message" innerHTML={sanitizeDOMString(message)}></div>
{this.renderAlertInputs()}
{this.renderAlertButtons()}

View File

@@ -3,12 +3,29 @@ import { expect } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { test } from '@utils/test/playwright';
const testAriaLabel = async (page: E2EPage, buttonID: string, expectedAriaLabel: string) => {
const testAria = async (
page: E2EPage,
buttonID: string,
expectedAriaLabelledBy: string | null,
expectedAriaDescribedBy: string | null
) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
const button = page.locator(`#${buttonID}`);
await button.click();
await didPresent.next();
const alert = page.locator('ion-alert');
await expect(alert).toHaveAttribute('aria-label', expectedAriaLabel);
/**
* expect().toHaveAttribute() can't check for a null value, so grab and check
* the values manually instead.
*/
const ariaLabelledBy = await alert.getAttribute('aria-labelledby');
const ariaDescribedBy = await alert.getAttribute('aria-describedby');
expect(ariaLabelledBy).toBe(expectedAriaLabelledBy);
expect(ariaDescribedBy).toBe(expectedAriaDescribedBy);
};
test.describe('alert: a11y', () => {
@@ -17,27 +34,27 @@ test.describe('alert: a11y', () => {
await page.goto(`/src/components/alert/test/a11y`);
});
test('should not have accessibility violations', async ({ page }) => {
const button = page.locator('#customHeader');
test('should not have accessibility violations when header and message are defined', async ({ page }) => {
const button = page.locator('#bothHeaders');
await button.click();
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
test('should have fallback aria-label when no header or subheader is specified', async ({ page }) => {
await testAriaLabel(page, 'noHeader', 'Alert');
test('should have aria-labelledby when header is set', async ({ page }) => {
await testAria(page, 'noMessage', 'alert-1-hdr', null);
});
test('should inherit aria-label from header', async ({ page }) => {
await testAriaLabel(page, 'customHeader', 'Header');
test('should have aria-describedby when message is set', async ({ page }) => {
await testAria(page, 'noHeaders', null, 'alert-1-msg');
});
test('should inherit aria-label from subheader if no header is specified', async ({ page }) => {
await testAriaLabel(page, 'subHeaderOnly', 'Subtitle');
test('should fall back to subHeader for aria-labelledby if header is not defined', async ({ page }) => {
await testAria(page, 'subHeaderOnly', 'alert-1-sub-hdr', 'alert-1-msg');
});
test('should allow for manually specifying aria-label', async ({ page }) => {
await testAriaLabel(page, 'customAriaLabel', 'Custom alert');
test('should allow for manually specifying aria attributes', async ({ page }) => {
await testAria(page, 'customAria', 'Custom title', 'Custom description');
});
});

View File

@@ -19,14 +19,11 @@
<main class="ion-padding">
<h1>Alert - A11y</h1>
<ion-button id="noHeader" expand="block" onclick="presentNoHeader()">Alert With No Header</ion-button>
<ion-button id="customHeader" expand="block" onclick="presentCustomHeader()">Alert With Custom Header</ion-button>
<ion-button id="subHeaderOnly" expand="block" onclick="presentSubHeaderOnly()"
>Alert With Subheader Only</ion-button
>
<ion-button id="customAriaLabel" expand="block" onclick="presentCustomAriaLabel()"
>Alert With Custom Aria Label</ion-button
>
<ion-button id="bothHeaders" expand="block" onclick="presentBothHeaders()">Both Headers</ion-button>
<ion-button id="subHeaderOnly" expand="block" onclick="presentSubHeaderOnly()">Subheader Only</ion-button>
<ion-button id="noHeaders" expand="block" onclick="presentNoHeaders()">No Headers</ion-button>
<ion-button id="noMessage" expand="block" onclick="presentNoMessage()">No Message</ion-button>
<ion-button id="customAria" expand="block" onclick="presentCustomAria()">Custom Aria</ion-button>
</main>
<script>
@@ -35,14 +32,7 @@
await alert.present();
}
function presentNoHeader() {
openAlert({
message: 'This is an alert message.',
buttons: ['OK'],
});
}
function presentCustomHeader() {
function presentBothHeaders() {
openAlert({
header: 'Header',
subHeader: 'Subtitle',
@@ -59,14 +49,30 @@
});
}
function presentCustomAriaLabel() {
function presentNoHeaders() {
openAlert({
message: 'This is an alert message.',
buttons: ['OK'],
});
}
function presentNoMessage() {
openAlert({
header: 'Header',
subHeader: 'Subtitle',
message: 'This is an alert message with a custom aria-label.',
buttons: ['OK'],
});
}
function presentCustomAria() {
openAlert({
header: 'Header',
subHeader: 'Subtitle',
message: 'This is an alert message with custom aria attributes.',
buttons: ['OK'],
htmlAttributes: {
'aria-label': 'Custom alert',
'aria-labelledby': 'Custom title',
'aria-describedby': 'Custom description',
},
});
}

View File

@@ -1,9 +1,57 @@
import { expect } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { test } from '@utils/test/playwright';
const openAlert = async (page: E2EPage, buttonID: string) => {
const didPresent = await page.spyOnEvent('ionAlertDidPresent');
await page.click(`#${buttonID}`);
await didPresent.next();
return page.locator('ion-alert');
};
const testAlert = async (page: E2EPage, buttonID: string) => {
await page.goto(`/src/components/alert/test/basic`);
const didDismiss = await page.spyOnEvent('ionAlertDidDismiss');
const alert = await openAlert(page, buttonID);
await expect(alert).toBeVisible();
expect(await alert.screenshot()).toMatchSnapshot(`alert-${buttonID}-${page.getSnapshotSettings()}.png`);
await alert.evaluate((el: HTMLIonAlertElement) => el.dismiss());
await didDismiss.next();
await expect(alert).toHaveCount(0);
};
test.describe('alert: basic', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/alert/test/basic');
test('focus trap should work correctly', async ({ page, skip, browserName }) => {
skip.rtl();
await page.goto(`/src/components/alert/test/basic`);
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
const alert = await openAlert(page, 'multipleButtons');
const alertBtns = alert.locator('button');
await page.keyboard.press(tabKey);
await expect(alertBtns.nth(0)).toBeFocused();
await page.keyboard.press(`Shift+${tabKey}`);
await expect(alertBtns.nth(2)).toBeFocused();
await page.keyboard.press(tabKey);
await expect(alertBtns.nth(0)).toBeFocused();
});
test('should set custom attributes', async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/alert/test/basic`);
const alert = await openAlert(page, 'basic');
expect(alert).toHaveAttribute('data-testid', 'basic-alert');
});
test('should dismiss when async handler resolves', async ({ page }) => {
@@ -25,4 +73,38 @@ test.describe('alert: basic', () => {
await expect(alert).toBeHidden();
});
test.describe('should not have visual regressions', () => {
test('header, subheader, message', async ({ page }) => {
await testAlert(page, 'basic');
});
test('long message', async ({ page }) => {
await testAlert(page, 'longMessage');
});
test('more than two buttons', async ({ page }) => {
await testAlert(page, 'multipleButtons');
});
test('no message', async ({ page }) => {
await testAlert(page, 'noMessage');
});
test('two buttons', async ({ page }) => {
await testAlert(page, 'confirm');
});
test('form prompt', async ({ page }) => {
await testAlert(page, 'prompt');
});
test('radios', async ({ page }) => {
await testAlert(page, 'radio');
});
test('checkboxes', async ({ page }) => {
await testAlert(page, 'checkbox');
});
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Some files were not shown because too many files have changed in this diff Show More