Spaces:
Runtime error
Runtime error
Franco Astegiano
commited on
Delete tf2_arbitrary_image_stylization.ipynb
Browse files
examples/colab/tf2_arbitrary_image_stylization.ipynb
DELETED
@@ -1,377 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "markdown",
|
5 |
-
"metadata": {
|
6 |
-
"id": "ScitaPqhKtuW"
|
7 |
-
},
|
8 |
-
"source": [
|
9 |
-
"##### Copyright 2019 The TensorFlow Hub Authors.\n",
|
10 |
-
"\n",
|
11 |
-
"Licensed under the Apache License, Version 2.0 (the \"License\");"
|
12 |
-
]
|
13 |
-
},
|
14 |
-
{
|
15 |
-
"cell_type": "code",
|
16 |
-
"execution_count": null,
|
17 |
-
"metadata": {
|
18 |
-
"id": "jvztxQ6VsK2k"
|
19 |
-
},
|
20 |
-
"outputs": [],
|
21 |
-
"source": [
|
22 |
-
"# Copyright 2019 The TensorFlow Hub Authors. All Rights Reserved.\n",
|
23 |
-
"#\n",
|
24 |
-
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
|
25 |
-
"# you may not use this file except in compliance with the License.\n",
|
26 |
-
"# You may obtain a copy of the License at\n",
|
27 |
-
"#\n",
|
28 |
-
"# http://www.apache.org/licenses/LICENSE-2.0\n",
|
29 |
-
"#\n",
|
30 |
-
"# Unless required by applicable law or agreed to in writing, software\n",
|
31 |
-
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
|
32 |
-
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
|
33 |
-
"# See the License for the specific language governing permissions and\n",
|
34 |
-
"# limitations under the License.\n",
|
35 |
-
"# =============================================================================="
|
36 |
-
]
|
37 |
-
},
|
38 |
-
{
|
39 |
-
"cell_type": "markdown",
|
40 |
-
"metadata": {
|
41 |
-
"id": "oXlcl8lqBgAD"
|
42 |
-
},
|
43 |
-
"source": [
|
44 |
-
"# Fast Style Transfer for Arbitrary Styles\n"
|
45 |
-
]
|
46 |
-
},
|
47 |
-
{
|
48 |
-
"cell_type": "markdown",
|
49 |
-
"metadata": {
|
50 |
-
"id": "MfBg1C5NB3X0"
|
51 |
-
},
|
52 |
-
"source": [
|
53 |
-
"<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
|
54 |
-
" <td>\n",
|
55 |
-
" <a target=\"_blank\" href=\"https://www.tensorflow.org/hub/tutorials/tf2_arbitrary_image_stylization\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />View on TensorFlow.org</a>\n",
|
56 |
-
" </td>\n",
|
57 |
-
" <td>\n",
|
58 |
-
" <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/hub/blob/master/examples/colab/tf2_arbitrary_image_stylization.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
|
59 |
-
" </td>\n",
|
60 |
-
" <td>\n",
|
61 |
-
" <a target=\"_blank\" href=\"https://github.com/tensorflow/hub/blob/master/examples/colab/tf2_arbitrary_image_stylization.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View on GitHub</a>\n",
|
62 |
-
" </td>\n",
|
63 |
-
" <td>\n",
|
64 |
-
" <a href=\"https://storage.googleapis.com/tensorflow_docs/hub/examples/colab/tf2_arbitrary_image_stylization.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />Download notebook</a>\n",
|
65 |
-
" </td>\n",
|
66 |
-
" <td>\n",
|
67 |
-
" <a href=\"https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2\"><img src=\"https://www.tensorflow.org/images/hub_logo_32px.png\" />See TF Hub model</a>\n",
|
68 |
-
" </td>\n",
|
69 |
-
"</table>"
|
70 |
-
]
|
71 |
-
},
|
72 |
-
{
|
73 |
-
"cell_type": "markdown",
|
74 |
-
"metadata": {
|
75 |
-
"id": "YeeuYzbZcJzs"
|
76 |
-
},
|
77 |
-
"source": [
|
78 |
-
"Based on the model code in [magenta](https://github.com/tensorflow/magenta/tree/master/magenta/models/arbitrary_image_stylization) and the publication:\n",
|
79 |
-
"\n",
|
80 |
-
"[Exploring the structure of a real-time, arbitrary neural artistic stylization\n",
|
81 |
-
"network](https://arxiv.org/abs/1705.06830).\n",
|
82 |
-
"*Golnaz Ghiasi, Honglak Lee,\n",
|
83 |
-
"Manjunath Kudlur, Vincent Dumoulin, Jonathon Shlens*,\n",
|
84 |
-
"Proceedings of the British Machine Vision Conference (BMVC), 2017.\n"
|
85 |
-
]
|
86 |
-
},
|
87 |
-
{
|
88 |
-
"cell_type": "markdown",
|
89 |
-
"metadata": {
|
90 |
-
"id": "TaM8BVxrCA2E"
|
91 |
-
},
|
92 |
-
"source": [
|
93 |
-
"## Setup"
|
94 |
-
]
|
95 |
-
},
|
96 |
-
{
|
97 |
-
"cell_type": "markdown",
|
98 |
-
"metadata": {
|
99 |
-
"id": "J65jog2ncJzt"
|
100 |
-
},
|
101 |
-
"source": [
|
102 |
-
"Let's start with importing TF2 and all relevant dependencies."
|
103 |
-
]
|
104 |
-
},
|
105 |
-
{
|
106 |
-
"cell_type": "code",
|
107 |
-
"execution_count": null,
|
108 |
-
"metadata": {
|
109 |
-
"id": "v-KXRY5XBu2u"
|
110 |
-
},
|
111 |
-
"outputs": [],
|
112 |
-
"source": [
|
113 |
-
"import functools\n",
|
114 |
-
"import os\n",
|
115 |
-
"\n",
|
116 |
-
"from matplotlib import gridspec\n",
|
117 |
-
"import matplotlib.pylab as plt\n",
|
118 |
-
"import numpy as np\n",
|
119 |
-
"import tensorflow as tf\n",
|
120 |
-
"import tensorflow_hub as hub\n",
|
121 |
-
"\n",
|
122 |
-
"print(\"TF Version: \", tf.__version__)\n",
|
123 |
-
"print(\"TF Hub version: \", hub.__version__)\n",
|
124 |
-
"print(\"Eager mode enabled: \", tf.executing_eagerly())\n",
|
125 |
-
"print(\"GPU available: \", tf.config.list_physical_devices('GPU'))"
|
126 |
-
]
|
127 |
-
},
|
128 |
-
{
|
129 |
-
"cell_type": "code",
|
130 |
-
"execution_count": null,
|
131 |
-
"metadata": {
|
132 |
-
"id": "tsoDv_9geoZn"
|
133 |
-
},
|
134 |
-
"outputs": [],
|
135 |
-
"source": [
|
136 |
-
"# @title Define image loading and visualization functions { display-mode: \"form\" }\n",
|
137 |
-
"\n",
|
138 |
-
"def crop_center(image):\n",
|
139 |
-
" \"\"\"Returns a cropped square image.\"\"\"\n",
|
140 |
-
" shape = image.shape\n",
|
141 |
-
" new_shape = min(shape[1], shape[2])\n",
|
142 |
-
" offset_y = max(shape[1] - shape[2], 0) // 2\n",
|
143 |
-
" offset_x = max(shape[2] - shape[1], 0) // 2\n",
|
144 |
-
" image = tf.image.crop_to_bounding_box(\n",
|
145 |
-
" image, offset_y, offset_x, new_shape, new_shape)\n",
|
146 |
-
" return image\n",
|
147 |
-
"\n",
|
148 |
-
"@functools.lru_cache(maxsize=None)\n",
|
149 |
-
"def load_image(image_url, image_size=(256, 256), preserve_aspect_ratio=True):\n",
|
150 |
-
" \"\"\"Loads and preprocesses images.\"\"\"\n",
|
151 |
-
" # Cache image file locally.\n",
|
152 |
-
" image_path = tf.keras.utils.get_file(os.path.basename(image_url)[-128:], image_url)\n",
|
153 |
-
" # Load and convert to float32 numpy array, add batch dimension, and normalize to range [0, 1].\n",
|
154 |
-
" img = tf.io.decode_image(\n",
|
155 |
-
" tf.io.read_file(image_path),\n",
|
156 |
-
" channels=3, dtype=tf.float32)[tf.newaxis, ...]\n",
|
157 |
-
" img = crop_center(img)\n",
|
158 |
-
" img = tf.image.resize(img, image_size, preserve_aspect_ratio=True)\n",
|
159 |
-
" return img\n",
|
160 |
-
"\n",
|
161 |
-
"def show_n(images, titles=('',)):\n",
|
162 |
-
" n = len(images)\n",
|
163 |
-
" image_sizes = [image.shape[1] for image in images]\n",
|
164 |
-
" w = (image_sizes[0] * 6) // 320\n",
|
165 |
-
" plt.figure(figsize=(w * n, w))\n",
|
166 |
-
" gs = gridspec.GridSpec(1, n, width_ratios=image_sizes)\n",
|
167 |
-
" for i in range(n):\n",
|
168 |
-
" plt.subplot(gs[i])\n",
|
169 |
-
" plt.imshow(images[i][0], aspect='equal')\n",
|
170 |
-
" plt.axis('off')\n",
|
171 |
-
" plt.title(titles[i] if len(titles) > i else '')\n",
|
172 |
-
" plt.show()\n"
|
173 |
-
]
|
174 |
-
},
|
175 |
-
{
|
176 |
-
"cell_type": "markdown",
|
177 |
-
"metadata": {
|
178 |
-
"id": "8etHh05-CJHc"
|
179 |
-
},
|
180 |
-
"source": [
|
181 |
-
"Let's get as well some images to play with."
|
182 |
-
]
|
183 |
-
},
|
184 |
-
{
|
185 |
-
"cell_type": "code",
|
186 |
-
"execution_count": null,
|
187 |
-
"metadata": {
|
188 |
-
"id": "dRc0vat3Alzo"
|
189 |
-
},
|
190 |
-
"outputs": [],
|
191 |
-
"source": [
|
192 |
-
"# @title Load example images { display-mode: \"form\" }\n",
|
193 |
-
"\n",
|
194 |
-
"content_image_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/Golden_Gate_Bridge_from_Battery_Spencer.jpg/640px-Golden_Gate_Bridge_from_Battery_Spencer.jpg' # @param {type:\"string\"}\n",
|
195 |
-
"style_image_url = 'https://upload.wikimedia.org/wikipedia/commons/0/0a/The_Great_Wave_off_Kanagawa.jpg' # @param {type:\"string\"}\n",
|
196 |
-
"output_image_size = 384 # @param {type:\"integer\"}\n",
|
197 |
-
"\n",
|
198 |
-
"# The content image size can be arbitrary.\n",
|
199 |
-
"content_img_size = (output_image_size, output_image_size)\n",
|
200 |
-
"# The style prediction model was trained with image size 256 and it's the \n",
|
201 |
-
"# recommended image size for the style image (though, other sizes work as \n",
|
202 |
-
"# well but will lead to different results).\n",
|
203 |
-
"style_img_size = (256, 256) # Recommended to keep it at 256.\n",
|
204 |
-
"\n",
|
205 |
-
"content_image = load_image(content_image_url, content_img_size)\n",
|
206 |
-
"style_image = load_image(style_image_url, style_img_size)\n",
|
207 |
-
"style_image = tf.nn.avg_pool(style_image, ksize=[3,3], strides=[1,1], padding='SAME')\n",
|
208 |
-
"show_n([content_image, style_image], ['Content image', 'Style image'])"
|
209 |
-
]
|
210 |
-
},
|
211 |
-
{
|
212 |
-
"cell_type": "markdown",
|
213 |
-
"metadata": {
|
214 |
-
"id": "yL2Bn5ThR1nY"
|
215 |
-
},
|
216 |
-
"source": [
|
217 |
-
"## Import TF Hub module"
|
218 |
-
]
|
219 |
-
},
|
220 |
-
{
|
221 |
-
"cell_type": "code",
|
222 |
-
"execution_count": null,
|
223 |
-
"metadata": {
|
224 |
-
"id": "467AVDSuzBPc"
|
225 |
-
},
|
226 |
-
"outputs": [],
|
227 |
-
"source": [
|
228 |
-
"# Load TF Hub module.\n",
|
229 |
-
"\n",
|
230 |
-
"hub_handle = 'https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2'\n",
|
231 |
-
"hub_module = hub.load(hub_handle)"
|
232 |
-
]
|
233 |
-
},
|
234 |
-
{
|
235 |
-
"cell_type": "markdown",
|
236 |
-
"metadata": {
|
237 |
-
"id": "uAR70_3wLEDB"
|
238 |
-
},
|
239 |
-
"source": [
|
240 |
-
"The signature of this hub module for image stylization is:\n",
|
241 |
-
"```\n",
|
242 |
-
"outputs = hub_module(content_image, style_image)\n",
|
243 |
-
"stylized_image = outputs[0]\n",
|
244 |
-
"```\n",
|
245 |
-
"Where `content_image`, `style_image`, and `stylized_image` are expected to be 4-D Tensors with shapes `[batch_size, image_height, image_width, 3]`.\n",
|
246 |
-
"\n",
|
247 |
-
"In the current example we provide only single images and therefore the batch dimension is 1, but one can use the same module to process more images at the same time.\n",
|
248 |
-
"\n",
|
249 |
-
"The input and output values of the images should be in the range [0, 1].\n",
|
250 |
-
"\n",
|
251 |
-
"The shapes of content and style image don't have to match. Output image shape\n",
|
252 |
-
"is the same as the content image shape."
|
253 |
-
]
|
254 |
-
},
|
255 |
-
{
|
256 |
-
"cell_type": "markdown",
|
257 |
-
"metadata": {
|
258 |
-
"id": "qEhYJno1R7rP"
|
259 |
-
},
|
260 |
-
"source": [
|
261 |
-
"## Demonstrate image stylization"
|
262 |
-
]
|
263 |
-
},
|
264 |
-
{
|
265 |
-
"cell_type": "code",
|
266 |
-
"execution_count": null,
|
267 |
-
"metadata": {
|
268 |
-
"id": "lnAv-F3O9fLV"
|
269 |
-
},
|
270 |
-
"outputs": [],
|
271 |
-
"source": [
|
272 |
-
"# Stylize content image with given style image.\n",
|
273 |
-
"# This is pretty fast within a few milliseconds on a GPU.\n",
|
274 |
-
"\n",
|
275 |
-
"outputs = hub_module(tf.constant(content_image), tf.constant(style_image))\n",
|
276 |
-
"stylized_image = outputs[0]"
|
277 |
-
]
|
278 |
-
},
|
279 |
-
{
|
280 |
-
"cell_type": "code",
|
281 |
-
"execution_count": null,
|
282 |
-
"metadata": {
|
283 |
-
"id": "OEAPEdq698gs"
|
284 |
-
},
|
285 |
-
"outputs": [],
|
286 |
-
"source": [
|
287 |
-
"# Visualize input images and the generated stylized image.\n",
|
288 |
-
"\n",
|
289 |
-
"show_n([content_image, style_image, stylized_image], titles=['Original content image', 'Style image', 'Stylized image'])"
|
290 |
-
]
|
291 |
-
},
|
292 |
-
{
|
293 |
-
"cell_type": "markdown",
|
294 |
-
"metadata": {
|
295 |
-
"id": "v-gYvjTWK-lx"
|
296 |
-
},
|
297 |
-
"source": [
|
298 |
-
"## Let's try it on more images"
|
299 |
-
]
|
300 |
-
},
|
301 |
-
{
|
302 |
-
"cell_type": "code",
|
303 |
-
"execution_count": null,
|
304 |
-
"metadata": {
|
305 |
-
"id": "WSMaY0YBNfkK"
|
306 |
-
},
|
307 |
-
"outputs": [],
|
308 |
-
"source": [
|
309 |
-
"# @title To Run: Load more images { display-mode: \"form\" }\n",
|
310 |
-
"\n",
|
311 |
-
"content_urls = dict(\n",
|
312 |
-
" sea_turtle='https://upload.wikimedia.org/wikipedia/commons/d/d7/Green_Sea_Turtle_grazing_seagrass.jpg',\n",
|
313 |
-
" tuebingen='https://upload.wikimedia.org/wikipedia/commons/0/00/Tuebingen_Neckarfront.jpg',\n",
|
314 |
-
" grace_hopper='https://storage.googleapis.com/download.tensorflow.org/example_images/grace_hopper.jpg',\n",
|
315 |
-
" )\n",
|
316 |
-
"style_urls = dict(\n",
|
317 |
-
" kanagawa_great_wave='https://upload.wikimedia.org/wikipedia/commons/0/0a/The_Great_Wave_off_Kanagawa.jpg',\n",
|
318 |
-
" kandinsky_composition_7='https://upload.wikimedia.org/wikipedia/commons/b/b4/Vassily_Kandinsky%2C_1913_-_Composition_7.jpg',\n",
|
319 |
-
" hubble_pillars_of_creation='https://upload.wikimedia.org/wikipedia/commons/6/68/Pillars_of_creation_2014_HST_WFC3-UVIS_full-res_denoised.jpg',\n",
|
320 |
-
" van_gogh_starry_night='https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg/1024px-Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg',\n",
|
321 |
-
" turner_nantes='https://upload.wikimedia.org/wikipedia/commons/b/b7/JMW_Turner_-_Nantes_from_the_Ile_Feydeau.jpg',\n",
|
322 |
-
" munch_scream='https://upload.wikimedia.org/wikipedia/commons/c/c5/Edvard_Munch%2C_1893%2C_The_Scream%2C_oil%2C_tempera_and_pastel_on_cardboard%2C_91_x_73_cm%2C_National_Gallery_of_Norway.jpg',\n",
|
323 |
-
" picasso_demoiselles_avignon='https://upload.wikimedia.org/wikipedia/en/4/4c/Les_Demoiselles_d%27Avignon.jpg',\n",
|
324 |
-
" picasso_violin='https://upload.wikimedia.org/wikipedia/en/3/3c/Pablo_Picasso%2C_1911-12%2C_Violon_%28Violin%29%2C_oil_on_canvas%2C_Kr%C3%B6ller-M%C3%BCller_Museum%2C_Otterlo%2C_Netherlands.jpg',\n",
|
325 |
-
" picasso_bottle_of_rum='https://upload.wikimedia.org/wikipedia/en/7/7f/Pablo_Picasso%2C_1911%2C_Still_Life_with_a_Bottle_of_Rum%2C_oil_on_canvas%2C_61.3_x_50.5_cm%2C_Metropolitan_Museum_of_Art%2C_New_York.jpg',\n",
|
326 |
-
" fire='https://upload.wikimedia.org/wikipedia/commons/3/36/Large_bonfire.jpg',\n",
|
327 |
-
" derkovits_woman_head='https://upload.wikimedia.org/wikipedia/commons/0/0d/Derkovits_Gyula_Woman_head_1922.jpg',\n",
|
328 |
-
" amadeo_style_life='https://upload.wikimedia.org/wikipedia/commons/8/8e/Untitled_%28Still_life%29_%281913%29_-_Amadeo_Souza-Cardoso_%281887-1918%29_%2817385824283%29.jpg',\n",
|
329 |
-
" derkovtis_talig='https://upload.wikimedia.org/wikipedia/commons/3/37/Derkovits_Gyula_Talig%C3%A1s_1920.jpg',\n",
|
330 |
-
" amadeo_cardoso='https://upload.wikimedia.org/wikipedia/commons/7/7d/Amadeo_de_Souza-Cardoso%2C_1915_-_Landscape_with_black_figure.jpg'\n",
|
331 |
-
")\n",
|
332 |
-
"\n",
|
333 |
-
"content_image_size = 384\n",
|
334 |
-
"style_image_size = 256\n",
|
335 |
-
"content_images = {k: load_image(v, (content_image_size, content_image_size)) for k, v in content_urls.items()}\n",
|
336 |
-
"style_images = {k: load_image(v, (style_image_size, style_image_size)) for k, v in style_urls.items()}\n",
|
337 |
-
"style_images = {k: tf.nn.avg_pool(style_image, ksize=[3,3], strides=[1,1], padding='SAME') for k, style_image in style_images.items()}\n"
|
338 |
-
]
|
339 |
-
},
|
340 |
-
{
|
341 |
-
"cell_type": "code",
|
342 |
-
"execution_count": null,
|
343 |
-
"metadata": {
|
344 |
-
"id": "dqB6aNTLNVkK"
|
345 |
-
},
|
346 |
-
"outputs": [],
|
347 |
-
"source": [
|
348 |
-
"#@title Specify the main content image and the style you want to use. { display-mode: \"form\" }\n",
|
349 |
-
"\n",
|
350 |
-
"content_name = 'sea_turtle' # @param ['sea_turtle', 'tuebingen', 'grace_hopper']\n",
|
351 |
-
"style_name = 'munch_scream' # @param ['kanagawa_great_wave', 'kandinsky_composition_7', 'hubble_pillars_of_creation', 'van_gogh_starry_night', 'turner_nantes', 'munch_scream', 'picasso_demoiselles_avignon', 'picasso_violin', 'picasso_bottle_of_rum', 'fire', 'derkovits_woman_head', 'amadeo_style_life', 'derkovtis_talig', 'amadeo_cardoso']\n",
|
352 |
-
"\n",
|
353 |
-
"stylized_image = hub_module(tf.constant(content_images[content_name]),\n",
|
354 |
-
" tf.constant(style_images[style_name]))[0]\n",
|
355 |
-
"\n",
|
356 |
-
"show_n([content_images[content_name], style_images[style_name], stylized_image],\n",
|
357 |
-
" titles=['Original content image', 'Style image', 'Stylized image'])"
|
358 |
-
]
|
359 |
-
}
|
360 |
-
],
|
361 |
-
"metadata": {
|
362 |
-
"accelerator": "GPU",
|
363 |
-
"colab": {
|
364 |
-
"collapsed_sections": [],
|
365 |
-
"name": "TF-Hub: Fast Style Transfer for Arbitrary Styles.ipynb",
|
366 |
-
"private_outputs": true,
|
367 |
-
"provenance": [],
|
368 |
-
"toc_visible": true
|
369 |
-
},
|
370 |
-
"kernelspec": {
|
371 |
-
"display_name": "Python 3",
|
372 |
-
"name": "python3"
|
373 |
-
}
|
374 |
-
},
|
375 |
-
"nbformat": 4,
|
376 |
-
"nbformat_minor": 0
|
377 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|