CSS3 लूपबैक स्लाइड शो

CSS3 के लिए धन्यवाद, हम जावास्क्रिप्ट का उपयोग किए बिना एनीमेशन प्रभाव बना सकते हैं, जो कई डेवलपर्स के काम को सरल करेगा।
हमें CSS3 का दुरुपयोग नहीं करना चाहिए क्योंकि पुराने ब्राउज़र इसके सभी गुणों का समर्थन नहीं करते हैं। किसी भी स्थिति में, हम सभी CSS3 की क्षमता देखते हैं, और इस लेख में हम चर्चा करेंगे कि केवल CSS3 के एनीमेशन का उपयोग करके एक लूप इमेज स्लाइडर कैसे बनाया जाए।

-   CSS3


लेख के अनुभाग

प्रक्रिया को शुरू से अंत तक समझने के लिए, लेख की सामग्री नीचे दी गई है। कृपया ध्यान दें कि यह प्रभाव केवल आधुनिक ब्राउज़रों में ठीक से काम करेगा जो सीएसएस 3 गुणों का उपयोग करते हैं।

  1. परिचय
    CSS3 के बदलाव और मुख्य फ़्रेम एनीमेशन से संबंधित बुनियादी अवधारणाओं का विवरण।
  2. HTML मार्कअप
    छवि स्लाइडर के लिए HTML मार्कअप बनाएं।
  3. सीएसएस शैलियों
    स्लाइडर को प्रदर्शित करने के लिए एक स्टाइल शीट बनाएं।
  4. CSS3 कीफ़्रेम एनीमेशन
    स्लाइडर में एनीमेशन जोड़ना। हम यहां होने वाली विभिन्न प्रक्रियाओं पर विचार करेंगे।
  5. प्रगति बार
    हमारे स्लाइडर में एक प्रगति पट्टी जोड़ना।
  6. टूलटिप
    शीर्षकों को प्रदर्शित करने के लिए टूलटिप जोड़ना।
  7. CSS3 के संक्रमण
    संकेत जब CSS3 संक्रमण का उपयोग कर मँडरा
  8. रोकें और पुनः आरंभ करें
    मँडराते समय स्लाइडर रुक जाता है।
  9. प्रदर्शन
    हम कार्रवाई में स्लाइडर दिखाते हैं।
  10. निष्कर्ष
    अंतिम विचार।


1. परिचय



इस ट्यूटोरियल का उपयोग करने के लिए, आपको विशेष रूप से CSS3 के बदलाव और कीफ़्रेम एनिमेशन में CSS की बुनियादी समझ की आवश्यकता है।
इन सरल अवधारणाओं के संदर्भ में, हम देखेंगे कि एक कार्यात्मक छवि स्लाइडर कैसे बनाया जाए।

बेसिक CSS3 संक्रमण परिवर्तन

आमतौर पर, जब आप CSS का मान बदलते हैं, तो परिवर्तन स्टेटिक रूप से प्रदर्शित होते हैं। अब, संक्रमण संपत्ति के लिए धन्यवाद, हम आसानी से एक राज्य से दूसरे में बदलाव कर सकते हैं।

हम चार संक्रमण गुणों का उपयोग कर सकते हैं:

transition-property
सीएसएस संपत्तियों के नाम (ओं) को परिभाषित करता है जिसमें संक्रमण लागू किया जाना चाहिए।

transition-duration
उस समय को परिभाषित करता है जिसमें संक्रमण होना चाहिए।

transition-timing-function
यह निर्धारित करता है कि मध्यवर्ती संक्रमण मूल्यों की गणना कैसे की जाती है।

transition-delay
निर्धारित करता है कि संक्रमण कब शुरू होता है।

CSS3 के संक्रमण वर्तमान में सफारी 3.2+, क्रोम, फ़ायरफ़ॉक्स 4+, ओपेरा 10.5+ और IE 10. में समर्थित हैं क्योंकि तकनीक अभी भी अपेक्षाकृत नई है, ब्राउज़र उपसर्गों की आवश्यकता है । आवश्यक उपसर्गों को जोड़ने के लिए सिंटैक्स सभी ब्राउज़रों के लिए समान है। हम उन्हें इस लेख में छोड़ देंगे, लेकिन कोड में उपसर्ग शामिल करना याद रखें।

