Կոդիմ-պիցցա

Բարև, Հաբր: Մենք ինքնաբուխ անցկացրինք մեր առաջին ներքին հաքաթոնը։ Ես որոշեցի կիսվել ձեզ հետ իմ ցավերով ու եզրակացություններով՝ դրան պատրաստվելու 2 շաբաթում, ինչպես նաև այն նախագծերով, որոնք ստացվեցին։

Կոդիմ-պիցցա

Ձանձրալի մասը մարքեթինգով հետաքրքրվողների համար

Ես կսկսեմ մի փոքրիկ պատմությունից:

Ապրիլի սկիզբ. Մեր գրասենյակում տեղի է ունենում MskDotNet համայնքի առաջին հաքաթոնը։ Տատուինի ճակատամարտն այս անգամ եռում է մեր գալակտիկայում: Շաբաթ. 20 թիմ. Պիցցա. Ամեն ինչ շատ անկեղծ է (ապացույցներ). Դահլիճի շուրջը լողում է փչովի R2-D2: Թիմերը գրում են ամենաճիշտ ալգորիթմները՝ քարտեզի վրա ամենավտանգավոր մրցավազքը անցնելու համար: Մենք տեղափոխում ենք առաջին մրցավազքի մեկնարկը: Թխվածքաբլիթները և սուրճը փրկություն են: Կազմակերպիչներն ու ես սպասում էինք, որ շաբաթ օրը ճաշից հետո շատերը կմեկնեն։ Բայց ոչ. 12 ժամ կոդավորման հետևում: Վերջնական. Ինչ-որ բան ընկնում է, ինչ-որ բան չի սկսվում: Բայց բոլորը երջանիկ են։ Մեր թիմը հաղթում է. Մենք կրկնակի ուրախ ենք.

Ես կիսում եմ իմ ուրախությունը Slack-ում և միտքս գալիս է. «Մենք պետք է անենք մեր սեփական հաքաթոնը»: Ես գրում եմ մեր սպասարկման կետ Սաշա. Լռություն։

Առավոտյան. Գրասենյակում սուրճ եմ խմում։ Ես տեսնում եմ, որ Սաշան ետևից է մոտենում։ «Լիզա, սա հիանալի է: Ապրիլի 21-ին կարևոր օր ունենք. Եկեք անենք դա!" WTF!? Այնքան արագ? Ա. Ինչ? Ապրիլի կեսերին ես պետք է թռչեմ Սիկտիվկար պրակտիկայի համար: Եվ դժոխք դրա հետ: Եկեք.

Մնաց 2 շաբաթ։ Ես երբեք չեմ եղել հաքաթոնի միակ կազմակերպիչը։ Թող դա ներքին լինի: Ես կարդացի հոդվածներ այս թեմայով: Կոշտ. Դա տեւում է մի քանի ամիս։ Պահանջվում է մի քանի հոգի։ Դուք պետք է մտածեք ապրանքների, մրցանակների, պայմանների, ժամանակացույցի, հետաքրքրությունների մասին, հասկանաք նպատակը, բյուջեները: Կամ գուցե նույնիսկ պարզել կյանքի իմաստը: Ես հաստատ ժամանակին չեմ հասնի: Իսկ մինչ դուք կարդում էիք ու պատրաստվում էիք, արդեն մեկ շաբաթ էր անցել։ Ժամանակն է մոռանալ հոդվածները և սկսել ինչ-որ բան անել։

