مفاهیم کلیدی API تجمیع خصوصی
این سند برای کیست؟
API تجمیع خصوصی، امکان جمعآوری دادههای تجمیعی از workletهایی که به دادههای بین سایتی دسترسی دارند را فراهم میکند. مفاهیم به اشتراک گذاشته شده در اینجا برای توسعهدهندگانی که توابع گزارشدهی را در Shared Storage و Protected Audience API ایجاد میکنند، مهم است.
- اگر شما یک توسعهدهنده هستید که در حال ساخت یک سیستم گزارشدهی برای اندازهگیری بین سایتی هستید.
- اگر شما یک بازاریاب ، دانشمند داده یا دیگر مصرفکنندگان گزارشهای خلاصه هستید، درک این مکانیسمها به شما کمک میکند تا تصمیمات طراحی را برای بازیابی یک گزارش خلاصه بهینه بگیرید.
اصطلاحات کلیدی
قبل از مطالعه این سند، آشنایی با اصطلاحات و مفاهیم کلیدی مفید خواهد بود. هر یک از این اصطلاحات در اینجا به تفصیل شرح داده خواهند شد.
- یک کلید تجمیع (که با نام سطل نیز شناخته میشود) مجموعهای از نقاط داده از پیش تعیینشده است. برای مثال، ممکن است بخواهید مجموعهای از دادههای مکانی را جمعآوری کنید که در آن مرورگر نام کشور را گزارش میدهد. یک کلید تجمیع ممکن است شامل بیش از یک بُعد باشد (برای مثال، کشور و شناسه ویجت محتوای شما).
- یک مقدار قابل تجمیع، یک نقطه داده منفرد است که در یک کلید تجمیع جمعآوری شده است. اگر میخواهید تعداد کاربران فرانسوی که محتوای شما را دیدهاند را اندازهگیری کنید،
Franceیک بُعد در کلید تجمیع است وviewCountبرابر با1، مقدار قابل تجمیع است. - گزارشهای قابل تجمیع در یک مرورگر تولید و رمزگذاری میشوند. برای API تجمیع خصوصی، این شامل دادههایی درباره یک رویداد واحد است.
- سرویس تجمیع، دادههای گزارشهای تجمیعپذیر را برای ایجاد یک گزارش خلاصه پردازش میکند.
- یک گزارش خلاصه ، خروجی نهایی سرویس تجمیع است و شامل دادههای تجمیعشدهی کاربر و دادههای تبدیل دقیق است.
- یک worklet بخشی از زیرساخت است که به شما امکان میدهد توابع خاص جاوا اسکریپت را اجرا کنید و اطلاعات را به درخواستکننده برگردانید. در یک worklet، میتوانید جاوا اسکریپت را اجرا کنید اما نمیتوانید با صفحه خارجی تعامل یا ارتباط برقرار کنید.
گردش کار تجمیع خصوصی
وقتی API تجمیع خصوصی را با یک کلید تجمیع و یک مقدار تجمیعپذیر فراخوانی میکنید، مرورگر یک گزارش تجمیعپذیر ایجاد میکند. گزارشها به سرور شما ارسال میشوند که گزارشها را دستهبندی میکند. گزارشهای دستهبندیشده بعداً توسط سرویس تجمیع پردازش میشوند و یک گزارش خلاصه ایجاد میشود.