आइए देखें कि एक लिंक पर एक साधारण संक्रमण कैसे लागू किया जाए:
 a { color: #000; transition-property: color; transition-duration: 0.7s; transition-timing-function: ease-in; transition-delay: 0.3s; } a:hover { color: #fff; } 


किसी तत्व को एनीमेशन असाइन करते समय, आप एक संक्षिप्त रूप का भी उपयोग कर सकते हैं:
 a { color: #000; transition: color 0.7s ease-in 0.3s; } a:hover { color: #fff; } 


W3C में सभी " एनीमेशन गुण " की एक सूची है

बेसिक CSS3 एनीमेशन अवधारणाओं

CSS एनीमेशन हमें जावास्क्रिप्ट के बिना कुंजी फ्रेम के एक सेट का उपयोग करके एनिमेशन बनाने की अनुमति देता है।
CSS बदलावों के विपरीत, keyframe एनीमेशन वर्तमान में केवल WebKit ब्राउज़रों, फ़ायरफ़ॉक्स में समर्थित है, और जल्द ही IE 10 में। असमर्थित ब्राउज़र बस एनीमेशन कोड को अनदेखा करेंगे।

एक एनीमेशन संपत्ति में आठ उपप्रकार होते हैं:

animation-delay
यह निर्धारित करता है कि एनीमेशन कब शुरू होता है।

animation-direction
यह निर्धारित करता है कि एनीमेशन को लूप्स को बदलने में विपरीत दिशा में खेलना चाहिए या नहीं।

animation-duration
समय की लंबाई को परिभाषित करता है कि एनीमेशन एक चक्र को पूरा करने के लिए लेता है।

animation-iteration-count
रोकने से पहले एनीमेशन चक्रों की संख्या निर्धारित करता है।

animation-name
@Keyframes में नियम का नाम परिभाषित करता है।

animation-play-state
यह निर्धारित करता है कि एनीमेशन चल रहा है या रोका गया है।

animation-fill-mode
यह निर्धारित करता है कि निष्पादन से पहले और बाद में सीएसएस एनिमेशन को अपने लक्ष्य पर शैलियों को कैसे लागू करना चाहिए।

आइए देखें कि एक साधारण एनीमेशन को एक ब्लॉक में कैसे लागू किया जाए:
 /* ,     . */ div { animation-name: move; animation-duration: 1s; animation-timing-function: ease-in-out; animation-delay: 0.5s; animation-iteration-count: 2; animation-direction: alternate; -moz-animation-name: move; -moz-animation-duration: 1s; -moz-animation-timing-function: ease-in-out; -moz-animation-delay: 0.5s; -moz-animation-iteration-count: 2; -moz-animation-direction: alternate; -webkit-animation-name: move; -webkit-animation-duration: 1s; -webkit-animation-timing-function: ease-in-out; -webkit-animation-delay: 0.5s; -webkit-animation-iteration-count: 2; -webkit-animation-direction: alternate; } /*   . */ @keyframes move { from { transform: translateX(0); } to { transform: translateX(100px); } } @-moz-keyframes move { from { -moz-transform: translateX(0); } to { -moz-transform: translateX(100px); } } @-webkit-keyframes move { from { -webkit-transform: translateX(0); } to { -webkit-transform: translateX(100px); } } 


हम सभी एनीमेशन गुणों को एक साथ सेट करने के लिए एक शॉर्टहैंड नोटेशन का उपयोग कर सकते हैं:
 div { animation: move 1s ease-in-out 0.5s 2 alternate; -moz-animation: move 1s ease-in-out 0.5s 2 alternate; -webkit-animation: move 1s ease-in-out 0.5s 2 alternate; } 


मुख्य फ्रेम

प्रत्येक कीफ़्रेम का वर्णन है कि एनीमेशन में किसी निश्चित समय बिंदु पर एनिमेटेड तत्व को कैसे व्यवहार करना चाहिए। मुख्य फ़्रेम समय निर्धारित करने के लिए प्रतिशत मान लेते हैं: 0% - एनीमेशन शुरू करें, जबकि 100% - अंत। आप वैकल्पिक रूप से एनिमेशन के लिए मध्यवर्ती फ्रेम जोड़ सकते हैं।

 /*   0%  100% */ @keyframes move { 0% { transform: translateX(0); } 100% { transform: translateX(100px); } } /*     */ @keyframes move { 0% { transform: translateX(0); } 50% { transform: translateX(20px); } 100% { transform: translateX(100px); } } 


W3C में " CSS3 एनीमेशन " के बारे में बहुत उपयोगी और विस्तृत जानकारी है

हमारे स्लाइडर की बुनियादी संरचना

अब जब हम जानते हैं कि संक्रमण और एनिमेशन कैसे काम करते हैं, तो देखते हैं कि केवल CSS3 का उपयोग करके हमारे स्लाइडर को कैसे बनाया जाए। यह स्केच दिखाता है कि एनीमेशन को कैसे काम करना चाहिए:


जैसा कि आप देख सकते हैं, स्लाइडर कंटेनर होगा जिसमें छवियां प्रदर्शित की जाएंगी।
एनीमेशन बहुत सरल है: छवि दी गई दिशा का अनुसरण करती है, " top ", " z-index " और " opacity " के गुणों को बदलती है।
आइए स्लाइडर बनाने के लिए सीधे HTML मार्कअप पर जाएं।

2. HTML मार्कअप


HTML मार्कअप बहुत सरल है। यह अच्छी तरह से संगठित और एसईओ के अनुकूल है। चलो पहले पूर्ण कोड देखें, और फिर विस्तार से पता करें कि सब कुछ कैसे काम करता है।

 <div class="container"> <div id="content-slider"> <div id="slider"> <!--    --> <div id="mask"> <!--  --> <ul> <li id="first" class="firstanimation"> <!-- ID        --> <a href="#"> <img src="images/img_1.jpg" alt="Cougar"/> </a> <div class="tooltip"> <h1>Cougar</h1> </div> </li> <li id="second" class="secondanimation"> <a href="#"> <img src="images/img_2.jpg" alt="Lions"/> </a> <div class="tooltip"> <h1>Lions</h1> </div> </li> <li id="third" class="thirdanimation"> <a href="#"> <img src="images/img_3.jpg" alt="Snowalker"/> </a> <div class="tooltip"> <h1>Snowalker</h1> </div> </li> <li id="fourth" class="fourthanimation"> <a href="#"> <img src="images/img_4.jpg" alt="Howling"/> </a> <div class="tooltip"> <h1>Howling</h1> </div> </li> <li id="fifth" class="fifthanimation"> <a href="#"> <img src="images/img_5.jpg" alt="Sunbathing"/> </a> <div class="tooltip"> <h1>Sunbathing</h1> </div> </li> </ul> </div> <!--   --> <div class="progress-bar"></div> <!--  --> </div> <!--     --> </div> </div> 


div id="slider"
यह मुख्य स्लाइडर कंटेनर है। इसका कोई विशिष्ट कार्य नहीं है, लेकिन हमें एनीमेशन को रोकने के लिए इसकी आवश्यकता है।

div id="mask"
हम इस ब्लॉक का उपयोग स्लाइडर के बाहर होने वाली हर चीज को छिपाने के लिए करेंगे। इसके अलावा, मुखौटा हमें स्लाइडर की सामग्री को प्रदर्शित करने की अनुमति देता है।

li id="first" class="firstanimation"
प्रत्येक सूची आइटम में एक आईडी और एक वर्ग होता है। आईडी एक टूलटिप प्रदर्शित करता है, और वर्ग एक एनीमेशन से बंधा होता है जो होने वाला है।

div class="tooltip"
यह ब्लॉक छवि शीर्षक प्रदर्शित करता है। आप इसे अपनी आवश्यकताओं के आधार पर बदल सकते हैं, उदाहरण के लिए, इसे क्लिक करने योग्य बनाने या छोटा विवरण जोड़ने के लिए।

div class="progress-bar"
इस ब्लॉक में एक फ़ंक्शन होता है जो एनीमेशन की प्रगति को दर्शाता है।

अब CSS फ़ाइल बनाने का समय आ गया है।

3. सीएसएस शैलियों


आइए एक बुनियादी स्लाइडर संरचना बनाएं। इसका आकार चित्र के समान होगा। बॉर्डर प्रॉपर्टी इमेज के चारों ओर बॉर्डर बनाने के लिए उपयोगी होगी।

 /*   */ #slider { background: #000; border: 5px solid #eaeaea; box-shadow: 1px 1px 5px rgba(0,0,0,0.7); height: 320px; width: 680px; margin: 40px auto 0; overflow: visible; position: relative; } 


mask वर्ग उन सभी तत्वों को छिपा देगा जो स्लाइडर के बाहर स्थित हैं। इसकी ऊंचाई स्लाइडर की ऊंचाई के बराबर होनी चाहिए।

 /*      */ #mask { overflow: hidden; height: 320px; } 


अंत में, छवियों की सूची को सॉर्ट करने के लिए, हम " position: absolute " और " top: -325px " का उपयोग करेंगे ताकि सभी चित्र स्लाइडर के बाहर स्थित हों।

 /*   */ #slider ul { margin: 0; padding: 0; position: relative; } #slider li { width: 680px; /*   */ height: 320px; /*   */ position: absolute; top: -325px; /*   (  ) */ list-style: none; } 


कोड की इन कुछ पंक्तियों के साथ, हमने स्लाइडर मार्कअप बनाया। अब हमें बस एनीमेशन जोड़ने की जरूरत है।

4. CSS3 कीफ्रेम एनीमेशन




एनीमेशन से शुरू करने से पहले, हमें एनीमेशन की सही प्रस्तुति प्राप्त करने के लिए कुछ मापदंडों को परिभाषित करने की आवश्यकता है।
जैसा कि हम जानते हैं, एनीमेशन की पूरी अवधि 25 सेकंड होगी, लेकिन हमें यह जानना होगा कि 1 सेकंड में कितने प्रमुख फ्रेम होंगे।
आइए कई श्रृंखलाओं को हल करते हैं जो हमें महत्वपूर्ण फ़्रेमों की सटीक संख्या और एनीमेशन की पूर्ण अवधि देगा। यहाँ गणना कर रहे हैं:
हम स्लाइडर में छवियों की कुल संख्या निर्धारित करते हैं: 5 ;
हम प्रत्येक छवि के लिए एनीमेशन की अवधि निर्धारित करते हैं: 5 सेकंड ;
हम प्रत्येक की अवधि द्वारा छवियों की कुल संख्या को गुणा करके एनीमेशन की पूरी अवधि निर्धारित करते हैं: 5 छवियां × 5 सेकंड = 25 सेकंड ;
हम गणना करते हैं कि एक सेकंड में कितने प्रमुख फ्रेम (प्रतिशत) होंगे।
एनीमेशन की पूर्ण अवधि के द्वारा मुख्य फ़्रेमों की कुल संख्या को विभाजित करें: 100% / 25 = 4% ,
एक सेकंड में, 4 कुंजी फ़्रेम, या 1 सेकंड एनीमेशन का 4% है।

इस सभी गणित के साथ, हम अब स्लाइडर पर CSS एनीमेशन लागू कर सकते हैं। हम एनीमेशन को अंतहीन लूप में रख सकते हैं, क्योंकि प्रत्येक छवि के लिए, एक अलग एनीमेशन सेट किया जाएगा, बाकी छवियों से स्वतंत्र।

 #slider li.firstanimation { animation: cycle 25s linear infinite; } #slider li.secondanimation { animation: cycletwo 25s linear infinite; } #slider li.thirdanimation { animation: cyclethree 25s linear infinite; } #slider li.fourthanimation { animation: cyclefour 25s linear infinite; } #slider li.fifthanimation { animation: cyclefive 25s linear infinite; } 


एक बार एनीमेशन गुण असाइन किए जाने के बाद, हमें एनीमेशन को गति में सेट करने के लिए कीफ़्रेम का उपयोग करना चाहिए।
इस सिद्धांत के बाद, हम सभी एनिमेशन को एक दूसरे से जोड़ सकते हैं, भले ही वे एक दूसरे से स्वतंत्र हों। यह हमें एक अंतहीन चक्र देगा।
मैंने गुण " opacity " और " z-index " को एक छवि से अगले अधिक आकर्षक बनाने के लिए जोड़ा।
जैसा कि आप कोड में देख सकते हैं, पहले एनीमेशन में बाकी की तुलना में अधिक महत्वपूर्ण फ्रेम हैं। इसका कारण यह है कि जब स्लाइडर लॉन्च किया जाता है, तो पहली छवि दूसरी के लिए जगह खाली कर देती है, लेकिन जब अंतिम छवि अपना एनीमेशन खत्म कर देती है, तो पहली छवि में अतिरिक्त कुंजी फ़्रेम होने चाहिए ताकि एनीमेशन चक्रों के बीच रुकावट पैदा न हो।

यहाँ सभी एनीमेशन कोड है:
 /*  */ @keyframes cycle { 0% { top: 0px; } /*   ,     */ 4% { top: 0px; } /*   */ 16% { top: 0px; opacity:1; z-index:0; } /*  4%  16 % (3 )   */ 20% { top: 325px; opacity: 0; z-index: 0; } /*  16%  20% (1 ) */ 21% { top: -325px; opacity: 0; z-index: -1; } /*        */ 92% { top: -325px; opacity: 0; z-index: 0; } 96% { top: -325px; opacity: 0; } /*  96%  100% (1 ) –  */ 100%{ top: 0px; opacity: 1; } } @keyframes cycletwo { 0% { top: -325px; opacity: 0; } /*      */ 16% { top: -325px; opacity: 0; }/*    16% */ 20% { top: 0px; opacity: 1; } 24% { top: 0px; opacity: 1; } /*  20%  24% (  1 ) — */ 36% { top: 0px; opacity: 1; z-index: 0; } /*  24%  36 % (3 )   */ 40% { top: 325px; opacity: 0; z-index: 0; } /*  36%  40% (1 )—  */ 41% { top: -325px; opacity: 0; z-index: -1; } /*     */ 100%{ top: -325px; opacity: 0; z-index: -1; } } @keyframes cyclethree { 0% { top: -325px; opacity: 0; } 36% { top: -325px; opacity: 0; } 40% { top: 0px; opacity: 1; } 44% { top: 0px; opacity: 1; } 56% { top: 0px; opacity: 1; } 60% { top: 325px; opacity: 0; z-index: 0; } 61% { top: -325px; opacity: 0; z-index: -1; } 100%{ top: -325px; opacity: 0; z-index: -1; } } @keyframes cyclefour { 0% { top: -325px; opacity: 0; } 56% { top: -325px; opacity: 0; } 60% { top: 0px; opacity: 1; } 64% { top: 0px; opacity: 1; } 76% { top: 0px; opacity: 1; z-index: 0; } 80% { top: 325px; opacity: 0; z-index: 0; } 81% { top: -325px; opacity: 0; z-index: -1; } 100%{ top: -325px; opacity: 0; z-index: -1; } } @keyframes cyclefive { 0% { top: -325px; opacity: 0; } 76% { top: -325px; opacity: 0; } 80% { top: 0px; opacity: 1; } 84% { top: 0px; opacity: 1; } 96% { top: 0px; opacity: 1; z-index: 0; } 100%{ top: 325px; opacity: 0; z-index: 0; } } 


एनीमेशन बनाने के बाद, हमें प्रत्येक एनीमेशन की अवधि प्रदर्शित करने के लिए एक प्रगति पट्टी जोड़ने की आवश्यकता है।

5. प्रगति पट्टी




प्रगति पट्टी को एनिमेट करने की प्रक्रिया वही है जो स्लाइडर के लिए थी। प्रगति बार बनाएं:

 /*   */ .progress-bar { position: relative; top: -5px; width: 680px; height: 5px; background: #000; animation: fullexpand 25s ease-out infinite; } 


वाक्य रचना से डरें नहीं। "से" के रूप में एक ही कार्य है। आप देख सकते हैं कि कीफ्रेम प्रत्येक छवि की उपस्थिति और गायब होने को निर्धारित करते हैं।

 /*    */ @keyframes fullexpand { /*       */ 0%, 20%, 40%, 60%, 80%, 100% { width: 0%; opacity: 0; } /*   —  */ 4%, 24%, 44%, 64%, 84% { width: 0%; opacity: 0.3; } /*   —   */ 16%, 36%, 56%, 76%, 96% { width: 100%; opacity: 0.7; } /*          */ 17%, 37%, 57%, 77%, 97% { width: 100%; opacity: 0.3; } /*       ,     */ 18%, 38%, 58%, 78%, 98% { width: 100%; opacity: 0; } } 


6. टूलटिप




स्लाइडर कमोबेश पूरा हो गया है। आइए इसे और अधिक कार्यात्मक बनाने के लिए कुछ विवरण जोड़ें। हम छवि हेडर के लिए टूलटिप्स सम्मिलित करेंगे जो तब दिखाई देंगे जब आप होवर करेंगे।

संकेत के लिए शैलियाँ:
  #slider .tooltip { background: rgba(0,0,0,0.7); width: 300px; height: 60px; position: relative; bottom: 75px; left: -320px; } #slider .tooltip h1 { color: #fff; font-size: 24px; font-weight: 300; line-height: 60px; padding: 0 0 0 10px; } 


यहां हमने केवल छवि हेडर दिखाई दिए हैं, लेकिन आप किसी भी पाठ, लिंक और अपनी इच्छित किसी भी चीज़ के लिए ऐसा कर सकते हैं।

7. CSS3 के बदलाव




हमने देखा कि तत्वों के लिए CSS3 संक्रमण कैसे लागू किया जाए, अब हम उन्हें युक्तियों के लिए बनाते हैं।
यदि आपको याद है, तो हमने प्रत्येक सूची ("पहला", "दूसरा", आदि) में एक आईडी जोड़ा, ताकि जब आप हॉवर करें तो प्रत्येक संकेत एक अलग छवि के साथ जुड़ा हुआ था, जबकि सभी संकेत एक बार में प्रकट नहीं हुए थे।

 #slider .tooltip { … transition: all 0.3s ease-in-out; } #slider li#first: hover .tooltip, #slider li#second: hover .tooltip, #slider li#third: hover .tooltip, #slider li#fourth: hover .tooltip, #slider li#fifth: hover .tooltip { left: 0px; } 


8. रोकें और पुनः आरंभ करें




उपयोगकर्ताओं को स्लाइडर को रोकने की अनुमति देने के लिए, सामग्री को देखने के लिए, हमें उस पर मँडराते समय एनीमेशन को रोकना होगा। हमें प्रगति बार एनीमेशन को रोकने की भी आवश्यकता होगी।

 #slider: hover li, #slider: hover .progress-bar { animation-play-state: paused; } 


9. प्रदर्शन


अंत में, हम सबक के अंत में पहुंच गए। स्लाइडर अब 100% तैयार है!
स्लाइडर डेमो ( वैकल्पिक स्रोत ) देखें। यह फ़ायरफ़ॉक्स 5+, सफारी 4+ और Google क्रोम, साथ ही iPhone और iPad में काम करता है। आप संग्रह ( वैकल्पिक स्रोत ) भी डाउनलोड कर सकते हैं।
उनकी छवियों के लिए मास्सिमो रिघी का धन्यवाद।

10. निष्कर्ष


प्रभाव प्रभावशाली है, लेकिन माना जाता है कि यह स्लाइडर बहुत बहुमुखी नहीं है। उदाहरण के लिए, अधिक छवियों को जोड़ने के लिए, आपको सभी प्रमुख फ़्रेमों को संपादित करने की आवश्यकता है। CSS3 में बहुत संभावनाएं हैं, लेकिन इसकी सीमाएं हैं, और कभी-कभी जावास्क्रिप्ट लक्षित दर्शकों के आधार पर बेहतर होता है।
इस स्लाइडर में कुछ दिलचस्प विशेषताएं हैं, जैसे ठहराव (होवर पर) और अद्वितीय छवि लिंक जो उपयोगकर्ताओं को स्लाइडर के साथ बातचीत करने की अनुमति देते हैं। यदि सभी ब्राउज़रों द्वारा पूर्ण समर्थन की आवश्यकता है, तो CSS3 का उपयोग करना संभव नहीं है, इसलिए जावास्क्रिप्ट की सिफारिश की जाती है। दुर्भाग्य से, CSS3 के एनिमेशन में कई सीमाएँ हैं। फिलहाल, लचीलेपन की कमी के कारण, हमारे पास व्यापक उपयोग की संभावना नहीं है। मुझे उम्मीद है कि यह लेख आपको CSS3 सीखने के लिए प्रोत्साहित करेगा।
अपने विचारों को टिप्पणियों में साझा करने के लिए स्वतंत्र महसूस करें।

अनुवादक से:
यदि आपको कोई अनुवाद त्रुटि मिलती है, तो कृपया निजी संदेशों में सदस्यता समाप्त करें। आपका धन्यवाद

Source: https://habr.com/ru/post/In143025/


All Articles