Ծանոթացեք մեր ստուգաթերթին՝ 1 շաբաթում ներքին հաքաթոն անցկացնելու համար

  • ՊլանԴու հանգիստ նստում ես ու ցուցակ գրում, թե ինչ է պետք անել հաքաթոնի համար: 30 րոպե.
  • ԱռաջադրանքՄասնակիցներն առաջարկում և ընտրում են այն նախագծերը, որոնք ցանկանում են ստեղծել Google Sheets-ում: Ֆոնային առաջադրանք, 2 ժամ.
  • ՉվացուցակՁեր ծնկի վրա գրում եք ժամանակի կարճ դասակարգում՝ հաշվի առնելով 3 ընդմիջումը և եզրափակիչը։ 20 րոպե.
  • ՀրամաններՀրապարակեք հաղորդագրություն հաքաթոնի մասին սպասարկման կայանից ժամանակացույցով Slack/mail/ և այլն ՏՏ ալիքներում և ստեղծեք առանձին ալիք հաքաթոնի համար: Դրանում բոլորը բաժանված են թիմերի, իսկ նրանք, ովքեր չեն կողմնորոշվում, դա անում են հաքաթոնի առաջին 5 րոպեներին։ Ֆոնային առաջադրանք, 2 ժամ.
  • ԲուլկիներԴուք երկու ծրագրավորողներով ապրանք եք առաջարկում, տալիս եք դիզայներին՝ մատուցելու և պատրաստ եք ստանում: Ֆոնային առաջադրանք, 3 օր.
  • ՀեքըթոնԴուք գալիս եք գրասենյակ, սկզբում համակարգում եք բոլորին, գնում եք ձեր գործին, կարդում եք Reddit-ը, կարևոր է հայտարարում թարմ պիցցայի մասին ամեն ընդմիջում, լուսանկարում մայրամուտը, հայտարարում եզրափակիչը, միասին քվեարկում և ընտրում հաղթողին: 1 օր.
  • Աստղանիշի տակԱնշուշտ, դուք անընդհատ մտածում եք, որ ամեն ինչ լավ է: Իհարկե, ոչ բոլորը կտեսնեն ձեր ուղերձը, և ավելի լավ է ոմանց հետ անձամբ զրուցել: Իհարկե, եթե ինչ-որ մեկը օգնի քեզ, ամեն ինչ 2 անգամ ավելի հեշտ կդառնա (ինձ օգնեց հրաշալի Ալենան):

Հեքըթոնի ամսաթվի մասին ավելի քիչ ձանձրալի հատվածը

Ինչո՞ւ ապրիլի 21. Այս օրը նշանակալից է մեզ համար։ Ուղիղ մեկ տարի առաջ՝ ապրիլի 21-ին, դաշնային գովազդային արշավի մեկնարկից հետո առաջին շաբաթավերջին մենք ծանրաբեռնված էինք։ Հաջորդ օրը՝ կիրակի, առավոտյան ժամը 8-ից մեր թիմը աշխատանքի էր։ Հետո մենք ստեղծեցինք Sundayhackathon-ի տախտակ Trello-ում և սկսվեց հերթափոխային շաբաթը՝ օրական 12 ժամ: Իրավիճակն այնքան կրիտիկական էր, որ մենք անգամ ուտելու ժամանակ չունեինք, և մեզ կերակրում էին այլ թիմերի տղաներ։

Կոդիմ-պիցցա

Ավելի մանրամասն պատմություն կարող եք կարդալ այստեղ Ֆյոդոր Օվչիննիկովի էջը (մեր գլխավոր տնօրենը): Այդ ժամանակվանից մենք շատ ենք փոխվել, բայց հիմա հաստատ չենք մոռանա ամսաթիվը։

Այս տարի մենք որոշեցինք, որ այս իրադարձությունն արժե հավերժացնել սերունդների հիշողության մեջ, և լավագույն ավանդույթներով կազմակերպեցինք Դոդոյի պատմության մեջ առաջին ներքին հաքաթոնը, որը տևեց 10 ժամ։

Հեքըթոնային նախագծերի ամենաձանձրալի մասը

Հրաժարում. բոլոր նկարագրությունները գրվել են հենց տղաների կողմից, ուստի տեքստի հեղինակությունն իմը չէ:

Oleg Learning (մեքենայական ուսուցում)

Դիմա Կոչնև, Սաշա Անդրոնով (@alexandronov)

Նրանք ցանկանում էին ստեղծել նեյրոնային ցանց, որը կորոշեր, թե ինչ տեսակի պիցցա է պատկերված լուսանկարում առանց որևէ գիտության։ Արդյունքում մենք պատրաստեցինք շատ պարզ և խաղալիք. այն ճանաչում է 10 պիցցան, մենք մոտավորապես պարզեցինք, թե ինչպես է ամեն ինչ աշխատում, որքան հնարավոր է մեկ օրվա ընթացքում (~10 ժամ):

Կոդիմ-պիցցա

Մասնավորապես, մենք հասկացանք, որ ոլորտը հասել է մի մակարդակի, երբ սովորական մշակողը կարող է վերցնել պատրաստի գրադարաններ, կարդալ փաստաթղթերը և մարզել իր նեյրոնային ցանցը՝ առանց թեմայի խորը իմացության: Եվ դա բավական լավ կաշխատի իրական խնդիրները լուծելու համար:

Օգտագործված գործիքներ.

  • imageai — հարմար և պարզ գրադարան՝ մեքենայական ուսուցման և համակարգչային տեսողության հետ աշխատելու համար:
  • Մենք փորձեցինք երկու մոդել՝ ResNet50, Yolo:
  • Կոդը գրվել է, իհարկե, Python-ով։

Մենք ունեինք 11000 լուսանկար, բայց գրեթե 3/4-ը աղբ էր, իսկ մնացածն ուներ տարբեր, անհամապատասխան անկյուններ։ Արդյունքում մենք վերցրեցինք պատրաստի մոդել (որը պարզապես գիտի, թե ինչպես գտնել պիցցա) և դրա օգնությամբ առանձնացրինք աղբը։ Հաջորդը, լուսանկարի վերնագրում ներառված էր պիցցայի անունը, այնպես որ մենք այն դասավորեցինք թղթապանակների մեջ, բայց պարզվեց, որ անունները չեն համընկնում իրականության հետ, և մենք պետք է այն մաքրենք մեր ձեռքերով: Ի վերջո, մնաց մոտ 500-600 լուսանկար, պարզ է, որ դա աննշան գումար է, բայց, այնուամենայնիվ, սա բավական էր 10 պիցցան իրարից բաժանելու համար։

Ցանցը մարզելու համար մենք վերցրեցինք ամենաէժան վիրտուալ մեքենան Azure-ում NVIDIA Tesla K80-ով: Նրանք մարզվել են դրա վրա 100 դարաշրջան, բայց պարզ էր, որ ցանցը գերհագեցված էր 50 դարաշրջանից հետո, քանի որ առկա էր փոքր տվյալների բազա։

Իրականում ամբողջ խնդիրը լավ տվյալների բացակայությունն է։

Կոդիմ-պիցցա

Միգուցե մենք մի փոքր շփոթել ենք եզրույթները, բայց պետք է հաշվի առնել, որ այս բոլոր հարցերի հետ աշխատելու փորձ ընդհանրապես չունենք։

GUI NOOBS-ի համար (պիցցա պատվիրելու վահանակ)

Միշա Կումաչև (Սերիդան), Ժենյա Բիկկինին, Ժենյա Վասիլև

Մենք հավաքել ենք կոնսոլային հավելվածի նախատիպը գիկերի համար, որի շնորհիվ կարող եք պատվիրել պիցցա տերմինալի կամ հրամանի տողով, կամ նույնիսկ այն ինտեգրել տեղակայման խողովակաշարին և հաջող թողարկումից հետո պիցցա առաքել գրասենյակ:

Կոդիմ-պիցցա

Աշխատանքը բաժանված էր մի քանի մասի. մենք պարզեցինք, թե ինչպես է աշխատում բջջային հավելվածների մեր API-ն, հավաքեցինք մեր սեփական CLI-ն՝ օգտագործելով օկլիֆ և կազմաձևեց մեր հավաքած փաթեթի հրապարակումը: Վերջին առաջադրանքը ենթադրում էր մի քանի տհաճ րոպե հաքաթոնի ավարտին: Մեզ մոտ ամեն ինչ աշխատում էր տեղական մակարդակում, և նույնիսկ փաթեթի հին հրապարակված տարբերակներն էին աշխատում, բայց նորերը (որոնք ավելացրեցին ավելի հետաքրքիր գործառույթներ և էմոցիոններ) հրաժարվեցին աշխատել: Մենք մոտ 40 րոպե ծախսեցինք՝ փորձելով պարզել, թե ինչն է սխալ եղել, բայց ի վերջո ամեն ինչ կախարդական կերպով աշխատեց ինքնուրույն):

Հեքըթոնի մեր առավելագույն ծրագիրը մեր CLI-ի միջոցով գրասենյակ պիցցայի իրական պատվերն էր: Մենք փորձարկման նստարանին մի տասնյակ անգամ վազեցինք ամեն ինչ, բայց իմ ձեռքերը դեռ դողում էին, երբ ես հրամաններ մուտքագրեցի արտադրության մեջ:

Կոդիմ-պիցցա

Արդյունքում մենք վերջապես դա արեցինք։

