शब्द
किसी कंपोनेंट के अपने कोई शब्द नहीं होते। कंपोनेंट जो भी लेबल, नाम और संदेश दिखाता या कहता है, वह आपके प्रॉडक्ट का है, जो कंपोनेंट पर दिया जाता है, पूरे प्रॉडक्ट के लिए एक बार, या आपके import किए अंग्रेज़ी शब्दों के पैक से लिया जाता है।
किसी कंपोनेंट के अपने कोई शब्द नहीं होते। किसी कंपोनेंट का किसी भी भाषा में कोई डिफ़ॉल्ट टेक्स्ट नहीं है: न “ज़रूरी”, न “बंद करें”, न “ठीक है”। कंपोनेंट जो शब्द दिखाता या कहता है, वह आपके प्रॉडक्ट का दिया हुआ है: आपका लिखा हुआ, या अंग्रेज़ी शब्दों के पैक से लिया हुआ, जिसे आप ख़ुद import करते हैं।
डिफ़ॉल्ट उसी चूक को छिपा देता है जो उसकी वजह से होती है। जापानी का जो प्रॉडक्ट एक शब्द भूल जाता है, वह अपने टेक्स्ट के बग़ल में अंग्रेज़ी दिखाता है, और इसकी रिपोर्ट कहीं नहीं होती। अंग्रेज़ी के प्रॉडक्ट की भी अपनी आवाज़ होती है (“Mandatory”, “Done”, “Nothing found”)। इसलिए कंपोनेंट के पास ऐसा कोई शब्द नहीं है जिस पर वह लौट सके, और जब कोई शब्द नहीं मिलता, तो वह आपको बताता है। अंग्रेज़ी शब्दों का पैक ऐसा फ़ॉलबैक नहीं है: आपके अपने import के सिवा उसे कुछ भी लागू नहीं करता।
कंपोनेंट तीन जगह देखता है, इसी क्रम में, और कहीं नहीं।
| जगह | क्या देता है | उदाहरण |
|---|---|---|
| ख़ुद कंपोनेंट | इसी एक चीज़ के बारे में शब्द, और वह शब्द जिसे यह एक कंपोनेंट अलग ढंग से कहता है | label, error-text; close-label="फ़िल्टर बंद करें" |
| आपके प्रॉडक्ट के शब्द | वे शब्द जिन्हें आप हर उस जगह एक ही तरह कहते हैं जहाँ वह भाग दिखता है, हर भाषा के लिए एक बार दिए गए, या आपके import किए अंग्रेज़ी शब्दों के पैक से | requiredText, closeLabel, previousMonthLabel |
| प्लैटफ़ॉर्म | जो ब्राउज़र के पास पाठक की भाषा में पहले से है | महीनों और हफ़्ते के दिनों के नाम, अंक, “AM”, ख़ाली छूटे मान के लिए ब्राउज़र का अपना संदेश |
इनके बाद कुछ नहीं है: न कोई फ़ॉलबैक भाषा, न “फ़िलहाल के लिए” अंग्रेज़ी।
Tanrei आपके लिए आपके प्रॉडक्ट के शब्दों का एक सेट लिखता है: हर कुंजी के लिए सादी, तटस्थ अंग्रेज़ी में एक शब्द, जैसे “Required”, “Close” और “Previous month”। इसे एक बार import करें:
import '@tanrei/web/words/en';यह पूरे पेज के शब्द देता है, ठीक वैसे ही जैसे setWords() की एक कॉल देती। आपकी जगह इसे कोई import नहीं करता: न @tanrei/web, न @tanrei/react, न कोई कंपोनेंट, और न पेज का lang। हर कुंजी के लिए पैक का शब्द कुंजियों की तालिका में है।
- आपके अपने शब्द फिर भी जीतते हैं। import के बाद
setWords()कॉल करें, तो आपकी दी हुई कुंजियाँ पैक के शब्दों की जगह ले लेती हैं; कंपोनेंट पर दिया शब्द इन दोनों से ऊपर है। import चलते ही हर कुंजी देता है, इसलिए उससे पहले दिया गया शब्द बदल जाता है। - इसके शब्दों से शुरू करें। मॉड्यूल इन्हें मान के रूप में भी देता है:
import { englishWords } from '@tanrei/web/words/en'। - किसी दूसरी भाषा के प्रॉडक्ट में, जो कुंजी आपकी भाषा के सेट में नहीं है, वह पेज के सेट से पढ़ी जाती है, और पैक import हो तो वह अंग्रेज़ी है। इसे वहीं import करें जहाँ आपकी न लिखी कुंजी के लिए अंग्रेज़ी ही वह शब्द है जो आप चाहते हैं; इसके बिना छूटे शब्द की रिपोर्ट होती है।
- यह वह नहीं छिपाता जो उसे नहीं छिपाना चाहिए। पैक import होने पर हर कुंजी का शब्द होता है, इसलिए
missingWords()ख़ाली रहता है। आपके प्रॉडक्ट ने जो शब्द अभी ख़ुद नहीं लिखे, उन्हें ढूँढने के लिए उस टेस्ट में पूछें जो पैक import नहीं करता।
React में भी import यही एक लाइन है, उस मॉड्यूल में जो सबसे पहले रेंडर होता है।
वेब पर setWords() को एक बार कॉल करें, कंपोनेंट के लोड होने से पहले या बाद में। जो एलिमेंट पेज पर पहले से हैं, वे ये शब्द तुरंत दिखाते हैं।
import { setWords } from '@tanrei/web';
setWords({
requiredText: 'ज़रूरी',
optionalText: 'वैकल्पिक',
closeLabel: 'बंद करें',
clearLabel: 'मिटाएँ',
targetLabel: 'नए टैब में खुलता है',
});सिर्फ़ उन्हीं कंपोनेंट के शब्द दें जो आप इस्तेमाल करते हैं। दूसरा कॉल पहले में जोड़ता है, एक-एक कुंजी करके; ख़ाली स्ट्रिंग के रूप में दी गई कुंजी हटा दी जाती है। @tanrei/web/words यही फ़ंक्शन कोई एलिमेंट डिफ़ाइन किए बिना एक्सपोर्ट करता है, और @tanrei/react भी इसे एक्सपोर्ट करता है।
किसी एक कंपोनेंट पर लिखा ऐट्रिब्यूट आपके प्रॉडक्ट के शब्दों पर हमेशा जीतता है:
ख़ुद कंपोनेंट पर लिखा शब्द: एक फ़ील्ड इसे अलग ढंग से कहता है
<tanrei-text-field label="ईमेल" required required-text="ज़रूरी"></tanrei-text-field>
<tanrei-text-field label="कंपनी" required required-text="इनवॉइस के लिए ज़रूरी"></tanrei-text-field>हर भाषा के लिए एक सेट दें। कंपोनेंट अपने आसपास के सबसे नज़दीकी lang ऐट्रिब्यूट का सेट पढ़ता है, इसलिए जापानी का पेज, या अंग्रेज़ी पेज का जापानी हिस्सा, जापानी शब्द पढ़ता है।
setWords({ requiredText: 'Required', closeLabel: 'Close' }, { lang: 'en' });
setWords({ requiredText: '必須', closeLabel: '閉じる' }, { lang: 'ja' });jaका सेटja-JPके लिए भी काम करता है, जब तक आपja-JPको उसका अपना सेट न दें।- जो कुंजी किसी भाषा के सेट में नहीं है, वह उस सेट से पढ़ी जाती है जो
langके बिना दिया गया है। - शब्द सादी स्ट्रिंग हैं। अगर आपके प्रॉडक्ट में लोकलाइज़ेशन की कोई लाइब्रेरी है, तो स्ट्रिंग वहीं से लेकर दें:
setWords()अनुवाद का सिस्टम नहीं है, और इसमें बहुवचन के नियम नहीं हैं। कुछ शब्दों में ऐसी जगहें होती हैं जिन्हें कंपोनेंट भरता है, और शब्द में इसके अलावा कुछ नहीं पढ़ा जाता।
कुछ वाक्यों में ऐसा मान होता है जिसे सिर्फ़ कंपोनेंट जानता है, उसी पल जब वह उन्हें कहता है: ले जाए जाने के बाद कोई पंक्ति कहाँ है, या पेस्ट से कितनी एंट्री बनीं। पूरा वाक्य फिर भी आपका प्रॉडक्ट लिखता है। मान कहाँ जाएगा, यह वह ब्रेस के बीच लिखे एक नाम से चिह्नित करता है, और कंपोनेंट मान को वहीं रख देता है।
setWords({ movedText: '{headline}: {position} of {count}' }, { lang: 'en' });
setWords({ movedText: '{headline}:{count} 件中 {position} 番目' }, { lang: 'ja' });शब्दों का क्रम आपकी भाषा का है। कंपोनेंट जगहें भरता है और वाक्य के साथ और कुछ नहीं करता।
- नाम कंपोनेंट तय करता है। हर कुंजी की अपनी जगहें हैं, जो कुंजियों की टेबल में दी गई हैं, और सिर्फ़ वही भरी जाती हैं। आप किसी जगह को एक बार लिख सकते हैं, कई बार, या बिलकुल नहीं।
- संख्या एलिमेंट की भाषा में लिखी जाती है।
{count}और{position}पूर्ण संख्याएँ हैं, जो सबसे नज़दीकीlangके अंकों और ग्रुपिंग के साथ लिखी जाती हैं। - टेक्स्ट अपनी दिशा बनाए रखता है।
{headline}और{entry}वे टेक्स्ट हैं जो कंपोनेंट के पास हैं: किसी पंक्ति की हेडलाइन, किसी व्यक्ति की टाइप की हुई एंट्री। वे सादे टेक्स्ट के रूप में रखे जाते हैं, मार्कअप के रूप में कभी नहीं। जहाँ वाक्य दिखाया या पढ़कर सुनाया जाता है, वहाँ यह टेक्स्ट आइसोलेट किया जाता है, इसलिए अरबी वाक्य के भीतर का लैटिन नाम अपने ही क्रम में रहता है। - ब्रेस लिखना हो, तो उसे दो बार लिखें।
{{को{के रूप में दिखाया जाता है और}}को}के रूप में। जिस शब्द में भरने की कोई जगह नहीं है, वह पढ़ा ही नहीं जाता, इसलिए वहाँ ब्रेस एक ही बार लिखा जाता है। - एक जगह ज़रूरी है।
entryRemoveLabelचिप फ़ील्ड की हर एंट्री के हटाने वाले बटन को नाम देता है।{entry}के बिना हर बटन का नाम एक ही होता है।
डेवलपमेंट में कंसोल इन बातों की रिपोर्ट करता है: ऐसी जगह जो उस कुंजी की नहीं है ({entri}), बिना जोड़ी का अकेला ब्रेस, और {entry} का न होना। वाक्य फिर भी ठीक वैसे ही इस्तेमाल होता है जैसा आपने लिखा। setWords() इनकी रिपोर्ट तब करता है जब आप शब्द देते हैं, और कंपोनेंट तब, जब वह एलिमेंट पर दिया गया शब्द इस्तेमाल करता है।
कंपोनेंट के पास कोई व्याकरण नहीं है: न बहुवचन के रूप, न क्रमसूचक संख्याएँ, न दो वाक्यों में से एक का चुनाव। संख्या से निपटने के आपके पास तीन तरीक़े हैं, और किसी के लिए Tanrei से कुछ नहीं चाहिए।
- ऐसा वाक्य लिखें जो हर संख्या के लिए सही हो:
{count} में से {position},जोड़े गए: {count}। - शब्द कंपोनेंट पर दें, और गिनती बदलने पर उसे बदलें। गिनती आपका प्रॉडक्ट जानता है, और कंपोनेंट पर दिया शब्द हमेशा जीतता है। वाक्य आपके अपने बहुवचन के नियम चुनते हैं।
- जहाँ संख्याएँ ख़ुद आपके प्रॉडक्ट के पास हैं, वहाँ शब्द में भरने की कोई जगह नहीं होती: टेबल की स्थिति (“132 में से 1–20”) एक पूरी स्ट्रिंग है, जो आप लिखते हैं।
छूटा हुआ शब्द प्रॉडक्ट की चूक है, जैसे बिना लेबल का टेक्स्ट फ़ील्ड। कंपोनेंट उसे व्यक्ति के लिए छोटा रखता है और आपके लिए दिखने लायक़।
- जो शब्द दिखने थे, वे नहीं दिखते। जहाँ कोई निशान वही बात कहता है, वहाँ उनकी जगह वह निशान रहता है: ज़रूरी के टैग के लिए तारांकन, पिकर के “रद्द करें” और “ठीक है” के लिए बंद करने और चेक के आइकन, “अगला दिन” के लिए
+1। जहाँ ऐसा कोई निशान नहीं है, वहाँ कुछ नहीं दिखता और वह जगह अपना साइज़ रखती है। - जिस कंट्रोल को नाम चाहिए, वह तब भी दिखता है और तब भी काम करता है। कैलेंडर के नेविगेशन बटन, टेक्स्ट फ़ील्ड का साइज़ हैंडल और पिकर की क्रियाएँ नाम के बिना भी काम करती रहती हैं। इकलौता अपवाद नंबर फ़ील्ड के स्टेपर हैं: बिना नाम का स्टेपर सहायक तकनीक से छिपा रहता है, क्योंकि उसके बग़ल का स्पिन बटन ख़ुद मान बढ़ाता और घटाता है।
- इसकी रिपोर्ट होती है। डेवलपमेंट में कंसोल ऐट्रिब्यूट का नाम बताता है, हर शब्द और पेज के लिए एक बार:
<tanrei-field>: required-text is empty and the product's words have no requiredText।
बिना एक्सेसिबल नाम का कंट्रोल उन लोगों के काम नहीं आता जो स्क्रीन रीडर इस्तेमाल करते हैं। रिपोर्ट इसलिए है कि आप उसे ठीक करें, इसलिए नहीं कि आप उसे वैसा ही छोड़ दें।
missingWords() वे कुंजियाँ लौटाता है जिनकी पेज के लोड होने के बाद से ज़रूरत पड़ी और जो किसी ने नहीं दीं। इसे उस टेस्ट के अंत में पूछें जो आपके पूरे प्रॉडक्ट से होकर गुज़रता है। जो पेज अंग्रेज़ी शब्दों का पैक import करता है, उसमें कोई शब्द नहीं छूटता।
import { missingWords } from '@tanrei/web';
test('प्रॉडक्ट को जिस भी शब्द की ज़रूरत है, वह दिया गया है', async () => {
// …प्रॉडक्ट की स्क्रीन रेंडर करें…
expect(missingWords()).toEqual([]);
});ग्लिफ़, तारांकन, डैश, अंक और वह सेपरेटर जो लोकेल देता है, शब्द नहीं हैं, और कंपोनेंट उन्हें तब भी दिखाता है। API के नाम (कोई प्रॉपर्टी, कोई मान) भी शब्द नहीं हैं, और न वह जो कंसोल डेवलपर को बताता है, जो अंग्रेज़ी में है। कीबोर्ड शॉर्टकट जो अक्षर दिखाता है (“Ctrl”, “Enter”, ⌘), वे वही हैं जो कीबोर्ड की कुंजियों पर ख़ुद लिखे होते हैं; शॉर्टकट के लिए जो पढ़कर सुनाया जाता है, वह आपका दिया हुआ label है।
हर कुंजी, वे प्रॉपर्टी जो उसे पढ़ती हैं, वे जगहें जिन्हें कंपोनेंट उसके वाक्य में भरता है, और अंग्रेज़ी शब्दों के पैक में उसका शब्द। ज़्यादातर कुंजियों का नाम वही है जो उनकी प्रॉपर्टी का है। तीन अलग हैं: कॉपी बटन की label और failedLabel प्रॉपर्टी copyLabel और copyFailedLabel पढ़ती हैं, और ब्रेडक्रंब की overflowLabel प्रॉपर्टी breadcrumbsOverflowLabel पढ़ती है।
| कुंजी | पढ़ने वाली प्रॉपर्टी | भरी जाने वाली जगहें | अंग्रेज़ी शब्दों के पैक में |
|---|---|---|---|
addedLabel | code-block.addedLabel | Added | |
attachLabel | chat-composer.attachLabel | Attach files | |
avatarGroupOverflowLabel | avatar.overflowLabel | {count} | {count} more |
backLabel | search.backLabel | Back | |
breadcrumbsOverflowLabel | breadcrumbs.overflowLabel | Show hidden levels | |
busyLabel | button.busyLabel | Loading | |
cancelLabel | date-time-picker.cancelLabel | Cancel | |
cancelledText | file-upload.cancelledText, list.cancelledText | {label}, {position}, {count} | {label} returned to {position} of {count} |
characterCountNoLimitText | text-input.counterNoLimitText | {count} | Characters: {count} |
characterCountText | text-input.counterText | {count}, {limit}, {remaining} | Characters: {count} of {limit} |
clearLabel | combobox.clearLabel, navigation-drawer.filterClearLabel, search.clearLabel, tree-view.filterClearLabel | Clear | |
closeLabel | bottom-sheet.closeLabel, callout.closeLabel, image-preview.closeLabel, popover.closeLabel, side-sheet.closeLabel, snackbar.closeLabel | Close | |
confirmLabel | date-time-picker.confirmLabel | OK | |
copiedLabel | code-block.copiedLabel, copy-button.copiedLabel | Copied | |
copyFailedLabel | code-block.copyFailedLabel, copy-button.failedLabel | Could not copy | |
copyLabel | code-block.copyLabel, copy-button.label | Copy | |
dateLabel | date-time-picker.dateLabel | Date | |
decrementLabel | number-input.decrementLabel | Decrease | |
dialLabel | date-time-picker.dialLabel | Dial | |
dragHandleHint | file-upload.dragHandleHint, list.dragHandleHint | Press Space to lift, the arrow keys to move, Space to drop, Escape to cancel; Enter opens the moves | |
dragHandleLabel | file-upload.dragHandleLabel, list.dragHandleLabel | {label} | Reorder {label} |
dropZoneRefusingText | drop-zone.refusingText | These files cannot be added here | |
dropZoneText | drop-zone.dropText | Drop files here | |
duplicateEntryText | chip-field.duplicateText | This is already in the list. | |
editLabel | tree-view.editLabel | Name | |
emptyText | combobox.emptyText | No matches | |
endLabel | calendar.endLabel, date-time-picker.endLabel | End | |
entriesAddedText | chip-field.addedCountText | {count} | Added: {count} |
entryAddedText | chip-field.addedText | {entry} | {entry} added |
entryLimitText | chip-field.limitText | No more can be added. | |
entryModeLabel | date-time-picker.entryModeLabel | Input mode | |
entryRemoveLabel | chip-field.removeLabel | {entry} | Remove {entry} |
entryRemovedText | chip-field.removedText | {entry} | {entry} removed |
expandLabel | snackbar.expandLabel | Show full message | |
externalLabel | link.externalLabel, link-card.externalLabel | external link | |
fileCountErrorText | chat-composer.countErrorText, file-upload.countErrorText | No more files can be added. | |
fileSizeErrorText | chat-composer.sizeErrorText, file-upload.sizeErrorText | This file is too large. | |
fileTypeErrorText | chat-composer.typeErrorText, file-upload.typeErrorText | This kind of file cannot be added. | |
filesDroppedText | drop-zone.droppedText | {count} | Files added: {count} |
filesRefusedText | drop-zone.refusedText | {count} | Files not added: {count} |
filterCountText | navigation-drawer.filterCountText, tree-view.filterCountText | {count} | Matches: {count} |
filterEmptyText | navigation-drawer.filterEmptyText, tree-view.filterEmptyText | No matches | |
filterPlaceholder | navigation-drawer.filterPlaceholder, tree-view.filterPlaceholder | Filter | |
firstPageLabel | pagination.firstLabel | First page | |
handleLabel | bottom-sheet.handleLabel | Resize sheet | |
highlightedLabel | code-block.highlightedLabel | Highlighted | |
hourLabel | date-time-picker.hourLabel | Hour | |
imageCountText | image-preview.countText | {position}, {count} | {position} of {count} |
imageErrorText | image-preview.errorText | This image could not be loaded | |
incrementLabel | number-input.incrementLabel | Increase | |
lastPageLabel | pagination.lastLabel | Last page | |
liftedText | file-upload.liftedText, list.liftedText | {label}, {position}, {count} | {label} lifted: {position} of {count} |
loadingLabel | image-preview.loadingLabel, navigation-drawer.loadingLabel, skeleton.label, tree-view.loadingLabel | Loading | |
marqueePauseLabel | marquee-text.pauseLabel | Pause scrolling text | |
marqueePlayLabel | marquee-text.playLabel | Play scrolling text | |
menubarOverflowLabel | menubar.overflowLabel | More | |
minuteLabel | date-time-picker.minuteLabel | Minute | |
moveAfterLabel | file-upload.moveAfterLabel, list.moveAfterLabel | Move down | |
moveBeforeLabel | file-upload.moveBeforeLabel, list.moveBeforeLabel | Move up | |
moveToEndLabel | file-upload.moveToEndLabel, list.moveToEndLabel | Move to bottom | |
moveToStartLabel | file-upload.moveToStartLabel, list.moveToStartLabel | Move to top | |
movedText | file-upload.movedText, list.movedText | {label}, {position}, {count} | {label}: {position} of {count} |
nextDayLabel | date-time-picker.nextDayLabel | next day | |
nextImageLabel | image-preview.nextLabel | Next image | |
nextItemLabel | carousel.nextLabel | Next slide | |
nextMonthLabel | calendar.nextMonthLabel, date-time-picker.nextMonthLabel | Next month | |
nextPageLabel | pagination.nextLabel | Next page | |
noFileText | file-upload.emptyText | No file chosen | |
noOptionsText | select.emptyText | No options | |
optionalText | field.optionalText, field-group.optionalText | Optional | |
pageCountText | pagination.countText | {page}, {count} | Page {page} of {count} |
pageLabel | pagination.pageLabel | {page} | Page {page} |
pauseLabel | carousel.pauseLabel | Pause slideshow | |
periodLabel | date-time-picker.periodLabel | AM/PM | |
playLabel | carousel.playLabel | Play slideshow | |
previousImageLabel | image-preview.previousLabel | Previous image | |
previousItemLabel | carousel.previousLabel | Previous slide | |
previousMonthLabel | calendar.previousMonthLabel, date-time-picker.previousMonthLabel | Previous month | |
previousPageLabel | pagination.previousLabel | Previous page | |
rangeErrorText | date-time-picker.rangeErrorText | End must be after start | |
rangeLabel | date-time-picker.rangeLabel | Range | |
removeLabel | file-item.removeLabel | {name} | Remove {name} |
removedLabel | code-block.removedLabel | Removed | |
requiredText | field.requiredText, field-group.requiredText | Required | |
resizeLabel | text-input.resizeLabel | Resize | |
retryLabel | file-item.retryLabel | {name} | Retry {name} |
segmentEmptyText | text-input.segmentEmptyText | Empty | |
selectAllLabel | table.selectAllLabel | Select all rows | |
sendLabel | chat-composer.sendLabel | Send | |
sortedAscendingLabel | table.sortedAscendingLabel | sorted ascending | |
sortedDescendingLabel | table.sortedDescendingLabel | sorted descending | |
startLabel | calendar.startLabel, date-time-picker.startLabel | Start | |
stepCompletedText | stepper.completedText | Completed | |
stepErrorText | stepper.errorText | Has an error | |
stepPositionText | stepper.positionText | {position}, {count} | Step {position} of {count} |
stopLabel | chat-composer.stopLabel | Stop | |
targetLabel | button.targetLabel, card.targetLabel, chip.targetLabel, link.targetLabel, link-card.targetLabel, list/list-item.targetLabel, menu/item.targetLabel, menubar/item.targetLabel, navigation-bar/destination.targetLabel, navigation-drawer/destination.targetLabel, search/result.targetLabel, search/result-group.targetLabel | opens in a new tab | |
todayLabel | calendar.todayLabel, date-time-picker.todayLabel | Today | |
toolbarOverflowLabel | toolbar.overflowLabel | More actions | |
wheelsLabel | date-time-picker.wheelsLabel | Wheels | |
yearViewLabel | calendar.yearViewLabel, date-time-picker.yearViewLabel | Choose a year | |
zoomInLabel | image-preview.zoomInLabel | Zoom in | |
zoomOutLabel | image-preview.zoomOutLabel | Zoom out |
जो शब्द किसी एक चीज़ के बारे में हैं, जैसे फ़ील्ड का label, तारीख़ और समय पिकर का label, हटाने वाले बटन का “Ada Lovelace को हटाएँ”, या गिनती वाला स्थिति टेक्स्ट, उनकी कोई कुंजी नहीं है: उन्हें कंपोनेंट पर दें।
नियम हर प्लैटफ़ॉर्म पर वही है। अभी तक सिर्फ़ वेब बना है; SwiftUI, Jetpack Compose, Flutter और React Native प्रॉडक्ट के शब्द, और यही अंग्रेज़ी शब्दों का पैक, अपने-अपने तरीक़े से लेंगे।