| AmirHossein |
رفتن به کانال در Telegram
635
مشترکین
-324 ساعت
-87 روز
-230 روز
آرشیو پست ها
خیلی از مردم واکنش عجیبی به این وضعیت فعلی دارن
نمیدونم چرا ولی انگار خوشحالن که جنگ شده
با هیجان و اشتیاق ازش صحبت میکنن
اون رو مسخره میکنن
و حرفای بچهگونه
نمیدونیم هدف از حمله چی بوده
سران مملکت؟ یا کی؟
مهم نیست، مهم اینه وسط مردم عادی هم آسیب دیدن
ویدیوهایی هست که نشون میده بچههای کوچیک کشته شدن، یا زیر آوار موندن
شاید شما توی خونتون آرامش داشته باشید(هنوز) ولی یه عده عزیزانشون رو از دست دادن
جنگ، جنگه؛ اونو بچهبازی ندونید، مسخره نکنید، نخندید، فاز هجیان و خوشحالی نگیرید
به امید آزادی و امنیت، تسلیت به مردم از دست رفته(جز مسئولین)
Repost from Start Unity
🎯 پکیج Magic WebAds منتشر شد! (نسخه آزمایشی)
یکی از مشکلات همیشگی ما توی ایران، نبود دسترسی به تبلیغات درونبرنامهای معروف مثل AdMob یا Unity Ads بوده. تحریمها، پیچیدگیها و نیاز به حساب بانکی خارجی باعث شده خیلی از بازیسازهای مستقل نتونن به راحتی ازشون استفاده کنن.
واسه همین تصمیم گرفتم یه پکیج سبک و ساده بسازم برای نمایش تبلیغات از طریق WebView، بدون نیاز به SDK و دردسر! یعنی هر لینکی که تبلیغات شما رو نشون میده، میتونید مستقیم توی بازی لود کنید. مخصوصاً برای پروژههای Web3 و تبلیغات کریپتویی خیلی کاربردیه.
🧪 این نسخه هنوز اولیهست و ممکنه باگ داشته باشه یا هنوز بهدرد پروژههای خیلی جدی نخوره، ولی پایهاش رو گذاشتم تا کمکم روش بسازم.
📱 حتماً نسخه دمو اندروید رو تست کنید، تبلیغ لود میشه و میتونید عملکرد کلی رو ببینید.
یه سمپل هم همراه پکیجه که خیلی راحت نشون میده چطوری ازش استفاده کنید.
بهزودی داکیومنت کامل و ویدیوهای آموزشی هم براش میسازم.
✨ اگه بهدردت میخوره یا دوست داری همچین ابزاری قویتر بشه، لطفاً یه ⭐️ بهش بده توی گیتهاب.
همین حمایت کوچیک کلی بهم انگیزه میده که قویتر و سریعتر توسعهاش بدم.
🔗 لینک پکیج: Magic WebAds on GitHub
🔗 دمو اندروید: دانلود فایل APK
مرسی که همیشه حمایتم میکنید ❤️
این VPNهای ارزون قیمتی که توی کانالها تبلیغ میکنند رو ازشون فرار کنید.
اکانت نامحدود فقط ۴۹ هزار تومنچنین چیزهایی یا بعد یک هفته از کار میوفتن، یا اطلاعات رو شنود میکنند. وگرنه چنین قیمتی برای VPN، اونم نامحدود اصلا منطقی نیست. از جای معتبر و آشنا بخرید.
دفعه قبلی که حوصلهم سررفته بود نسشتم و پکیج Laraquest رو با زبان GoLang بازنویسی کردم و حاصلش شد Laraquest-Go.
ولی با خودم فکر کردم که شاید خیلی حوصلهم سرنرفته بوده، در نتیجه اینبار بیشتر حوصلهم سر رفت، و struct ها رو به PHP اضافه کردم.
نمیدونم اینبار به اندازه کافی حوصلهم سر رفته بوده یا نه، ولی به نظر برای الان کافیه.
در نتیجه من الان یک PHP دارم که میتونم توش از struct استفاده کنم.
البته که اضافه کردن چیزی مثل structها به PHP به این سادگی ها نیست و هنوز کلی کار نیاز داره، مثلا الان با یک کلاس هیچ تفاوتی نداره جز محدودیت هاش.
یعنی توی این استراکت نمیتونیم مجیکمتد استفاده کنیم، یا ارثبری داشته باشیم و...
ولی در نهایت مثل یک کلاس رجیستر میشه، که این یعنی هیچ تفاوتی با ساخت یک کلاس نداره و عملا وجودش بیفایدهس.
به همین دلیل اگر حوصلهم بازم سر رفت کمی بیشتر روش وقت میذارم و در کنار class_entryها، struct_entry هم اضافه میکنم که از کلاسها کاملا جدا بشه و سبک تر.
و در نهایت سینتکس رو به صورت زیر تغییر میدم:
Square{1, 2}
اما در کل برای تفریح و کسب تجربه چیز جالبی بود.
@AmirhDeveloper
.جدا چطور میفهمن که من دارم کامپایل میکنم تا برقو قطع کنن
سیستم ذغالیه، یه کامپایل ۱۰ دیقه طول میکشه
بعد صاف وسطش برق قطع میشه
استریم ها در PHP - قسمت دوازدهم
- ساخت فیلترهای سفارشی
در بخش سوم با استریم php://filter آشنا شدیم. همانطور که میدانید، این استریم امکان فیلتر کردن و پردازش دادههای ورودی یا خروجی را در حین خواندن و نوشتن فراهم میکند. همچنین با فیلترهایی مانند string.toupper و string.strip_tags آشنا شدیم.
در PHP، کلاس php_user_filter پایهای است برای تعریف فیلترهای استریم سفارشی (Custom Stream Filters). وقتی شما یک فیلتر سفارشی میسازید، باید از این کلاس ارثبری کنید و متدهای آن را پیادهسازی کنید تا بتوانید روی دادههای استریم، پردازش دلخواه خود را انجام دهید.
- ساختار کلی کلاس php_user_filter
1- متد filter
این متد مهمترین بخش فیلتر است. دادههای ورودی از استریم در قالب یک یا چند "باکت" (bucket) به این متد میآیند. هدف شما این است که دادهها را در هر باکت پردازش کنید و سپس آن را به باکتهای خروجی منتقل کنید.
public function filter(resource $in, resource $out, int &$consumed, bool $closing): int
{
//
}
پارامتر in : استریم ورودی که دادههای خام در قالب باکتها داخلش هستند.
پارامتر out : استریم خروجی که باید دادههای پردازش شده داخلش قرار بگیرد.
پارامتر consumed : تعداد بایتهایی که از ورودی خوانده و مصرف شدهاند. باید این مقدار را بهروز کنید.
پارامتر closing : اگر true باشد، استریم در حال بسته شدن است و باید پردازش نهایی انجام شود.
این متد باید یک عدد صحیح را return کند، این عدد بین 0 تا 2 می باشد که در قالب ثابت های زیر موجود هستند:
ثابت PSFS_PASS_ON : ادامه معمولی پردازش (عدد 0)
ثابت PSFS_FEED_ME : منتظر داده بیشتر باش (عدد 1)
ثابت PSFS_ERR_FATAL : خطای بحرانی (عدد 2)
در ادامه یک فیلتر برای بزرگ کردن حروف ایجاد می کنیم:
public function filter(resource $in, resource $out, int &$consumed, bool $closing): int
{
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = strtoupper($bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
در هر تکرار، تابع stream_bucket_make_writeable($in) یک "باکت" دادهای از ورودی دریافت میکند.
باکت یک ساختار است که شامل دادههای خام ($bucket->data) و طول دادهها ($bucket->datalen) است.
اگر دادهای وجود داشته باشد، باکت به صورت نوشتنی بازگردانده میشود.
در این مثال، دادههای موجود در باکت به حروف بزرگ تبدیل میشوند:
$bucket->data = strtoupper($bucket->data);
یعنی هر رشتهای که از ورودی آمده، با strtoupper تبدیل به حروف بزرگ میشود.
تعداد بایتهایی که از ورودی خوانده شده است باید به $consumed اضافه شود:
$consumed += $bucket->datalen;
این به PHP کمک میکند بفهمد چقدر از دادهها مصرف شدهاند.
پس از پردازش، باکت به استریم خروجی ارسال میشود:
stream_bucket_append($out, $bucket);
به این ترتیب، دادههای پردازش شده آماده خواندن در خروجی هستند.
در نهایت، مقدار PSFS_PASS_ON برگردانده میشود، این مقدار به معنی "ادامه پردازش عادی" است و نشان میدهد که فیلتر با موفقیت کار خود را انجام داده است.
———
2- متد onCreate
این متد هنگام ایجاد فیلتر و اتصال آن به استریم فراخوانی میشود.
public function onCreate(): bool
{
//
}
میتوانید در اینجا پارامترهای ورودی در $this->params را پردازش یا مقداردهی اولیه انجام دهید.
اگر مقدار true بازگردد، اجازه ساخت استریم داده می شود. در غیر این صورت ایجاد فیلتر به شکست میخورد.
———
3- متد onClose
زمانی که استریم بسته میشود، این متد فراخوانی میشود تا فیلتر بتواند منابع را آزاد کند یا تمیزکاری کند.
public function onClose(): void
{
//
}
نکته: تنها پیاده سازی متد filter اجباری می باشد.
- مثال کامل
class UppercaseFilter extends php_user_filter
{
public function filter($in, $out, &$consumed, $closing): int
{
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = strtoupper($bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
stream_filter_register('my_uppercase', 'UppercaseFilter') or die('Failed to register filter');
$fp = fopen('php://memory', 'r+');
fwrite($fp, "hello");
rewind($fp);
stream_filter_append($fp, 'my_uppercase');
echo stream_get_contents($fp); // HELLO
// OR
echo file_get_contents("php://filter/read=my_uppercase/resource=input.txt");
#PHP #PHP_streams
@AmirhDeveloper
.استریم ها در PHP - قسمت دوازدهم
- ساخت فیلترهای سفارشی
در بخش سوم با استریم php://filter آشنا شدیم. همانطور که میدانید، این استریم امکان فیلتر کردن و پردازش دادههای ورودی یا خروجی را در حین خواندن و نوشتن فراهم میکند. همچنین با فیلترهایی مانند string.toupper و string.strip_tags آشنا شدیم.
در PHP، کلاس php_user_filter پایهای است برای تعریف فیلترهای استریم سفارشی (Custom Stream Filters). وقتی شما یک فیلتر سفارشی میسازید، باید از این کلاس ارثبری کنید و متدهای آن را پیادهسازی کنید تا بتوانید روی دادههای استریم، پردازش دلخواه خود را انجام دهید.
- ساختار کلی کلاس php_user_filter
1- متد filter
این متد مهمترین بخش فیلتر است. دادههای ورودی از استریم در قالب یک یا چند "باکت" (bucket) به این متد میآیند. هدف شما این است که دادهها را در هر باکت پردازش کنید و سپس آن را به باکتهای خروجی منتقل کنید.
public function filter(resource $in, resource $out, int &$consumed, bool $closing): int
{
//
}
پارامتر in : استریم ورودی که دادههای خام در قالب باکتها داخلش هستند.
پارامتر out : استریم خروجی که باید دادههای پردازش شده داخلش قرار بگیرد.
پارامتر consumed : تعداد بایتهایی که از ورودی خوانده و مصرف شدهاند. باید این مقدار را بهروز کنید.
پارامتر closing : اگر true باشد، استریم در حال بسته شدن است و باید پردازش نهایی انجام شود.
این متد باید یک عدد صحیح را return کند، این عدد بین 0 تا 2 می باشد که در قالب ثابت های زیر موجود هستند:
ثابت PSFS_PASS_ON : ادامه معمولی پردازش (عدد 0)
ثابت PSFS_FEED_ME : منتظر داده بیشتر باش (عدد 1)
ثابت PSFS_ERR_FATAL : خطای بحرانی (عدد 2)
در ادامه یک فیلتر برای بزرگ کردن حروف ایجاد می کنیم:
public function filter(resource $in, resource $out, int &$consumed, bool $closing): int
{
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = strtoupper($bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
در هر تکرار، تابع stream_bucket_make_writeable($in) یک "باکت" دادهای از ورودی دریافت میکند.
باکت یک ساختار است که شامل دادههای خام ($bucket->data) و طول دادهها ($bucket->datalen) است.
اگر دادهای وجود داشته باشد، باکت به صورت نوشتنی بازگردانده میشود.
در این مثال، دادههای موجود در باکت به حروف بزرگ تبدیل میشوند:
$bucket->data = strtoupper($bucket->data);
یعنی هر رشتهای که از ورودی آمده، با strtoupper تبدیل به حروف بزرگ میشود.
تعداد بایتهایی که از ورودی خوانده شده است باید به $consumed اضافه شود:
$consumed += $bucket->datalen;
این به PHP کمک میکند بفهمد چقدر از دادهها مصرف شدهاند.
پس از پردازش، باکت به استریم خروجی ارسال میشود:
stream_bucket_append($out, $bucket);
به این ترتیب، دادههای پردازش شده آماده خواندن در خروجی هستند.
در نهایت، مقدار PSFS_PASS_ON برگردانده میشود، این مقدار به معنی "ادامه پردازش عادی" است و نشان میدهد که فیلتر با موفقیت کار خود را انجام داده است.
———
2- متد onCreate
این متد هنگام ایجاد فیلتر و اتصال آن به استریم فراخوانی میشود.
public function onCreate(): bool
{
//
}
میتوانید در اینجا پارامترهای ورودی در $this->params را پردازش یا مقداردهی اولیه انجام دهید.
اگر مقدار true بازگردد، اجازه ساخت استریم داده می شود. در غیر این صورت ایجاد فیلتر به شکست میخورد.
———
3- متد onClose
زمانی که استریم بسته میشود، این متد فراخوانی میشود تا فیلتر بتواند منابع را آزاد کند یا تمیزکاری کند.
public function onClose(): void
{
//
}
نکته: تنها پیاده سازی متد filter اجباری می باشد.
- مثال کامل
class UppercaseFilter extends php_user_filter
{
public function filter($in, $out, &$consumed, $closing): int
{
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = strtoupper($bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}
stream_filter_register('my_uppercase', 'UppercaseFilter') or die('Failed to register filter');
$fp = fopen('php://memory', 'r+');
fwrite($fp, "hello");
rewind($fp);
stream_filter_append($fp, 'my_uppercase');
echo stream_get_contents($fp); // HELLO
// OR
echo file_get_contents("php://filter/read=my_uppercase/resource=input.txt");
#PHP #PHP_streams
@AmirhDeveloper
.استریم ها در PHP - قسمت یازدهم
- متدهای قابل پیادهسازی در استریم رپرها - قسمت دوم
11- متد mkdir
ساخت دایرکتوری جدید با مسیر و دسترسی داده شده.
پارامتر path مسیر دایرکتوری که باید ساخته شود، مثلا "mywrapper://newdir"
پارامتر mode دسترسیهای دایرکتوری (مثلا 0755)
پارامتر options گزینههایی مانند STREAM_MKDIR_RECURSIVE که به شما اجازه میدهد ساخت چند مرحلهای دایرکتوری را انجام دهید.
public function mkdir(string $path, int $mode, int $options): bool {
// Creating a virtual directory
return true;
}
// Called if:
mkdir("mywrapper://newdir", 0755);
12- متد rmdir
برای حذف یک دایرکتوری.
پارامتر path مسیر دایرکتوری مورد نظر برای حذف
پارامتر options گزینههایی که میتوانند کنترل بیشتری بر حذف داشته باشند (در عمل معمولا 0)
public function rmdir(string $path, int $options): bool {
// Deleting a virtual directory
return true;
}
// Called if:
rmdir("mywrapper://newdir");
13- متد rename
جابجایی یا تغییر نام فایل یا دایرکتوری.
پارامتر path_from مسیر مبدأ
پارامتر path_to مسیر مقصد
public function rename(string $path_from, string $path_to): bool {
// Rename or move a file or directory
return true;
}
// Called if:
rename("mywrapper://old.txt", "mywrapper://new.txt");
14- متد unlink
حذف فایل مشخص شده.
پارامتر path مسیر فایل برای حذف
public function unlink(string $path): bool {
// Deleting a virtual file
return true;
}
// Called if:
unlink("mywrapper://file.txt");
15- متد dir_opendir
بازکردن دایرکتوری برای شروع خواندن محتویات.
پارامتر path مسیر دایرکتوری
پارامتر options گزینهها (معمولاً 0)
public function dir_opendir(string $path, int $options): bool {
$this->dirEntries = ['file1.txt', 'file2.txt'];
$this->dirPosition = 0;
return true;
}
// Called if:
$dir = opendir("mywrapper://somedir");
16- متد dir_readdir
خواندن نام فایل یا دایرکتوری بعدی از داخل دایرکتوری باز شده.
public function dir_readdir(): string|bool {
if (isset($this->dirEntries[$this->dirPosition])) {
return $this->dirEntries[$this->dirPosition++];
}
return false;
}
// Called if:
while (($file = readdir($dir)) !== false) {
echo $file . "\n";
}
17- متد dir_rewinddir
بازگرداندن اشارهگر خواندن به ابتدای دایرکتوری.
public function dir_rewinddir(): bool {
$this->dirPosition = 0;
return true;
}
// Called if:
rewinddir($dir);
18- متد dir_closedir
بستن دایرکتوری و آزادسازی منابع.
public function dir_closedir(): bool {
// Resource liberation
return true;
}
// Called if:
closedir($dir);
19- متد stream_lock
اعمال قفل روی فایل برای هماهنگی دسترسی همزمان.
پارامتر operation نوع قفل مانند LOCK_SH (اشتراکی)، LOCK_EX (انحصاری)، یا LOCK_UN (آزادسازی قفل)
public function stream_lock(int $operation): bool {
// File lock management
return true;
}
// Called if:
flock($fp, LOCK_EX);
20- متد stream_metadata
مدیریت متادیتا مثل chmod و touch.
پارامتر path مسیر فایل یا دایرکتوری
پارامتر option نوع تغییر (مثلاً STREAM_META_ACCESS برای تغییر دسترسی، STREAM_META_TOUCH برای تغییر زمان)
پارامتر value مقدار جدید (مثلاً دسترسی جدید یا زمان)
public function stream_metadata(string $path, int $option, mixed $value): bool {
// Changing file and directory permissions or time
return true;
}
// Called if:
chmod("mywrapper://file.txt", 0644);
touch("mywrapper://file.txt", time());
21- متد stream_truncate
تغییر اندازه داده استریم (کوتاه کردن یا طولانی کردن).
پارامتر new_size اندازه جدید فایل
public function stream_truncate(int $new_size): bool {
$this->data = substr($this->data, 0, $new_size);
if (strlen($this->data) < $new_size) {
$this->data .= str_repeat("\0", $new_size - strlen($this->data));
}
return true;
}
// Called if:
ftruncate($fp, 1024);
22- متد stream_cast
تبدیل به resource (مثلاً برای socket).
پارامتر cast_as نوع resource مورد نظر
public function stream_cast(int $cast_as): resource|false {
return false;
}
// Called if:
if (stream_select($read, $write, $except, 0, 200000)) {
echo fread($read[0], 1024);
}
متدهای construct و destruct را نیز میتوانید بسته به نیاز خود پیادهسازی کنید.
#PHP #PHP_streams
@AmirhDeveloper
.استریم ها در PHP - قسمت دهم
- متدهای قابل پیادهسازی در استریم رپرها
در قسمت قبل با ساخت یک استریم رپر سفارشی آشنا شدیم.
در کلاسهای استریم رپر متدهایی با نام خاص پیادهسازی میشوند و هرکدام در مواقع خاص (مثل بازکردن استریم یا خواندن و نوشتن روی استریم) اجرا میشوند.
در ادامه با این متدها آشنا میشویم.
1- متد stream_open
این متد برای باز کردن استریم استفاده میشود.
پارامتر path مسیر استریم مثل mywrapper://file.txt
پارامتر mode حالت باز کردن مثل "r", "w", "a" و غیره
پارامتر options گزینههای اضافی (مثل STREAM_USE_PATH)
پارامتر opened_path ارجاعی برای مسیر واقعی باز شده (اختیاری)
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool {
$this->position = 0;
$this->data = "";
return true;
}
// Called if:
$fp = fopen("mywrapper://file.txt", "r");
در این مثال اشارهگر برابر 0 قرار می گیرید، داده اولیه برابر "" قرار می گیرد و در نهایت اعلام می شود که با موفقیت انجام شده.
2- متد stream_read
برای خواندن از استریم استفاده میشود.
پارامتر count تعداد بایتی که قرار است خوانده شود.
public function stream_read(int $count): string|false {
$result = substr($this->data, $this->position, $count);
$this->position += strlen($result);
return $result;
}
// Called if:
$data = fread($fp, 100);
این متد بخشی از داده را از موقعیت فعلی میخواند و موقعیت را جلو میبرد.
3- متد stream_write
برای نوشتن در استریم به کار میرود.
پارامترdata رشته دادهای که باید نوشته شود.
public function stream_write(string $data): int {
$left = substr($this->data, 0, $this->position);
$right = substr($this->data, $this->position + strlen($data));
$this->data = $left . $data . $right;
$this->position += strlen($data);
return strlen($data);
}
// Called if:
fwrite($fp, "Hello World");
داده در محل اشارهگر نوشته شده و موقعیت جابجا میشود و طول داده نوشته شده برمیگردد.
4- متد stream_eof
بررسی رسیدن به انتهای استریم.
public function stream_eof(): bool {
return $this->position >= strlen($this->data);
}
// Called if:
if (feof($fp)) {
echo "End of file";
}
5- متد stream_tell
موقعیت فعلی خواندن/نوشتن در استریم را برمیگرداند.
public function stream_tell(): int {
return $this->position;
}
// Called if:
$pos = ftell($fp);
6- متد stream_seek
برای جابجایی موقعیت خواندن/نوشتن.
پارامتر offset جابجایی
پارامتر whence مبنا (SEEK_SET, SEEK_CUR, SEEK_END)
public function stream_seek(int $offset, int $whence): bool {
$length = strlen($this->data);
switch ($whence) {
case SEEK_SET:
if ($offset >= 0 && $offset <= $length) {
$this->position = $offset;
return true;
}
return false;
case SEEK_CUR:
//
case SEEK_END:
//
default:
return false;
}
}
// Called if:
fseek($fp, 10, SEEK_SET);
جابجایی موقعیت اشارهگر بر اساس $offset و مبنای $whence (ابتدا، موقعیت فعلی، یا انتها).
7- متد stream_close
برای بستن استریم و آزادسازی منابع.
public function stream_close(): void {
// free up resources.
}
// Called if:
fclose($fp);
8- متد stream_flush
برای خالی کردن بافر دادهها به مقصد نهایی.
public function stream_flush(): bool {
// Save or send data
return true;
}
// Called if:
fflush($fp);
9- متد stream_stat
بازگرداندن اطلاعات استریم مانند اندازه و زمان تغییرات.
public function stream_stat(): array|false {
return [
'size' => strlen($this->data),
'mtime' => time(),
'mode' => 0100666,
];
}
// Called if:
$fstat = fstat($fp);
10- متد url_stat
دریافت اطلاعات مسیر بدون باز کردن استریم.
پارامتر path مسیر کامل فایل یا دایرکتوری مثل "mywrapper://file.txt"
پارامتر flags فلگهایی که اطلاعات بیشتری درباره نوع stat میدهند. معمولاً 0 یا ترکیبی از STREAM_URL_STAT_LINK (برای گرفتن اطلاعات لینک نمادین) یا STREAM_URL_STAT_QUIET (بدون تولید خطا)
public function url_stat(string $path, int $flags): array|false {
return $this->stream_stat();
}
// Called if:
stat("mywrapper://file.txt");
در قسمت بعد با سایر متدها آشنا خواهیم شد.
#PHP #PHP_streams
@AmirhDeveloper
.
اکنون در دسترس! پژوهش تلگرام ۲۰۲۵ — مهمترین بینشهای سال 