Կոդիմ-պիցցա

CourierGo

Անտոն Բրուժմելև (հեղինակ), Վանյա Զվերև, Գլեբ Լեսնիկով (անթրոպիա), Անդրեյ Սարաֆանով

Մենք վերցրեցինք «App for Courier» գաղափարը:

Նախապատմություն պատրաստման մասին.Սկզբում ինձ հետաքրքրում էր, թե ինչպիսի՞ հնարավորություններ կարող են լինել հավելվածում: Առաջացել է ֆունկցիոնալության հետևյալ ցանկը.

  • Հավելվածը մուտքագրվում է առաքման դրամարկղ՝ օգտագործելով կոդը:
  • Հավելվածն անմիջապես ցույց է տալիս առկա պատվերներն ու պատվերները, որոնք պետք է ընդունվեն:
  • Սուրհանդակը նշում է պատվերը և այն տանում ճանապարհորդության ժամանակ:
  • Նրան ցույց են տալիս գնահատված ժամանակը և արդյոք նա ժամանակին է, թե ոչ։
  • Ցույց է տալիս հաճախորդին, որ առաքիչը հեռացել է:
  • Հաճախորդին սկսում է ցույց տալ առաքիչի կետը քարտեզի վրա և գնահատված ժամանակը:
  • Սուրհանդակը կարող է հաճախորդին գրել հավելվածից չաթում:
  • Հաճախորդը կարող է գրել սուրհանդակին հավելվածից չաթի միջոցով:
  • Ժամանումից հինգ րոպե առաջ հաճախորդը հաղորդագրություն է ստանում, որ առաքիչը մոտ է, պատրաստ եղեք։
  • Սուրհանդակը դիմումում նշում է, որ եկել է և սպասում է։
  • Սուրհանդակը զանգահարում է հավելվածից մեկ սեղմումով և հայտնում, որ (բարձրանում է, ժամանել է և այլն)
  • Հաճախորդը ընդունում է պատվերը և մուտքագրում է PIN ծածկագիրը հավելվածից կամ SMS՝ առաքումը հաստատելու համար (որպես ստորագրություն) Որպեսզի առաքիչը չկարողանա նախապես կատարել առաքումը, եթե ուշանա։
  • Պատվերը նշվում է որպես առաքված համակարգում:

Գումարած մի քանի այլընտրանքային սցենարներ.

  • Սուրհանդակը կարող է պատվերը նշել որպես չառաքված և ընտրել պատճառը։
  • Եթե ​​ուշացաք, սուրհանդակը կարող է մեկ կոճակով SMS-ի միջոցով էլեկտրոնային վկայական տալ։ Կամ վկայականը ավտոմատ կերպով հասնում է, եթե առաքման վերջնաժամկետը չի պահպանվում:

Այս նախագծի խոստման ու անհրաժեշտության զգացումը, իհարկե, աշխուժացնող էր։

Հաջորդ օրը մենք գնացինք լանչի թիմի հետ և քննարկեցինք, թե ինչպիսին կլինի հավելվածի նվազագույն ֆունկցիոնալությունը:

Արդյունքում կազմվեց հաքաթոնում անելիքների հետևյալ ցանկը.

  • Մուտք գործեք առաքման դրամարկղ:
  • Ցուցադրել ընթացիկ դիրքը:
  • Տվյալներն ուղարկեք արտաքին API-ին (կոորդինատները, ստացան պատվերը, առաքվեցին պատվերը):
  • Ստացեք տվյալներ արտաքին API-ից (ընթացիկ սուրհանդակային պատվերներ):
  • Ուղարկեք միջոցառում՝ նշելով, որ դուք վերցրել եք պատվերը առաքման/առաքման համար:
  • Կայքի քարտեզի վրա ցուցադրեք սուրհանդակի ներկայիս դիրքը:

Հիմնական աշխատանքը, ինչպես թվում էր, հետնամասի ստեղծումն էր՝ հենց հավելվածը (քննարկումներից հետո մենք ընտրեցինք ReactNative-ը՝ հավելվածը մշակելու համար, ավելի ճիշտ՝ դրա շրջանակը. expo.io, որը թույլ է տալիս ընդհանրապես չգրել հայրենի կոդը): Ինչ վերաբերում է հետին պլանին, ի սկզբանե հույս կար Վանյա Զվերևի վրա, քանի որ նա փորձառու էր մեր ծառայության ձևանմուշների և k8-ների հետ աշխատելու մեջ (որը նա ստանձնեց): Անդրեյ Սարաֆանովը և ես վերցրեցինք ReactNative-ը պտտվելու համար:

Ես որոշեցի փորձել անմիջապես ստեղծել աշխատանքային շտեմարան հենց նախագծի համար: Գիշերը ժամը 12-ին ես հանդիպեցի այն փաստի, որ ֆոնի վրա գեոլոկացիան լավ չի աշխատում ReactNative-ում, եթե հայրենի կոդը չես գրում, ես մի փոքր հիասթափվեցի։ Հետո ես բաց թողեցի, երբ հասկացա, որ ես կարդում եմ ոչ թե expo.io շրջանակի փաստաթղթերը, այլ ReactNative-ի: Արդյունքում, երեկոյի ընթացքում ես արդեն հասկացա, թե ինչպես ստանալ ընթացիկ դիրքը expo.io-ում և նկարել առանձին էկրաններ (մուտքի, պատվերի ցուցադրման և այլն):

Կոդիմ-պիցցա

Առավոտյան հաքաթոնում նրանք Գլեբին գրավեցին իրենց գերխոստումնալից նախագծի մեջ: Նրանք արագ մշակեցին ծրագիր, թե ինչ պետք է անել:

Կոդիմ-պիցցա

Մենք սխալվեցինք, երբ, համաձայն նախագծի ձևանմուշի, փորձեցինք հաղորդակցվել ոչ թե HTTP-ի, այլ GRPC-ի միջոցով, քանի որ ոչ ոք չգիտեր, թե ինչպես ստեղծել GRPC հաճախորդ JavaScript-ի համար: Ի վերջո, դրա վրա մոտ մեկուկես ժամ ծախսելուց հետո մենք հրաժարվեցինք այս գաղափարից։ Դրա պատճառով հետևի տղաները սկսեցին վերամշակել պատրաստի սերվերը GRPC-ից WebApi: Կես ժամ անց մենք վերջապես կարողացանք կապ հաստատել հավելվածի և հետին պլանի միջև, ահա և ահա: Բայց միևնույն ժամանակ, Գլեբը գրեթե ավարտում էր k8s-ի տեղակայումը և գումարած վարպետի համար հանձնառության ավտոմատ տեղադրումը: 🙂

Որպես պահեստ ընտրել ենք MySQL-ն, որպեսզի ռիսկի չդիմենք գոնե տվյալների բազայի հետ կապված (մտքեր ունեինք CosmosDb-ի մասին)։

Կոդիմ-պիցցա

In Summary:

  • Իրականացվել է առաքիչի ընթացիկ կոորդինատները հավելվածից տվյալների բազա պահելը:
  • Մենք տեղադրեցինք RabbitMQ և բաժանորդագրվեցինք առաքիչի պատվերը վերցնելու մասին հաղորդագրություններին, որպեսզի անմիջապես ցուցադրենք առաքիչի պատվերը հավելվածում:
  • Մենք սկսեցինք պատվերի առաքման ժամանակը պահել մեր տվյալների բազայում այն ​​բանից հետո, երբ սուրհանդակը սեղմեց հավելվածի կոճակը: Մենք ժամանակ չունեինք ռեբիթին ավելացնելու հետադարձ իրադարձություն ուղարկելը, որ պատվերը առաքվել է:
  • Ես քարտեզի ցուցադրում էի կայքի ընթացիկ պատվերի էջում՝ առաքիչի ներկայիս դիրքով: Բայց այս ֆունկցիոնալությունը մի փոքր անավարտ մնաց, քանի որ հնարավոր չէր կարգավորել CORS-ը շրջակա միջավայրում՝ մեր նոր ծառայությունից կոորդինատներ ստանալու համար:

M87

Ռոմա Բուկին, Գոշա Պոլևոյ (georgepolevoy), Արտյոմ Տրոֆիմուշկին

