О Google Gears можно услышать довольно много чего интересного. Дескать, есть такой мегаплагин, добавляет кучу возможностей. И еще - с ним можно оптимизировать сайты.
Посмотрим подробнее, что это такое, для чего он нужен, что умеет.
Эта статья не ставит своей целью заменить документацию по Google Gears (которой, к сожалению, нет на русском языке). Ее цель - показать основные возможности Google Gears и существующие способы их применения, включая использование Gears в Joomla, Wordpress, Youtube.
UPDATE: в связи с тем, что технология умерла, статья имеет интерес разве что исторический.
Google Gears (или просто Gears) - плагин для браузера. На момент написания статьи работает во всех современных браузерах, кроме Safari 4 и Opera Desktop до 10 версии включительно.
Конечно, этот плагин надо ставить. Обычно браузер предлагает это сделать в виде выпадающего сообщения.
В спецификации HTML 5 предусмотрено хранение и доступ к данным при помощи SQL: Offline Web Applications. Эта возможность поддерживается в Safari.
Google Gears пошел другим путем и предоставляет свой SQL-интерфейс Database API.
Основное отличие - в Gears запросы к базе синхронные, а в HTML 5 - асинхронные (назначается callback на получение результата). Это удобно, т.к. для асинхронности в gears можно использовать многопоточность там, где это нужно.
Удалены некоторые возможности SQLite - в основном это касается работы напрямую с файловой системой и системных опций.
Жестко задана кодировка: UTF-8.
Есть полнотекстовой поиск FTS2 (не для русского языка).
Файл с базой хранится внутри домашней директории пользователя. Таким образом, разграничение доступа между пользователями компьютера осуществляется средствами OS.
Одновременно в базу может писать только один процесс - иначе генерируется исключение.
Много баз данных. Но базы привязаны к текущему протоколу-порту-домену. То есть, базы с одинаковым именем для разных сайтов никак не пересекаются (Same Origin), и залезть с одного сайта в базу другого нельзя.
Доступ к базе требует разрешения от посетителя.
Следующий пример создаст базу и таблицу (если не существует) и добавит туда запись. Многократный запуск добавит много записей, который сохранятся в базе на локальном компьютере.
Пример: Записать в таблицу и сделать выборку
var db = google.gears.factory.create('beta.database');
db.open('js');
db.execute('create table if not exists test(phrase text, created datetime)');
var phrase = prompt("Введите фразу")
db.execute('insert into test values (?, datetime())', [phrase])
var rs = db.execute('select * from test order by created desc')
while (rs.isValidRow()) {
alert(rs.field(0) + ' создано ' + rs.field(1))
rs.next()
}
rs.close()
Пример: Удалить базу
var db = google.gears.factory.create('beta.database')
db.open('js')
db.remove()
Здесь, как и в дальнейших примерах, пропущена проверка ошибок выполнения. Например, посетитель может запретить Google Gears. При любых ошибках gears инициирует исключения, которые легко поймать конструкцией try..catch.
Многопоточность, а точнее, многопроцессность - пожалуй, самая интересная возможность Google Gears.
Каждый новый поток является отдельным процессом со своими переменными и средой выполнения.
Реализуется она при помощи WorkerPool API, которое представляет собой вольную переработку черновика Web Workers из HTML5.
Новые процессы запускаются вызовом createWorker/createWorkerFromUri класса WorkerPool.
// получить разрешение на доступ к WorkerPool
workerPool = google.gears.factory.create('beta.workerpool')
// создать новый процесс, загрузить для выполнения скрипт worker.js
int childId = workerPool.createWorkerFromUrl('/files/gears/worker.js')
Эти методы возвращают идентификатор, который мы можем использовать для общения с процессом.
Чтобы принять сообщение, в скрипте дочернего процесса (worker.js) должен быть определен метод onmessage на неявно передаваемом в дочерний поток объекте google.gears.workerPool:
Дочерние процессы не имеют доступа к объектам document и window. Для рисования используйте основной javascript-процесс. А вместо XmlHttpRequest и setTimeout/setInterval, которые есть в window, Gears предоставляет сходные аналоги: HttpRequest и Timer.
Невозможна одновременная запись в базу с разных потоков. Один запишет, другие получат исключения. Соответственно, нужно закладывать в код обработку исключений и повторение SQL-запроса.
Метод createWorkerFromUrl не работает из дочерних процессов. В них можно использовать метод createWorker, которому передается не URL, а текст скрипта.
Локальный сервер - пожалуй, самая востребованная часть Google Gears API.
По смыслу - это не совсем тот сервер, о котором привык слышать веб-разработчик.
Он умеет две основные вещи.
Загружать одну страницу или их список в локальное хранилище
Неявно перехватывать обращения браузера к загруженным страницам и отдавать их из локального хранилища.
Разумеется, поддерживается и обновление локального хранилища.
Хранилище работает в рамках стандартного контекста безопасности Same Origin, так что сохранить локально можно только страницы с текущего протокола-домена-порта.
createStore / openStore / removeStore - для управления хранилищем типа ResourceStore
createManagedStore / openManagedStore / removeManagedStore - для управления хранилищем типа ManagedResourceStore
Таким образом, можно создавать именованные хранилища двух видов, которые различаются логикой хранения и обновления.
Если запрошенная посетителем страница есть в хранилище - запрос будет перехвачен LocalServer'ом, и она будет взята из локального хранилища, а не с удаленного сервера.
Функции LocalServer предусматривают также атрибут requiredCookie, который может ограничивать доступ к хранилищу и требовать наличия, либо отсутствия у посетителя заданного cookie.
Таким образом, можно например привязать хранилище к ID посетителя:
var localServer = google.gears.factory.create('beta.localserver')
// создать или открыть, если есть
var store = localServer.createManagedStore('data', 'userid=123')
Данные этого хранилища будут доступны только посетителю с cookie: userid=123.
Конечно, эта мера скорее нацелена на удобство, нежели на безопасность.
Но часто бывает, что у одного человека есть несколько аккаунтов, скажем, почтовых, и здесь ограничение requiredCookie может быть как нельзя более удобно.
У каждого хранилища есть атрибут enabled, который позволяет включать или отключать его, при этом не удаляя данные. Он наиболее полезен при отладке, рабочие приложения его обычно не используют.
Это хранилище целиком настраивается на клиенте. Оно позволяет получать с сервера произвольные страницы (или сразу много страниц).
Основной метод: capture(urlOrUrlArray, callback) - получает и сохраняет страницы с сервера.
Для примера посмотрим на таймер. Это обычный div, для которого javascript при помощи xmlhttprequest раз в секунду запрашивает с сервера страницу time.php с текущим серверным временем и выводит ее в div с id="timer".
Кликните, пожалуйста, на кнопку запуска для активации кода таймера:
// используется jQuery функция load, получающая данные
// при помощи XMLHttpRequest
setInterval(function() { $('#timer').load('/files/gears/time.php') }, 1000)
После того, как вы запустите следующий код, время застынет, т.к. страница time.php, содержимое которой ежесекундно попадает в div, станет отдаваться не с сервера, а с вашей машины.
Пример: Загрузить страницу в хранилище
var localServer = google.gears.factory.create('beta.localserver')
var store = localServer.createStore('time-store')
store.capture(
"/files/gears/time.php",
function() { alert('Страница загружена в хранилище') }
)
А этот код удалит страницу из хранилища, после чего таймер опять заработает.
Пример: Удалить страницу из хранилища
var localServer = google.gears.factory.create('beta.localserver')
var store = localServer.createStore('time-store')
store.remove("/files/gears/time.php")
alert('Страница удалена из хранилища')
Для хранилища нет разницы, как запрашивается страница: напрямую или через xmlhttprequest - оно проверяет точное совпадение URL и возвращает страницу из хранилища, если она там есть.
Если не запускать обновления явным образом при помощи checkForUpdate - Gears будет проверять обновления (запрашивать сервер) самостоятельно при каждом получении страницы из хранилища, но не чаще чем раз в 10 секунд.
В этом - важное отличие от обычного ResourceStore, которое обновляется только "вручную".
Как правило, набор статических файлов (картинок, стилей, скриптов) - не меняется в пределах версии сайта/релиза/"апа"/"деплоя на продакшн".
Поэтому, указав эту версию в манифесте (например, точную дату или ревизию), и собрав в нем всю статику, можно позволить Gears один раз загрузить весь набор и навсегда (до следующей версии) избавить посетителя от лишних запросов к серверу.
Все картинки, скрипты и т.п. Gears будет возвращать из соответствующего ManagedResourceStore.
Таким образом оптимизируют свои админки контент-системы, такие как Joomla, Wordpress и т.п.
Хотя для такой настройки сервера есть ряд ограничений, в частности, в URL лучше не иметь знак вопроса - некоторые браузеры не будут жестко кешировать такие страницы, она вполне применима и отлично работает. Без Gears. Более подробно - описано в самой статье.
ManagedResourceStore почти не требует изменения в приложении, просто пишется небольшой дополнительный код для создания и обновления манифеста.
Умное кеширование позволяет обновить один ресурс, не затрагивая остальные
ManagedResourceStore позволяет:
указать опции сравнения: ignoreQuery/matchQuery
выбирать хранилище по имени в методе openManagedStore
ограничить хранилище указанием requiredCookie
Как видите, есть место для обоих технологий.
Кстати, о плагинах...
В Firefox к Gears имеют доступ расширения. Это можно использовать. Например, Greasemonkey может запускать пользовательские скрипты для сайта.
Такой скрипт может загружать статику в локальное хранилище вне зависимости от поддержки Gears сайтом.
Таким образом оптимизация сайта может быть сделана на стороне посетителя, независимо от поддержки сайтом разных полезных технологий
Все начинается с класса Desktop, метода openFiles.
Он позволяет посетителю выбрать несколько файлов "родным" селектором операционной системы. Например, в Windows можно выделить файлы мышкой.
Первый аргумент - функция, которой будут передан
ы выбранные файлы, вторым можно указать объект опций с параметрами filter/singleFile (см. OpenFileOptions).
var desktop = google.gears.factory.create('beta.desktop');
desktop.openFiles(
function (files) { alert('Выбрано файлов: ' + files.length) }
)
Вызвать эту функцию можно, например, при клике на кнопку, то есть вообще без элемента типа <input type="file">.
Файлы передаются в виде массива объектов типа File.
Каждый файл имеет имя name и содержимое blob.
Доступ к содержимому файла предоставляет наибольший интерес.
Это объект типа Blob.
Gears предоставляет следующие возможности для манипуляции Blob.
Canvas API позволяет делать операции crop/resize над файлами-изображениями.
Blob API дает возможность вырезать часть Blob'а, а BlobBuilder - добавить данные к существующему Blob
Локальное хранилище ResourceStore предоставляет метод getAsBlob(url), возвращающий полученный ресурс в виде Blob. Таким образом, Blob можно получить из файла с сервера
HttpRequest (аналог XmlHttpRequest) умеет отправлять Blob на сервер и возвращать текущее состояние процесса загрузки ProgressEvent.
Сетевые операции, как и все операции gears, выполняются только в контексте текущего протокола-домена-порта (same origin).
Gears, по возможности не хранит весь Blob в памяти. Для файлов Blob - это лишь указатель на файл, который может быть размером в сотни и тысячи мегабайт. При этом если файл меняется в процессе работы, и какие-то операции становятся некорректными (например, файл удален с диска) - Gears инициирует исключение.
Что это дает на практике?
Для картинок - можно обрабатывать их локально (на уровне crop/resize). Объект Canvas умеет делать операции над Blob, но не умеет показывать картинку на экране.
Поэтому показ картинки (и вообще, типичный способ добавления Blob в DOM) состоит из следующих шагов:
Подготовить объект типа Blob
Загрузить его в локальное хранилище типа ResourceStore, используя метод captureBlob(Blob blob, string url, string optContentType)
Вставить на страницу элемент, который прочитает данные с адреса url, например <img src="url">
Следующий пример масштабирует выбранную картинку до размера 150x150 без сохранения пропорций и показывает результат. А может отправить получившееся изображение на сервер и т.п.
Конечно, не всем нужно масштабировать картинки, но пример - типовой и демонстрирует один из вариантов использования разных компонент gears вместе.
Контейнер для картинки:
function resize() {
var desktop = google.gears.factory.create('beta.desktop');
// опция singleFile для выбора не более одного файла
desktop.openFiles(resizeAndShow,
{ singleFile : true, filter: ['image/jpeg', 'image/gif', 'image/png'] }
)
}
function resizeAndShow(files) {
// (1)
var canvas = google.gears.factory.create('beta.canvas');
canvas.decode(files[0].blob)
canvas.resize(150,150)
var blob = canvas.encode("image/jpeg")
// (2)
var localServer = google.gears.factory.create('beta.localserver')
var store = localServer.createStore('store')
// (2.1)
var url = '/img.jpg?'+Math.random()
store.captureBlob(blob, url, "image/jpeg")
// (3)
$('#resized').css('background-image', 'url('+url+')')
$('#resized')[0].scrollIntoView()
// (4)
setTimeout(function (){store.remove(url)},0)
}
Функция resize запускает выбор файла, а resizeAndShow выполняет основные операции.
Рассмотрим ее более подробно.
Декодировать картинку из содержимого первого (в нашем случае - единственного) выбранного файла, отмасштабировать ее, а затем обратно закодировать в Blob.
Инициализовать хранилище
Положить картинку в хранилище по временному адресу, чтобы затем браузер отобразил ее, обратившись по нему. Используется временный URL.
Чтобы избежать возможного кеширования, он выбирается случайным образом.
Хранилище ResourceStore возвратит картинку только при полном совпадении url, так что конфликта с обычным изображением img.jpg не возникнет.
При записи картинки в хранилище явно указан тип содержания: image/jpeg
Использовать URL с картинкой в качестве фона для контейнера. Вторая строчка прокручивает страницу, чтобы сделать контейнер видимым.
Мы использовали хранилище с временным URL для показа картинки. После того, как картинка будет показана, стоит почистить хранилище. Оно хранится на компьютере посетителя, и не стоит забивать его излишним мусором.
Если убрать setTimeout, то remove выполнится тут же, до того как браузер отрендерит background-image. Использование setTimeout откладывает вызов, так что он произойдет после показа картинки.
Как видно из примера, компоненты Gears отлично пригнаны друг к другу и замечательно взаимодействуют между собой.
Пользователь выбирает файлы при помощи desktop.openFiles, что дает нам содержимое файла в виде объекта Blob
Для отправки файла на сервер инициализуется объект up.SingleUploader.
Файл пересылается по частям, максимальный размер части задан константой up.CHUNK_SIZE. Пересылку каждой части выполняет метод upload_.
Внутри upload_ первый, а затем и каждый следующий кусок выдирается из файла в виде строки вызовом Blob API: file.blob.slice. Текущая позиция в файле сохраняется в свойстве offset.
Подготавливаются стандартные заголовки загрузки файла, включая Content-Disposition, а также добавляются заголовки с авторизационными данными и идентификатор пересылки.
Данные файла, заголовки и каллбэки отправляются на выполнение Worker'у, который отсылает запрос на сервер
По мере выполнения запроса HttpRequest вызывает событие onprogress. Это событие Worker через каллбэк транслирует основному процессу, который рисует progress bar.
По завершении закачки Worker вызывает каллбэк основного процесса onUploadComplete_, который, если все в порядке, снова вызывает upload_ (см. 4).
Метод upload_, как только увидит (сравнив offset с размером файла), что пересылка подошла к концу, вызывает finishUpload_
Серверная часть отслеживает пересылку по идентификатору пересылки и собирает большой файл по частям.
Конкретные детали, если они вам понадобятся, вы без труда поймете из кода. Все реализуется корректно и без каких-либо хаков.
Надо сказать, идея Youtube не нова. Такой способ отсылки запросов на сервер можно использовать и со стандартным XMLHTTPRequest. Другое дело, что передать содержимое файла XMLHTTPRequest средствами стандартного javascript нельзя.
Да и остальные компоненты Gears здесь как нельзя кстати.
На этом описание возможностей Google Gears подошло к концу. Все основные возможности мы разобрали.
Остались всего несколько небольших.
Создание shortcut на рабочем столе с указанием иконки через URL. Делается desktop.createShortcut (Google demo)
Получение текущего местоположения позиции вызовом Geolocation API - работает, в том числе, и для мобильных устройств.
Принятие Drag'n'drop объектов на уровне OS (перенос объектов в окошко браузера) при помощи Desktop API.
Эта часть HTML5 частично реализована в Firefox 3.5, но Gears позволяет читать содержимое перенесенных файлов.
Разобраться с этими возможностями вы легко сможете из примеров. Пока я не встречал их удачного применения в известных приложениях, но кто знает - может быть, вы будете первым.
Thanks for a wonderful share. Your article has proved your hard work and experience you have got in this field. Brilliant .i love it reading. fmcg distribution company in Nigeria
Astounding read, Positive webpage, where did u think of the data on this posting?I have perused a couple of the articles on your site now, and I extremely like your style. You rock and please keep up the compelling work. 먹튀사이트
Interesting post. I Have Been wondering about this issue, so thanks for posting. Pretty cool post.It 's really very nice and Useful post.Thanks 레플리카사이트
Interesting post. I Have Been wondering about this issue, so thanks for posting. Pretty cool post.It 's really very nice and Useful post.Thanks 레플리카사이트
nice post, keep up with this interesting work. It really is good to know that this topic is being covered also on this web site so cheers for taking time to discuss this! 강남오피
I have read your article, it is very informative and helpful for me.I admire the valuable information you offer in your articles. Thanks for posting it.. custom laptop brands
This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work Real estate Playa Del Carmen
Thanks for posting this info. I just want to let you know that I just check out your site and I find it very interesting and informative. I can't wait to read lots of your posts. Information Technology
Truly, this article is really one of the very best in the history of articles. I am a antique ’Article’ collector and I sometimes read some new articles if I find them interesting. And I found this one pretty fascinating and it should go into my collection. Very good work! agen bandarq online
I’ve been searching for some decent stuff on the subject and haven't had any luck up until this point, You just got a new biggest fan!.. email marketing companies
Positive site, where did u come up with the information on this posting? I'm pleased I discovered it though, ill be checking back soon to find out what additional posts you include. email marketing companies
I really thank you for the valuable info on this great subject and look forward to more great posts. Thanks a lot for enjoying this beauty article with me. I am appreciating it very much! Looking forward to another great article. Good luck to the author! All the best! Valves in uae
I've been using WordPress on a number of websites for about a year and am worried about switching to another platform. I have heard good things about keo nhacai. Is there a way I can transfer all my wordpress content into it? Any help would be really appreciated!
Thank you so much for sharing this great blog.Very inspiring and helpful too.Hope you continue to share more of your ideas.I will definitely love to read. Arborist
I'm glad I found this web site, I couldn't find any knowledge on this matter prior to.Also operate a site and if you are ever interested in doing some visitor writing for me if possible feel free to let me know, i am always look for people to check out my web site. zinc citrate
Wonderful article, thanks for putting this together! This is obviously one great post. Thanks for the valuable information and insights you have so provided here. carte yugioh
Superbly written article. if only all bloggers offered the same content as you. the internet would be a far better place.. business for sale south africa
Yes i am completely concurred with this article and i simply need say this article is extremely decent and exceptionally useful article.I will make a point to be perusing your blog more. You made a decent point yet I can"t resist the urge to ponder, shouldn"t something be said about the other side? 토토사이트추천
This is very educational content and written well for a change. It's nice to see that some people still understand how to write a quality post! governance risk compliance gdpr software
I think this is an informative post and it is very useful and knowledgeable. therefore. I would like to thank you for the efforts you have made in writing this article. xerium
I found that site very usefull and this survey is very cirious. I ' ve never seen a blog that demand a survey for this actions. very curious... redraiderrvpark
안전놀이터 With the victory, Ginseng Corporation scored 14 wins and 15 losses and 43 points in the season. On the other hand, Hyundai Engineering & Construction suffered its first consecutive loss of the season
Its a great pleasure reading your post.Its full of information I am looking for and I love to post a comment that "The content of your post is awesome" Great work. a course in miracles
https://mukoff.com/
Last week, deputies were called to a San Marin daycare owned by Goularte's mother regarding an alleged sexual assault involving a child, the Santa Clara County Sheriff's Office said in a statement Wednesday.
An intriguing discussion may be worth comment. I’m sure you should write much more about this topic, may well be described as a taboo subject but generally folks are too little to chat on such topics. An additional. Cheers 메이저토토사이트
Thanks for your post. The article is neatly organized with the information I want, so there are many things to refer to. Bookmark this site and visit often in the future. Thanks again.^^ keonhacai
I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post. cameronjamesusa
I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post. cameronjamesusa
Sex in Berlin Ogłoszenia kontaktowe to, że tak powiem, standardowe serwisy randkowe, w których single rejestrują się, tworzą profil i za jego pomocą ujawniają publicznie informacje o sobie. Istnieją oczywiście liczne odmiany tego typu stron, np. strony poświęcone związkom dla określonych grup ludzi (gotów, rozwodników, społeczności LGBT itp.). Serwisy randkowe umożliwiają także wyszukiwanie osób na podstawie różnych czynników (wiek, wzrost, lokalizacja, odległość, zainteresowania itp.)
We are looking for a lot of data on this item. In the meantime, this is the perfect article I was looking for . Please post a lot about items related to 비아그라구매 !!! I am waiting for your article. And when you are having difficulty writing articles, I think you can get a lot of help by visiting my .
I visited last Monday, and in the meantime, I came back in 우리카지노계열 anticipation that there might be other articles related to I know there is no regret and leave a comment. Your related articles are very good, keep going!!
It seems like I've never seen an article of a kind like . It literally means the best thorn. It seems to be a fantastic article. It is the best among articles related to 열공캔디 . seems very easy, but it's a difficult kind of article, and it's perfect.
It's very interesting. And it's fun. This is a timeless article. I also write articles related to , and I run a community related to 비아그라 . For more information, please feel free to visit !!
This is a smart blog. I mean it. You have so much knowledge about this issue, and so much passion. You also know how to make people rally behind it, obviously from the responses.
When did it start? The day I started surfing the Internet to read articles related to . I've been fond of seeing various sites related to 비아그라구매 around the world for over 10 years. Among them, I saw your site writing articles related to and I am very satisfied.
I always think about what is. It seems to be a perfect article that seems to blow away such worries. 마하캔디 seems to be the best way to show something. When you have time, please write an article about what means!!
I'm so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.
Hello! Nice to meet you, I say . The name of the community I run is 해머캔디 , and the community I run contains articles similar to your blog. If you have time, I would be very grateful if you visit my site .
I accidentally searched and visited your site. I still saw several posts during my visit, but the text was neat and readable. I'll quote this post and post it on my blog. Would you like to visit my blog later? 온라인카지노사이트
I accidentally searched and visited your site. I still saw several posts during my visit, but the text was neat and readable. I'll quote this post and post it on my blog. Would you like to visit my blog later? 온라인카지노사이트
ZFVDFG
Which is some inspirational stuff. Never knew that opinions might be this varied. Thank you for all the enthusiasm to provide such helpful information here.베트남 황제투어 It helped me a lot. If you have time, I hope you come to my site and share your opinions. Have a nice day.
After study a handful of the blog posts with your internet site now, we truly like your technique for blogging. I bookmarked it to my bookmark internet site list and are checking back soon. 다낭 밤문화
Hello! I could have sworn I've been to this site before but after checking through some of the post I realized it's new to me. Nonetheless, I'm definitely happy I found keonhacai and I'll be book-marking and checking back frequently!
What a nice post! I'm so happy to read this. 해머캔디효과 What you wrote was very helpful to me. Thank you. Actually, I run a site similar to you. If you have time, could you visit my site? Please leave your comments after reading what I wrote. If you do so, I will actively reflect your opinion. I think it will be a great help to run my site. Have a good day.
I finally found what I was looking for! I'm so happy. 해머캔디가격 Your article is what I've been looking for for a long time. I'm happy to find you like this. Could you visit my website if you have time? I'm sure you'll find a post of interest that you'll find interesting.
I’m not sure exactly why but this weblog is loading incredibly slow for me. Is anyone else having this problem or is it a problem on my end? I’ll check back later on and see if the problem still exists. 바카라사이트추천
fhj
I've been troubled for several days with this topic. 카지노사이트, But by chance looking at your post solved my problem! I will leave my blog, so when would you like to visit it?
I've been looking for photos and articles on this topic over the past few days due to a school assignment, 온라인카지노 and I'm really happy to find a post with the material I was looking for! I bookmark and will come often! Thanks
Of course, your article is good enough, 카지노사이트 but I thought it would be much better to see professional photos and videos together. There are articles and photos on these topics on my homepage, so please visit and share your opinions.
Of course, your article is good enough, 카지노사이트 but I thought it would be much better to see professional photos and videos together. There are articles and photos on these topics on my homepage, so please visit and share your opinions.
This is the post I was looking for. I am very happy to read this article. If you have time, please come to my site 카지노사이트 and share your thoughts. Have a nice day.
cfhhh
I've been reading all the articles related to 플레이포커머니상 for the past hour, but I don't know why I saw this post now. It seems like very useful information.
I love seeing more and more people visiting your blog. I, who have been together for a long time, created a forum with the same topic as yours this time. The subject is going to be captured by 플레이포커머니상.
Your ideas have inspired me a lot. I want to learn your writing skills. There is also a website. Please visit us and leave your comments. Thank you. 온라인카지노
gfjh
Your ideas have inspired me a lot. I want to learn your writing skills. There is also a website. Please visit us and leave your comments. Thank you. 온라인카지노
fdhh
It is my first visit to your blog, and I am very impressed with the articles that you serve. Give adequate knowledge for me. Thank you for sharing useful material. I will be back for the more great post. 카지노게임사이트 But by chance looking at your post solved my problem! I will leave my blog, so when would you like to visit it?!
ghjj
What a post I've been looking for! I'm very happy to finally read this post. 토토사이트 Thank you very much. Can I refer to your post on my website? Your post touched me a lot and helped me a lot. If you have any questions, please visit my site and read what kind of posts I am posting. I am sure it will be interesting.
Someone necessarily help to make severely articles I might state. That is the first time I frequented your web page and up to now? I surprised with the analysis you made to create this actual publish extraordinary. Fantastic process 하하포커
Your ideas inspired me very much. 토토사이트순위 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thank you.
I'm so happy to finally find a post with what I want. 토토사이트모음 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.
What a nice post! I'm so happy to read this. 온라인카지노 What you wrote was very helpful to me. Thank you. Actually, I run a site similar to you. If you have time, could you visit my site? Please leave your comments after reading what I wrote. If you do so, I will actively reflect your opinion. I think it will be a great help to run my site. Have a good day.
Thanks for your personal marvelous posting! I quite enjoyed reading it, you will be a great author. I will always bookmark your blog and will come back down the road. I want to encourage one to continue your great posts, have a nice morning! pgslot168" title="pgslot168">pgslot168
Thanks for another informative site. The place else may I get that kind of info written in such a perfect way? I’ve a venture that I’m just now operating on, and I have been on the glance out for such info. ufa168
It’s really a great and helpful piece of info. I’m glad that you shared this helpful info with us. Please keep us up to date like this. Thanks for sharing. biogaming vip
THE ONE CARGO รับนำเข้าสินค้าจีน เว็บ สั่งสินค้าจากจีน ที่ช่วยดูแลทุกการนำเข้าจนถึงหน้าบ้านคุณ ช่วยคุยติดต่อ โรงงาน ร้านค้าแหล่งขายส่ง มีล่ามช่วยแก้ปัญหาต่อราคาคุยกับร้านจีนให้ มีระบบติดตามสถานะพัสดุ พร้อมแจ้งเตื่อนเข้า Line
Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены. Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Thanks for a wonderful share. Your article has proved your hard work and experience you have got in this field. Brilliant .i love it reading.
fmcg distribution company in Nigeria
Astounding read, Positive webpage, where did u think of the data on this posting?I have perused a couple of the articles on your site now, and I extremely like your style. You rock and please keep up the compelling work. 먹튀사이트
Interesting post. I Have Been wondering about this issue, so thanks for posting. Pretty cool post.It 's really very nice and Useful post.Thanks
레플리카사이트
Interesting post. I Have Been wondering about this issue, so thanks for posting. Pretty cool post.It 's really very nice and Useful post.Thanks
레플리카사이트
Interesting post. I Have Been wondering about this issue, so thanks for posting. Pretty cool post.It 's really very nice and Useful post.Thanks
레플리카사이트
gratis sex chat – for more interesting informations!
I have been checking out a few of your stories and i can state pretty good stuff. I will definitely bookmark your blog
my lowes life
Love to read it,Waiting For More new Update and I Already Read your Recent Post its Great Thanks.
출장마사지
Love what you're doing here guys, keep it up!..
Cherada
nice post, keep up with this interesting work. It really is good to know that this topic is being covered also on this web site so cheers for taking time to discuss this!
강남오피
I have read your article, it is very informative and helpful for me.I admire the valuable information you offer in your articles. Thanks for posting it..
custom laptop brands
This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles, I guess I am not the only one having all the enjoyment here! keep up the good work
Real estate Playa Del Carmen
Nice post! This is a very nice blog that I will definitively come back to more times this year! Thanks for informative post.
Online Books Portal
Thanks for your information, it was really very helpfull..
Tony robbins Books
Nice Informative Blog having nice sharing..
Tony robbins Books
Thanks for posting this info. I just want to let you know that I just check out your site and I find it very interesting and informative. I can't wait to read lots of your posts.
Information Technology
The information you have posted is very useful. The sites you have referred was good. Thanks for sharing this…..
Information Technology
Truly, this article is really one of the very best in the history of articles. I am a antique ’Article’ collector and I sometimes read some new articles if I find them interesting. And I found this one pretty fascinating and it should go into my collection. Very good work! agen bandarq online
I’ve been searching for some decent stuff on the subject and haven't had any luck up until this point, You just got a new biggest fan!..
email marketing companies
Positive site, where did u come up with the information on this posting? I'm pleased I discovered it though, ill be checking back soon to find out what additional posts you include.
email marketing companies
i am always looking for some free stuffs over the internet. there are also some companies which gives free samples.
출장마사지
it was a wonderful chance to visit this kind of site and I am happy to know. thank you so much for giving us a chance to have this opportunity..
butik masaj
Nice to read your article! I am looking forward to sharing your adventures and experiences.
คำคม
Nice to read your article! I am looking forward to sharing your adventures and experiences.
คำคม
I really thank you for the valuable info on this great subject and look forward to more great posts. Thanks a lot for enjoying this beauty article with me. I am appreciating it very much! Looking forward to another great article. Good luck to the author! All the best!
Valves in uae
The website is looking bit flashy and it catches the visitors eyes. Design is pretty simple and a good user friendly interface.
pre owned rolex
I read a article under the same title some time ago, but this articles quality is much, much better. How you do this..
check valve
best fiduciary advisors
google search ads
janitorial cleaning
cargo transportation services
private house inspector
gdx stock
floor sanding and polishing northern suburbs
willdylan.tv
find an independent advisor
affiliate link
I've been using WordPress on a number of websites for about a year and am worried about switching to another platform. I have heard good things about keo nhacai. Is there a way I can transfer all my wordpress content into it? Any help would be really appreciated!
Thank you so much for sharing this great blog.Very inspiring and helpful too.Hope you continue to share more of your ideas.I will definitely love to read.
Arborist
I'm glad I found this web site, I couldn't find any knowledge on this matter prior to.Also operate a site and if you are ever interested in doing some visitor writing for me if possible feel free to let me know, i am always look for people to check out my web site.
zinc citrate
I would like to say that this blog really convinced me to do it! Thanks, very good post.read more
Wonderful article, thanks for putting this together! This is obviously one great post. Thanks for the valuable information and insights you have so provided here.
carte yugioh
This is a great inspiring article.I am pretty much pleased with your good work.You put really very helpful information...
banklast
Superbly written article. if only all bloggers offered the same content as you. the internet would be a far better place..
business for sale south africa
The adults always told us how to play safely. I think what adults say is always right. Let's find out how to play safely. 안전놀이터
unisuper advice
unisuper advice
unisuper advice
magazine ads
grade tile cleaner
best project method
properties analytics home
your advisor
engineered floorboards
willdylan.tv
Yes i am completely concurred with this article and i simply need say this article is extremely decent and exceptionally useful article.I will make a point to be perusing your blog more. You made a decent point yet I can"t resist the urge to ponder, shouldn"t something be said about the other side? 토토사이트추천
I would like to say that this blog really convinced me to do it! Thanks. very good post.
Grocery Delivery Zimbabwe
This is very educational content and written well for a change. It's nice to see that some people still understand how to write a quality post!
governance risk compliance gdpr software
Great content material and great layout. Your website deserves all of the positive feedback it’s been getting.
things to do in the cayman islands
I think this is an informative post and it is very useful and knowledgeable. therefore. I would like to thank you for the efforts you have made in writing this article.
xerium
I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.
서울안마
I was looking at some of your posts on this website and I conceive this web site is really instructive! Keep putting up..
whitelabel seo reports
https://elenashevchuk.com/
I've been looking also for some tutorials but found this great site and your article also. Thanks anyway for sharing! Roofing Contractor Olympia
I've been looking also for some tutorials but found this great site and your article also. Thanks anyway for sharing! Roofing Contractor Olympia
I read that Post and got it fine and informative. Please share more like that...
xerium
I found that site very usefull and this survey is very cirious. I ' ve never seen a blog that demand a survey for this actions. very curious...
redraiderrvpark
안전놀이터 With the victory, Ginseng Corporation scored 14 wins and 15 losses and 43 points in the season. On the other hand, Hyundai Engineering & Construction suffered its first consecutive loss of the season
How are you all living in the era of untact? I'm trying in a variety of ways 토토사이트
How are you all living in the era of untact? I'm trying in a variety of ways. 토토사이트
Its a great pleasure reading your post.Its full of information I am looking for and I love to post a comment that "The content of your post is awesome" Great work.
a course in miracles
https://mukoff.com/
Last week, deputies were called to a San Marin daycare owned by Goularte's mother regarding an alleged sexual assault involving a child, the Santa Clara County Sheriff's Office said in a statement Wednesday.
An intriguing discussion may be worth comment. I’m sure you should write much more about this topic, may well be described as a taboo subject but generally folks are too little to chat on such topics. An additional. Cheers 메이저토토사이트
Thanks for your post. The article is neatly organized with the information I want, so there are many things to refer to. Bookmark this site and visit often in the future. Thanks again.^^ keonhacai
https://toolbarqueries.google.sc/url?q=https%3A%2F%2Fsite789.com
It is a great website.. The Design looks very good.. Keep working like that!.
red sox news
Drift Hunters is Car Driving and Racing Simulator. Best Car Tuning on Android!
Speeddaten is famous for: communication on topics you are interested in;
I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.
cameronjamesusa
I wanted to thank you for this great read!! I definitely enjoying every little bit of it I have you bookmarked to check out new stuff you post.
cameronjamesusa
Sex in Berlin Ogłoszenia kontaktowe to, że tak powiem, standardowe serwisy randkowe, w których single rejestrują się, tworzą profil i za jego pomocą ujawniają publicznie informacje o sobie. Istnieją oczywiście liczne odmiany tego typu stron, np. strony poświęcone związkom dla określonych grup ludzi (gotów, rozwodników, społeczności LGBT itp.). Serwisy randkowe umożliwiają także wyszukiwanie osób na podstawie różnych czynników (wiek, wzrost, lokalizacja, odległość, zainteresowania itp.)
Gameboy Advance Games
Download Cuphead Mobile game on Android phones at https://modpree.com/cuphead/
Roksa sroda
There are also articles on these topics on my blog and I hope you visit once and have a deep discussion! 메이저놀이터
Hello ! I am the one who writes posts on these topics 카지노사이트 I would like to write an article based on your article. When can I ask for a review?
Thanks for the information, this is a great work. Download your latest MP3, video, Album music at
Liteboxmusic
DOWNLOAD MP3
DOWNLOAD MP3 MUSIC
DOWNLOAD LATEST MP3 MUSIC
MP3 MUSIC
DOWNLOAD LATEST SONGS
citywidesafeandlock.com
ufc vettori
cladding
paccapital.com.au
social influencer
synthesis.capital
2nd floor house
Safe And Lock
brazilian ufc fighters
resolute home llc
website
social creator
website
farmhouse plans with wrap around porch
citywidesafeandlock.com
mma boxing
safetech property
paccapital.com.au
snapchat youtube
synthesis.capital
20 by 50 house plan
We are looking for a lot of data on this item. In the meantime, this is the perfect article I was looking for . Please post a lot about items related to 비아그라구매 !!! I am waiting for your article. And when you are having difficulty writing articles, I think you can get a lot of help by visiting my .
Enjoy sexy contacts with fine ladies in EU only at sex winterthur
I visited last Monday, and in the meantime, I came back in 우리카지노계열 anticipation that there might be other articles related to I know there is no regret and leave a comment. Your related articles are very good, keep going!!
It seems like I've never seen an article of a kind like . It literally means the best thorn. It seems to be a fantastic article. It is the best among articles related to 열공캔디 . seems very easy, but it's a difficult kind of article, and it's perfect.
citywidesafeandlock.com
petr yan ufc
millennium property
paccapital.com.au
pinterest social service
synthesis.capital
corner lot house plans
I am contemplating this topic. I think you can solve my problems. My site is at " 열공캔디 ". I hope you can help me.
It's very interesting. And it's fun. This is a timeless article. I also write articles related to , and I run a community related to 비아그라 . For more information, please feel free to visit !!
This is a smart blog. I mean it. You have so much knowledge about this issue, and so much passion. You also know how to make people rally behind it, obviously from the responses.
When did it start? The day I started surfing the Internet to read articles related to . I've been fond of seeing various sites related to 비아그라구매 around the world for over 10 years. Among them, I saw your site writing articles related to and I am very satisfied.
Videkilany
I always think about what is. It seems to be a perfect article that seems to blow away such worries. 마하캔디 seems to be the best way to show something. When you have time, please write an article about what means!!
I'm so happy to finally find a post with what I want. 바카라게임사이트 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.
Hello! Nice to meet you, I say . The name of the community I run is 해머캔디 , and the community I run contains articles similar to your blog. If you have time, I would be very grateful if you visit my site .
I accidentally searched and visited your site. I still saw several posts during my visit, but the text was neat and readable. I'll quote this post and post it on my blog. Would you like to visit my blog later? 온라인카지노사이트
I accidentally searched and visited your site. I still saw several posts during my visit, but the text was neat and readable. I'll quote this post and post it on my blog. Would you like to visit my blog later? 온라인카지노사이트
ZFVDFG
This is the perfect post.바카라사이트 It helped me a lot. If you have time, I hope you come to my site and share your opinions. Have a nice day.
dxzgh
Which is some inspirational stuff. Never knew that opinions might be this varied. Thank you for all the enthusiasm to provide such helpful information here.베트남 황제투어 It helped me a lot. If you have time, I hope you come to my site and share your opinions. Have a nice day.
This is the perfect post.바카라사이트 It helped me a lot. If you have time, I hope you come to my site and share your opinions. Have a nice day.
fdhfgd
LIVE 바카라사이트 GAMES - Sunday stream!
After study a handful of the blog posts with your internet site now, we truly like your technique for blogging. I bookmarked it to my bookmark internet site list and are checking back soon. 다낭 밤문화
tax professional
gym training
tax professional
tax preparer
Hello! I could have sworn I've been to this site before but after checking through some of the post I realized it's new to me. Nonetheless, I'm definitely happy I found keonhacai and I'll be book-marking and checking back frequently!
What a nice post! I'm so happy to read this. 해머캔디효과 What you wrote was very helpful to me. Thank you. Actually, I run a site similar to you. If you have time, could you visit my site? Please leave your comments after reading what I wrote. If you do so, I will actively reflect your opinion. I think it will be a great help to run my site. Have a good day.
Your article was very impressive to me. It was unexpected information,but after reading it like this 바카라사이트추천, I found it very interesting.
I finally found what I was looking for! I'm so happy. 해머캔디가격 Your article is what I've been looking for for a long time. I'm happy to find you like this. Could you visit my website if you have time? I'm sure you'll find a post of interest that you'll find interesting.
I’m not sure exactly why but this weblog is loading incredibly slow for me. Is anyone else having this problem or is it a problem on my end? I’ll check back later on and see if the problem still exists. 바카라사이트추천
fhj
I've been troubled for several days with this topic. 카지노사이트, But by chance looking at your post solved my problem! I will leave my blog, so when would you like to visit it?
สล็อตxo 1688">สล็อตxo 1688
ที่มาพร้อมความบันเทิงแบบครบวงจรทั้ง สล็อต ยิงปลา การันตีความมั่นคง ปลอดภัย 100% เล่นได้ จ่ายจริงI've been looking for photos and articles on this topic over the past few days due to a school assignment, 온라인카지노 and I'm really happy to find a post with the material I was looking for! I bookmark and will come often! Thanks
There must have been many difficulties in providing this information. 카지노사이트 Nevertheless, thank you for providing such high-quality information.
Of course, your article is good enough, 카지노사이트 but I thought it would be much better to see professional photos and videos together. There are articles and photos on these topics on my homepage, so please visit and share your opinions.
Of course, your article is good enough, 카지노사이트 but I thought it would be much better to see professional photos and videos together. There are articles and photos on these topics on my homepage, so please visit and share your opinions.
This is the post I was looking for. I am very happy to read this article. If you have time, please come to my site 카지노사이트 and share your thoughts. Have a nice day.
cfhhh
SexyPG89 เกม IPRO999 แตกง่าย แตกหนัก แจกจริง
I've been reading all the articles related to 플레이포커머니상 for the past hour, but I don't know why I saw this post now. It seems like very useful information.
I love seeing more and more people visiting your blog. I, who have been together for a long time, created a forum with the same topic as yours this time. The subject is going to be captured by 플레이포커머니상.
Your ideas have inspired me a lot. I want to learn your writing skills. There is also a website. Please visit us and leave your comments. Thank you. 온라인카지노
gfjh
Your ideas have inspired me a lot. I want to learn your writing skills. There is also a website. Please visit us and leave your comments. Thank you. 온라인카지노
fdhh
It is my first visit to your blog, and I am very impressed with the articles that you serve. Give adequate knowledge for me. Thank you for sharing useful material. I will be back for the more great post. 카지노게임사이트 But by chance looking at your post solved my problem! I will leave my blog, so when would you like to visit it?!
ghjj
What a post I've been looking for! I'm very happy to finally read this post. 토토사이트 Thank you very much. Can I refer to your post on my website? Your post touched me a lot and helped me a lot. If you have any questions, please visit my site and read what kind of posts I am posting. I am sure it will be interesting.
If you are interested in investing in virtual currency,
You may have heard of the ‘Binance’ exchange.
Binance
Binance Referral
Binance Code
Binance Fees
Binance Discount
Binance Featured
Join Binance
Binance Method
Someone necessarily help to make severely articles I might state. That is the first time I frequented your web page and up to now? I surprised with the analysis you made to create this actual publish extraordinary. Fantastic process 하하포커
Your ideas inspired me very much. 토토사이트순위 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thank you.
I'm so happy to finally find a post with what I want. 토토사이트모음 You have inspired me a lot. If you are satisfied, please visit my website and leave your feedback.
What a nice post! I'm so happy to read this. 온라인카지노 What you wrote was very helpful to me. Thank you. Actually, I run a site similar to you. If you have time, could you visit my site? Please leave your comments after reading what I wrote. If you do so, I will actively reflect your opinion. I think it will be a great help to run my site. Have a good day.
1.카지노사이트 추천,카지노사이트 검증,카지노사이트 주소,카지노사이트 순위,
슬롯사이트 추천,슬롯사이트 검증,슬롯사이트 순위,슬롯사이트 주소
https://start.me/p/wMno27
https://start.me/p/p1g5aG
슬롯사이트
카지노사이트
카지노사이트
슬롯사이트
1.카지노사이트 추천,카지노사이트 검증,카지노사이트 주소,카지노사이트 순위,
슬롯사이트 추천,슬롯사이트 검증,슬롯사이트 순위,슬롯사이트 주소
https://start.me/p/wMno27
https://start.me/p/p1g5aG
슬롯사이트
카지노사이트
카지노사이트
슬롯사이트
betflixvip ค่ายเกมทำเงินมาแรง แจ็กพอตแตกแสนทุกวัน
betflik vip กติกา บาคาร่า และวิธีเล่นเกมไพ่ยอดนิยม เข้าใจง่าย ทำเงินดีที่สุด
Thanks for your personal marvelous posting! I quite enjoyed reading it, you will be a great author. I will always bookmark your blog and will come back down the road. I want to encourage one to continue your great posts, have a nice morning! pgslot168" title="pgslot168">pgslot168
Thanks for another informative site. The place else may I get that kind of info written in such a perfect way? I’ve a venture that I’m just now operating on, and I have been on the glance out for such info. ufa168
betflikvip Excellent information you have shared, thanks for taking the time to share with us such a great article. I really appreciate your work.
It’s really a great and helpful piece of info. I’m glad that you shared this helpful info with us. Please keep us up to date like this. Thanks for sharing. biogaming vip
THE ONE CARGO ยินดีให้บริการรับ นำเข้าสินค้าจากจีน สั่งสินค้าจากจีน แลกหยวน โอนเงิน ฝากจ่าย รวมถึงติดต่อโรงงาน ร้านค้าใน Taobao 1688 สินค้า Alibaba จัดซื้อ จัดหาสินค้าจีนทุกประเภท พร้อมให้คำปรึกษา
เว็บจ่ายไว เว็บแทงบอลราคาดี มีคู่บอลเปิดให้แทงมากที่สุด บาคาร่า อันดับ1 ศูนย์รวมเกมพนันทุกเกม สมัครง่าย ไม่มีขั้นต่ำ
เว็บตรง 100 เว็บแทงบอลราคาดี มีคู่บอลเปิดให้แทงมากที่สุด บาคาร่า อันดับ1 ศูนย์รวมเกมพนันทุกเกม สมัครง่าย ไม่มีขั้นต่ำ
THE ONE CARGO รับนำเข้าสินค้าจีน เว็บ สั่งสินค้าจากจีน ที่ช่วยดูแลทุกการนำเข้าจนถึงหน้าบ้านคุณ ช่วยคุยติดต่อ โรงงาน ร้านค้าแหล่งขายส่ง มีล่ามช่วยแก้ปัญหาต่อราคาคุยกับร้านจีนให้ มีระบบติดตามสถานะพัสดุ พร้อมแจ้งเตื่อนเข้า Line
Отправить комментарий
Приветствуются комментарии:Для остальных вопросов и обсуждений есть форум.