- وقتی API تجمیع خصوصی را فراخوانی میکنید، کلاینت (مرورگر) گزارش تجمیعپذیر را تولید و برای جمعآوری به سرور شما ارسال میکند.
- سرور شما گزارشها را از کلاینتها جمعآوری کرده و آنها را برای ارسال به سرویس تجمیع، دستهبندی میکند.
- پس از جمعآوری گزارشهای کافی، آنها را دستهبندی کرده و به سرویس تجمیع که در یک محیط اجرایی قابل اعتماد اجرا میشود، ارسال میکنید تا یک گزارش خلاصه تهیه شود.
گردش کاری که در این بخش شرح داده شده است مشابه API گزارشدهی نسبتدهی است. با این حال، گزارشدهی نسبتدهی دادههای جمعآوریشده از یک رویداد نمایش و یک رویداد تبدیل را که در زمانهای مختلف اتفاق میافتند، به هم مرتبط میکند. تجمیع خصوصی یک رویداد واحد و بینسایتی را اندازهگیری میکند.
کلید تجمیع
یک کلید تجمیع (به اختصار "کلید") نشاندهندهی سطلی است که مقادیر قابل تجمیع در آن جمع میشوند. یک یا چند بُعد را میتوان در این کلید کدگذاری کرد. یک بُعد نشاندهندهی جنبهای است که میخواهید اطلاعات بیشتری در مورد آن کسب کنید، مانند گروه سنی کاربران یا تعداد نمایش یک کمپین تبلیغاتی.
برای مثال، ممکن است ویجتی داشته باشید که در چندین سایت تعبیه شده است و بخواهید کشور کاربرانی را که ویجت شما را دیدهاند، تجزیه و تحلیل کنید. شما به دنبال پاسخ به سؤالاتی مانند «چند نفر از کاربرانی که ویجت من را دیدهاند از کشور X هستند؟» هستید. برای گزارش در مورد این سؤال، میتوانید یک کلید تجمیع تنظیم کنید که دو بُعد را رمزگذاری میکند: شناسه ویجت و شناسه کشور.
کلید ارائه شده به API تجمیع خصوصی یک BigInt است که از چندین بُعد تشکیل شده است. در این مثال، ابعاد، شناسه ویجت و شناسه کشور هستند. فرض کنید شناسه ویجت میتواند تا ۴ رقم مانند 1234 باشد و هر کشور به ترتیب حروف الفبا به یک عدد نگاشت میشود، مانند افغانستان 1 ، فرانسه 61 و زیمبابوه 195 بنابراین، کلید تجمیع ۷ رقم خواهد بود که ۴ کاراکتر اول برای WidgetID و ۳ کاراکتر آخر برای CountryID رزرو شدهاند.
فرض کنید کلید، تعداد کاربرانی از فرانسه (با شناسه کشور 061 ) را نشان میدهد که ویجت با شناسه 3276 را دیدهاند. کلید تجمیع 3276061 است.
| کلید تجمیع | |
| شناسه ابزارک | شناسه کشور |
| ۳۲۷۶ عدد | ۰۶۱ |
کلید تجمیع همچنین میتواند با یک مکانیزم هشینگ مانند SHA-256 تولید شود. برای مثال، رشته {"WidgetId":3276,"CountryID":67} میتواند هش شده و سپس به یک مقدار BigInt برابر با 42943797454801331377966796057547478208888578253058197330928948081739249096287n تبدیل شود. اگر مقدار هش بیش از 128 بیت داشته باشد، میتوانید آن را کوتاه کنید تا مطمئن شوید که از حداکثر مقدار مجاز سطل 2^128−1 تجاوز نمیکند.
در یک کتابچه Shared Storage، میتوانید به ماژولهای crypto و TextEncoder دسترسی داشته باشید که میتوانند به شما در تولید هش کمک کنند. برای کسب اطلاعات بیشتر در مورد تولید هش، SubtleCrypto.digest() در MDN بررسی کنید.
مثال زیر نحوه تولید کلید سطل از یک مقدار هش شده را شرح میدهد:
async function convertToBucket(data) {
// Encode as UTF-8 Uint8Array
const encodedData = new TextEncoder().encode(data);
// Generate SHA-256 hash
const hashBuffer = await crypto.subtle.digest('SHA-256', encodedData);
// Truncate the hash
const truncatedHash = Array.from(new Uint8Array(hashBuffer, 0, 16));
// Convert the byte sequence to a decimal
return truncatedHash.reduce((acc, curr) => acc * 256n + BigInt(curr), 0n);
}
const data = {
WidgetId: 3276,
CountryID: 67
};
const dataString = JSON.stringify(data);
const bucket = await convertToBucket(dataString);
console.log(bucket); // 126200478277438733997751102134640640264n
ارزش قابل جمع
مقادیر قابل تجمیع به ازای هر کلید در بین بسیاری از کاربران جمع میشوند تا بینشهای تجمیعی را در قالب مقادیر خلاصه در گزارشهای خلاصه ایجاد کنند.
حالا، به سوال نمونهای که قبلاً مطرح شد، برگردید: «چند نفر از کاربرانی که ویجت من را دیدهاند اهل فرانسه هستند؟» پاسخ این سوال چیزی شبیه به این خواهد بود: «تقریباً ۴۸۸۱ کاربر که شناسه ویجت ۳۲۷۶ من را دیدهاند اهل فرانسه هستند.» مقدار قابل تجمیع برای هر کاربر ۱ است و «۴۸۸۱ کاربر» مقدار تجمیعی است که مجموع تمام مقادیر قابل تجمیع برای آن کلید تجمیع است.
| کلید تجمیع | ارزش قابل جمع | |
| شناسه ابزارک | شناسه کشور | تعداد مشاهده |
| ۳۲۷۶ عدد | ۰۶۱ | ۱ |
برای این مثال، ما به ازای هر کاربری که ویجت را میبیند، مقدار را ۱ واحد افزایش میدهیم. در عمل، مقدار قابل تجمیع را میتوان برای بهبود نسبت سیگنال به نویز مقیاسبندی کرد.
بودجه مشارکت
هر فراخوانی به API خصوصی تجمیع، یک مشارکت نامیده میشود. برای محافظت از حریم خصوصی کاربر، تعداد مشارکتهایی که میتوان از یک فرد جمعآوری کرد، محدود است.
وقتی تمام مقادیر قابل تجمیع را در تمام کلیدهای تجمیع جمع میکنید، مجموع باید کمتر از بودجه مشارکت باشد. بودجه به ازای هر worklet origin و هر روز محدود میشود و برای Protected Audience API و Shared Storage worklets جداگانه است. برای هر روز از یک پنجره متحرک تقریباً ۲۴ ساعت گذشته استفاده میشود. اگر یک گزارش قابل تجمیع جدید باعث شود که از بودجه تجاوز شود، گزارش ایجاد نمیشود.
بودجه مشارکت با پارامتر L1 نشان داده شده است و به ازای هر ده دقیقه در روز، 216 (65536) با حداقل 220 (1048576) تنظیم شده است. برای کسب اطلاعات بیشتر در مورد این پارامترها، به توضیحات مراجعه کنید.
مقدار بودجه مشارکت دلخواه است، اما نویز با آن مقیاسبندی میشود. میتوانید از این بودجه برای به حداکثر رساندن نسبت سیگنال به نویز در مقادیر خلاصه استفاده کنید (در بخش نویز و مقیاسبندی بیشتر مورد بحث قرار خواهد گرفت).
برای کسب اطلاعات بیشتر در مورد بودجههای مشارکتی، به توضیح مربوطه مراجعه کنید. همچنین، برای راهنمایی بیشتر به بودجه مشارکتی مراجعه کنید.
محدودیت مشارکت در هر گزارش
بسته به فراخواننده، محدودیت مشارکت ممکن است متفاوت باشد و برای Shared Storage، این محدودیتها پیشفرض هستند که میتوانند لغو شوند. در حال حاضر، گزارشهای تولید شده برای فراخوانندگان Shared Storage API حداکثر تا 20 مشارکت در هر گزارش را پوشش میدهند. از سوی دیگر، فراخوانندگان Protected Audience API حداکثر تا 100 مشارکت در هر گزارش را پوشش میدهند. این محدودیتها برای ایجاد تعادل بین تعداد مشارکتهایی که میتوانند جاسازی شوند و اندازهی payload انتخاب شدهاند.
برای Shared Storage، مشارکتهای انجامشده در یک عملیات run() یا selectURL() در یک گزارش دستهبندی میشوند. برای Protected Audience، مشارکتهای انجامشده توسط یک مبدأ واحد در یک حراج با هم دستهبندی میشوند.
مشارکتها با حاشیهنویسی
مشارکتها با ویژگی padding بیشتر اصلاح میشوند. عمل padding بار مفید، اطلاعات مربوط به تعداد واقعی مشارکتهای جاسازیشده در گزارش قابل تجمیع را حفظ میکند. padding بار مفید را با مشارکتهای null (یعنی با مقدار ۰) افزایش میدهد تا به طول ثابتی برسد.
گزارشهای قابل تجمیع
به محض اینکه کاربر API تجمیع خصوصی را فراخوانی کند، مرورگر گزارشهای تجمیعی ایجاد میکند تا در زمان دیگری توسط سرویس تجمیع پردازش شوند و گزارشهای خلاصه تولید کنند. یک گزارش تجمیعی با فرمت JSON است و شامل یک لیست رمزگذاری شده از مشارکتها است که هر کدام یک جفت {aggregation key, aggregatable value} هستند. گزارشهای تجمیعی با تأخیر تصادفی تا یک ساعت ارسال میشوند.
مشارکتها رمزگذاری شدهاند و خارج از سرویس تجمیع قابل خواندن نیستند. سرویس تجمیع، گزارشها را رمزگشایی کرده و یک گزارش خلاصه تولید میکند. کلید رمزگذاری برای مرورگر و کلید رمزگشایی برای سرویس تجمیع توسط هماهنگکننده صادر میشود که به عنوان سرویس مدیریت کلید عمل میکند. هماهنگکننده لیستی از هشهای دودویی تصویر سرویس را نگه میدارد تا تأیید کند که تماسگیرنده مجاز به دریافت کلید رمزگشایی است.
یک نمونه گزارش قابل تجمیع با حالت اشکالزدایی فعال:
"aggregation_service_payloads": [
{
"debug_cleartext_payload": "omRkYXRhgaJldmFsdWVEAAAAgGZidWNrZXRQAAAAAAAAAAAAAAAAAAAE0mlvcGVyYXRpb25paGlzdG9ncmFt",
"key_id": "2cc72b6a-b92f-4b78-b929-e3048294f4d6",
"payload": "a9Mk3XxvnfX70FsKrzcLNZPy+00kWYnoXF23ZpNXPz/Htv1KCzl/exzplqVlM/wvXdKUXCCtiGrDEL7BQ6MCbQp1NxbWzdXfdsZHGkZaLS2eF+vXw2UmLFH+BUg/zYMu13CxHtlNSFcZQQTwnCHb"
}
],
"debug_key": "777",
"shared_info": "{\"api\":\"shared-storage\",\"debug_mode\":\"enabled\",\"report_id\":\"5bc74ea5-7656-43da-9d76-5ea3ebb5fca5\",\"reporting_origin\":\"https://localhost:4437\",\"scheduled_report_time\":\"1664907229\",\"version\":\"0.1\"}"
گزارشهای قابل تجمیع را میتوان از صفحه chrome://private-aggregation-internals بررسی کرد:

برای اهداف آزمایشی، میتوان از دکمهی «ارسال گزارشهای انتخابشده» برای ارسال فوری گزارش به سرور استفاده کرد.
گزارشهای قابل تجمیع را جمعآوری و دستهبندی کنید
مرورگر گزارشهای قابل تجمیع را با استفاده از مسیر شناختهشدهی ذکر شده، به مبدأ worklet حاوی فراخوانی Private Aggregation API ارسال میکند:
- برای فضای ذخیرهسازی مشترک:
/.well-known/private-aggregation/report-shared-storage - برای مخاطبان محافظتشده:
/.well-known/private-aggregation/report-protected-audience
در این نقاط پایانی، شما نیاز به راهاندازی یک سرور - که به عنوان یک جمعآوریکننده عمل میکند - دارید که گزارشهای قابل جمعآوری ارسالی از کلاینتها را دریافت میکند.
سپس سرور باید گزارشها را دستهبندی کرده و به سرویس تجمیع ارسال کند. بر اساس اطلاعات موجود در فایل رمزگذاری نشده گزارش تجمیعپذیر، مانند فیلد shared_info ، دستههایی ایجاد کنید. در حالت ایدهآل، دستهها باید حاوی ۱۰۰ گزارش یا بیشتر در هر دسته باشند.
شما میتوانید تصمیم بگیرید که گزارشها را به صورت روزانه یا هفتگی دستهبندی کنید. این استراتژی انعطافپذیر است و میتوانید استراتژی دستهبندی خود را برای رویدادهای خاصی که انتظار حجم بیشتری دارید تغییر دهید - مثلاً روزهایی از سال که انتظار میرود تعداد نمایشها بیشتر باشد. دستهبندیها باید شامل گزارشهایی از همان نسخه API، مبدا گزارش و زمانبندی گزارش باشند.
شناسههای فیلتر
API و سرویس تجمیع خصوصی، امکان استفاده از شناسههای فیلترینگ را برای پردازش اندازهگیریها در سطح جزئیتر، مانند هر کمپین تبلیغاتی، به جای پردازش نتایج در پرسوجوهای بزرگتر، فراهم میکند.