Մենք ցանկանում էինք ներդնել OpenID Connect պրովայդեր, քանի որ այս պահին մենք օգտագործում ենք մեր իսկ դիզայնի նույնականացման արձանագրությունը, և դա մի շարք դժվարություններ է ստեղծում՝ պատվիրատուների գրադարաններ, արտաքին գործընկերների կողմից անհարմար աշխատանք, անվտանգության հնարավոր խնդիրներ (ի վերջո , OAuth2.0-ը և OpenID Connect-ը հղման իրականացման մեջ կարող են անվտանգ համարվել, բայց ես վստահ չեմ մեր լուծման մասին):

Կոդիմ-պիցցա

Մենք ստեղծել ենք առանձին ծառայություն, որը նմանակում է անձնական տվյալների պահպանման ծառայությանը, որպեսզի ստեղծենք նույնականացման մատակարարի մի փոքր Country-Agnostic մոդել, որը կգնա առանձին ծառայության անձնական տվյալների համար (դա ապագայում հնարավորություն կտա ունենալ մեկ ծառայություն որը կարելի է մուտք գործել ցանկացած երկրում գրանցման միջոցով, և միևնույն ժամանակ համապատասխանել GDPR-ին և այլ դաշնային օրենքներին): Մենք արեցինք այս մասը, ինչպես և մատակարարը, և հաջողությամբ կապեցինք դրանք միմյանց հետ: Այնուհետև անհրաժեշտ էր ստեղծել API, որը կպաշտպանվեր մատակարարի կողմից թողարկված նշաններով, կաջակցեր դրանց ներքննությունը մատակարարի միջոցով և կվերադարձներ պաշտպանված տվյալները, եթե հարցումը բավարարում էր թույլտվության քաղաքականությանը (մենք ստուգում ենք, որ օգտագործողը վավերացված է ըստ Bearer սխեմայի: , նրա նշանը պարունակում է որոշակի շրջանակ + y Օգտատերն ինքն ունի թույլտվություն, որը թույլ է տալիս կատարել զանգը): Այս հատվածը նույնպես ավարտվեց. Վերջին բաղադրիչը JavaScript-ի հաճախորդն էր, որին տրվելու էր նշան, որի օգնությամբ այն կանվաներ պաշտպանված API։ Մենք ժամանակ չունեինք այս հատվածն անելու։ Այսինքն՝ ամբողջ ֆունկցիոնալ մասը պատրաստ էր, բայց ճակատային մասը պատրաստ չէր ցուցադրելու ամբողջ համակարգի ֆունկցիոնալությունը։

E-E-E (խաղալիք)

Դիմա Աֆոնչենկո, Սաշա Կոնովալով

Մենք պատրաստեցինք մինի-խաղալիք յունկայի վրա, որտեղ թրթռուն ձեռքերը երշիկ են նետում պիցցայի վրա: Եթե ​​նրբերշիկը սխալ եք դնում, էկրանին հայտնվում է տխուր «Մերժված» հաղորդագրությունը, իսկ եթե ամբողջ նրբերշիկը ճիշտ է դրված, պատահական փաստ է հայտնվում պիցցայի մասին։

Կոդիմ-պիցցա

Մենք ուզում էինք երկրորդ մակարդակը լոլիկներ նետել, բայց ժամանակ չունեինք։

Կոդիմ-պիցցա

Կարճ շարունակություն. ո՞վ հաղթեց.

Հեքըթոնից առաջ զրուցեցինք տղաների հետ և հարցրի, թե ինչ մրցանակ կցանկանային ստանալ, եթե հաղթեն։ Պարզվեց, որ ամենաթանկ մրցանակը լինելու է «ճանապարհ դեպի սնունդ»։

Կոդիմ-պիցցա

Հետևաբար, ակնկալեք, որ շուտով կհայտարարենք ձեռքերով խաղ, որը պղպեղ է դնում պիցցայի վրա:

Ինչպես կարող էր նկատել ուշադիր ընթերցողը, «E-E-E (խաղալիք)» թիմը հաղթեց: Շնորհավոր տղաներ:

Հարցմանը կարող են մասնակցել միայն գրանցված օգտվողները։ Մուտք գործել, խնդրում եմ:

Ո՞ր նախագիծն է ձեզ ամենաշատը դուր եկել:

  • Oleg Learning (մեքենայական ուսուցում)

  • GUI NOOBS-ի համար

  • CourierGo

  • M87

  • E-E-E

Քվեարկել է 5 օգտատեր։ 3 օգտատեր ձեռնպահ է մնացել։

Source: www.habr.com

Добавить комментарий