برای شروع استفاده از این مورد از امروز، در اینجا چند گام کلی برای اعمال روی پیادهسازی فعلی شما آورده شده است.
مراحل ذخیرهسازی مشترک
اگر در جریان کاری خود از Shared Storage API استفاده میکنید:
مشخص کنید که ماژول Shared Storage جدید خود را کجا تعریف و اجرا خواهید کرد. در مثال زیر، ما فایل ماژول را
filtering-worklet.jsنامگذاری کردهایم که در زیرfiltering-exampleثبت شده است.(async function runFilteringIdsExample () { await window.sharedStorage.worklet.addModule('filtering-worklet.js'); await window.sharedStorage.run('filtering-example', { keepAlive: true, privateAggregationConfig: { contextId: 'example-id', filteringIdMaxBytes: 8 // optional } }}); })();توجه داشته باشید که
filteringIdMaxBytesبرای هر گزارش قابل تنظیم است و در صورت عدم تنظیم، به طور پیشفرض روی ۱ قرار دارد. این مقدار پیشفرض برای جلوگیری از افزایش غیرضروری اندازه payload و در نتیجه هزینههای ذخیرهسازی و پردازش است. برای اطلاعات بیشتر به توضیح مشارکت انعطافپذیر مراجعه کنید.در
filtering-worklet.js، وقتی یک مشارکت را بهprivateAggregation.contributeToHistogram(...)در داخل worklet مربوط به Shared Storage ارسال میکنید، میتوانید یک شناسه فیلترینگ مشخص کنید.// Within filtering-worklet.js class FilterOperation { async run() { let contributions = [{ bucket: 1234n, value: 56, filteringId: 3n // defaults to 0n if not assigned, type bigint }]; for (const c of contributions) { privateAggregation.contributeToHistogram(c); } … } }); register('filtering-example', FilterOperation);گزارشهای قابل تجمیع به جایی که نقطه پایانی
/.well-known/private-aggregation/report-shared-storageرا تعریف کردهاید، ارسال میشوند. برای کسب اطلاعات بیشتر در مورد تغییرات مورد نیاز در پارامترهای کار سرویس تجمیع، به راهنمای فیلتر کردن شناسهها مراجعه کنید.
پس از تکمیل دستهبندی و ارسال آن به سرویس تجمیع مستقر شده، نتایج فیلتر شده شما باید در گزارش خلاصه نهایی منعکس شود.
مراحل مخاطب محافظتشده
اگر در جریان کاری خود از API مخاطب محافظتشده استفاده میکنید:
در پیادهسازی فعلی خود از Protected Audience، میتوانید موارد زیر را برای اتصال به Private Aggregation تنظیم کنید. برخلاف Shared Storage، هنوز امکان پیکربندی حداکثر اندازه شناسه فیلتر وجود ندارد. به طور پیشفرض، حداکثر اندازه شناسه فیلتر ۱ بایت است و روی
0nتنظیم میشود. به خاطر داشته باشید که این موارد در توابع گزارشدهی Protected Audience شما (مثلاًreportResult()یاgenerateBid()) تنظیم میشوند.const contribution = { ... filteringId: 0n }; privateAggregation.contributeToHistogram(contribution);گزارشهای تجمیعپذیر به جایی که شما نقطه پایانی
/.well-known/private-aggregation/report-protected-audienceرا تعریف کردهاید، ارسال میشوند. پس از تکمیل دستهبندی و ارسال به سرویس تجمیع مستقر شده، نتایج فیلتر شده شما باید در گزارش خلاصه نهایی شما منعکس شود. توضیحات زیر برای API گزارشدهی انتسابی و API تجمیع خصوصی و همچنین پیشنهاد اولیه موجود است.
برای مطالعهی جزئیات بیشتر، به راهنمای فیلتر کردن شناسهها در سرویس تجمیع مراجعه کنید یا به بخشهای API گزارشدهی انتساب مراجعه کنید.
خدمات تجمیع

سرویس تجمیع، گزارشهای تجمیعپذیر رمزگذاریشده را از گردآورنده دریافت کرده و گزارشهای خلاصهای تولید میکند. برای استراتژیهای بیشتر در مورد نحوه تجمیع گزارشهای تجمیعپذیر در گردآورنده خود، به راهنمای تجمیع ما مراجعه کنید.
این سرویس در یک محیط اجرای قابل اعتماد (TEE) اجرا میشود که سطحی از اطمینان را برای یکپارچگی دادهها، محرمانگی دادهها و یکپارچگی کد فراهم میکند. اگر میخواهید نگاه دقیقتری به نحوه استفاده از هماهنگکنندهها در کنار TEEها داشته باشید، درباره نقش و هدف آنها بیشتر بخوانید.
گزارشهای خلاصه
گزارشهای خلاصه به شما امکان میدهند دادههایی را که جمعآوری کردهاید با اضافه کردن نویز مشاهده کنید. میتوانید برای مجموعهای از کلیدها، گزارشهای خلاصه درخواست کنید.
یک گزارش خلاصه شامل مجموعهای از جفتهای کلید-مقدار به سبک دیکشنری JSON است. هر جفت شامل موارد زیر است:
-
bucket: کلید تجمیع به صورت یک رشته عدد دودویی. اگر کلید تجمیع مورد استفاده "123" باشد، آنگاه bucket برابر با "1111011" است. -
value: مقدار خلاصه برای یک هدف اندازهگیری معین، که از تمام گزارشهای قابل جمعآوری موجود با افزودن نویز، خلاصه شده است.
برای مثال:
[
{"bucket":` `"111001001",` `"value":` `"2558500"},
{"bucket":` `"111101001",` `"value":` `"3256211"},
{"bucket":` `"111101001",` `"value":` `"6536542"},
]
نویز و مقیاسبندی
برای حفظ حریم خصوصی کاربر، سرویس تجمیع، هر بار که گزارش خلاصه درخواست میشود، یک بار به هر مقدار خلاصه نویز اضافه میکند. مقادیر نویز به صورت تصادفی از توزیع احتمال لاپلاس استخراج میشوند. در حالی که شما کنترل مستقیمی بر نحوه اضافه شدن نویز ندارید، میتوانید بر تأثیر نویز بر دادههای اندازهگیری آن تأثیر بگذارید.
توزیع نویز صرف نظر از مجموع تمام مقادیر قابل تجمیع، یکسان است. بنابراین، هرچه مقادیر قابل تجمیع بالاتر باشند، احتمال تأثیر نویز کمتر است.
برای مثال، فرض کنید توزیع نویز دارای انحراف معیار ۱۰۰ است و در مرکز صفر قرار دارد. اگر مقدار گزارش قابل تجمیع جمعآوریشده (یا «مقدار قابل تجمیع») فقط ۲۰۰ باشد، انحراف معیار نویز ۵۰٪ از مقدار تجمیعشده خواهد بود. اما اگر مقدار قابل تجمیع ۲۰۰۰۰ باشد، انحراف معیار نویز فقط ۰.۵٪ از مقدار تجمیعشده خواهد بود. بنابراین، مقدار قابل تجمیع ۲۰۰۰۰ نسبت سیگنال به نویز بسیار بالاتری خواهد داشت.
بنابراین، ضرب کردن مقدار قابل تجمیع شما در یک ضریب مقیاسبندی میتواند به کاهش نویز کمک کند. ضریب مقیاسبندی نشان میدهد که شما چقدر میخواهید یک مقدار قابل تجمیع مشخص را مقیاسبندی کنید.

افزایش مقادیر با انتخاب یک ضریب مقیاسبندی بزرگتر، نویز نسبی را کاهش میدهد. با این حال، این امر همچنین باعث میشود که مجموع تمام مشارکتها در تمام سطوح سریعتر به حد بودجه مشارکت برسند. کاهش مقادیر با انتخاب یک ثابت ضریب مقیاسبندی کوچکتر، نویز نسبی را افزایش میدهد، اما خطر رسیدن به حد بودجه را کاهش میدهد.

برای محاسبهی ضریب مقیاسبندی مناسب، بودجهی مشارکت را بر حداکثر مجموع مقادیر قابل تجمیع در تمام کلیدها تقسیم کنید.
برای کسب اطلاعات بیشتر به مستندات بودجه مشارکت مراجعه کنید.
مشارکت کنید و بازخورد خود را به اشتراک بگذارید
API مربوط به Private Aggregation در دست بررسی فعال است و ممکن است در آینده تغییر کند. اگر این API را امتحان کردید و بازخوردی داشتید، خوشحال میشویم آن را بشنویم.
- گیتهاب : توضیحات را بخوانید، سوال بپرسید و در بحث شرکت کنید .