मान अभिव्यक्ति (Value Expressions)

Script में जहाँ भी कोई मान आवश्यक होता है (URL, request body, field मान, शर्त, filter मान, target id आदि), वह नीचे दिए तीन रूपों में से एक होता है। अपवाद केवल दो हैं। Regex का pattern और Cache की key केवल लिटरल के रूप में लिखे जाते हैं और उनके भीतर का { /pointer } मान में नहीं बदलता। यह दस्तावेज़ उन तीन रूपों को, मान कहाँ से आते हैं (context रूट), और WEEGLOO डेटा के लिए विशिष्ट locale map नियमों को समझाता है। Statement कैटलॉग के सभी fields इस नियम का पालन करते हैं।

तीन रूप

रूपनियमउदाहरण
संदर्भ (reference)किसी string के भीतर के { /json-pointer } को context के सापेक्ष resolve करता है।"{ /payload/fields/title }"
लिटरल (literal){ /ptr } रहित मान (string, संख्या, बूलियन, ऑब्जेक्ट, array)। इसे ज्यों-का-त्यों उपयोग किया जाता है।"draft", 42, true, { "a": 1 }
संक्रिया और शर्त (JsonLogic)एक ऑब्जेक्ट जिसकी key एक ऑपरेटर होती है। इसके ऑपरेंड फिर से मान अभिव्यक्ति होते हैं (संदर्भ, लिटरल, नेस्टेड)। स्थान के अनुसार ऑपरेटर पर $ आवश्यक होता है।{ "$+": [ "{ /vars/n }", 1 ] }

तीनों रूप नेस्ट होते हैं। JsonLogic के ऑपरेंड में एक संदर्भ रखकर, फिर उस संदर्भ के परिणाम को किसी अन्य संक्रिया में डालकर इन्हें संयोजित किया जाता है।

डेटा स्थान और अभिव्यक्ति स्थान: $ कब लगाएं

एक ही JSON स्थान के अनुसार अलग-अलग पढ़ा जाता है। अंतर की कसौटी यह है कि उस स्थान की keys का स्वामी कौन हैfields की keys Content Type की field id होती हैं और Http.body की keys सामने वाले API की schema होती हैं, इसलिए ऐसे स्थानों पर cat या in ऑपरेटर नहीं, बल्कि field नाम होने चाहिए।

स्थानसंबंधित fieldपढ़ने का तरीका
डेटा स्थानfields (ResourceCreate, ResourceUpdate, ResourcePatch), Http.body, Return.value, SetVar.value, Cache.value, Cache.defaultValue$ रहित key हमेशा field नाम होती है। संक्रिया करनी हो तो $ लगाएं।
अभिव्यक्ति स्थानIf.condition, Loop.while, versionपूरा मान ही एक अभिव्यक्ति है। ऑपरेटर के रूप में cat भी चलता है और $cat भी।
टेम्प्लेट स्थानबाकी सब कुछ (url, method, headers[].value, locale, order, over, target.sys.id, EmailSend के fields, तथा Signature·Hash·Regex के मान वाले fields)ये string हैं, इसलिए इनमें केवल { /pointer } आता है।
केवल लिटरलRegex.pattern, Cache.keyयह मान अभिव्यक्ति नहीं है। Regex.pattern में लिखा { /pointer } प्रतिस्थापित नहीं होता, बल्कि pattern का हिस्सा बन जाता है।

नियम दो पंक्तियों का है।

  1. डेटा स्थान में $ रहित key हमेशा field नाम होती है। संक्रिया करनी हो तो ऑपरेटर पर $ लगाएं।
  2. एक बार $ के ज़रिए अभिव्यक्ति में प्रवेश कर जाने के बाद उसके भीतर सब कुछ अभिव्यक्ति है। नेस्टेड ऑपरेटरों पर $ की ज़रूरत नहीं होती (लगाएं तो भी चलता है)।

उलझन हो तो हर ऑपरेटर पर $ लगाएं। यह हर स्थान पर सही रहता है।

// डेटा स्थान: यहाँ cat, Content Type का field नाम है (जोड़ने वाली संक्रिया नहीं)
"fields": { "cat": { "en-US": "hello" } }
 
// डेटा स्थान में गणना: केवल सीमा पर $, उसके भीतर ज्यों-का-त्यों
"fields": { "tier": { "en-US": { "$if": [ { ">=": [ "{ /p/score }", 700 ] }, "gold", "silver" ] } } }
 
// अभिव्यक्ति स्थान: ज्यों-का-त्यों लिखें
"condition": { "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }

जब $ से शुरू होने वाला field नाम चाहिए: $$

JSON Schema के $ref, $schema की तरह जब key को सचमुच $ से शुरू होना हो, तो $ दो बार लिखें। "$$ref" का अर्थ डेटा key $ref है। सबसे आगे का केवल एक $ हटता है ($$$ref का अर्थ $$ref), और यह केवल keys पर लागू होता है (मान के भीतर का $ ज्यों-का-त्यों रहता है)।

"body": { "$$ref": "#/components/schemas/Item", "topK": { "$min": [ "{ /payload/fields/k }", 50 ] } }

दो चीज़ें जो अस्वीकार की जाती हैं

नीचे दिए दोनों मामलों को चुपचाप किसी दूसरे अर्थ में नहीं पढ़ा जाता, बल्कि त्रुटि मानकर अस्वीकार कर दिया जाता है।

  • $ key का उसी ऑब्जेक्ट की किसी दूसरी key के साथ होना त्रुटि है। संक्रिया उस ऑब्जेक्ट की एकमात्र key होनी चाहिए, और सहोदर डेटा को एक स्तर बाहर निकाल दें।
  • अज्ञात $ key त्रुटि है। $catt का अर्थ $catt नाम का कोई field नहीं है। $ नेमस्पेस ऑपरेटरों के लिए आरक्षित है।

अभिव्यक्ति स्थान में ऑपरेटर नाम का सहोदर keys के साथ होना भी त्रुटि है ({ "and": […], "or": […] })। उस स्थान पर डेटा जैसी कोई व्याख्या नहीं होती और हर ऑब्जेक्ट सत्य माना जाता है, इसलिए ऐसा छोड़ देने पर शर्त चुपचाप हमेशा सत्य हो जाती है।

संदर्भ: { /json-pointer }

ब्रेसेस { } के भीतर एक RFC 6901 JSON Pointer (जो अनिवार्यतः / से शुरू होता है) रखें। ब्रेसेस के आस-पास का space मान्य है ({ /a/b }, {/a/b} के समान है)।

एकल पॉइंटर बनाम मिश्रित टेम्प्लेट: टाइप नियम

  • जब पूरी string एक ही पॉइंटर हो, तो मान अपना मूल टाइप बनाए रखता है (संख्या हो तो संख्या, ऑब्जेक्ट हो तो ऑब्जेक्ट, array हो तो array)।
  • जब यह लिटरल टेक्स्ट के साथ मिश्रित हो, तो परिणाम string संयोजन (concatenation) होता है।
"{ /payload/fields/count }"                 // संख्या हो तो संख्या ज्यों-की-त्यों (उदा. 42)
"{ /payload/fields/tags }"                  // array हो तो array ज्यों-का-त्यों
"page-{ /payload/fields/n }-of-10"          // string संयोजन → "page-42-of-10"
"Bearer { /payload/fields/token }"          // string संयोजन → "Bearer abc123"

अनुपस्थित मान

  • जब path अनुपस्थित हो या मान खाली हो, तो एकल पॉइंटर null और मिश्रित टेम्प्लेट खाली string के रूप में संसाधित होता है।

Context रूट: मान कहाँ से आते हैं

{ /pointer } का शीर्ष-स्तरीय segment नीचे दिए सात में से एक होता है।

रूटसामग्री
/payloadcall के समय पास किया गया JSON payload (input)। उदाहरण: { /payload/fields/email }
/rawPayloadवही input, पर कॉलर द्वारा भेजी गई body string ज्यों-की-त्यों (पार्स करने से पहले)। उदाहरण: { /rawPayload }
/headerscall के समय पास किए गए request HTTP हेडर। keys लोअरकेस होती हैं और प्रति नाम एकल मान होता है। उदाहरण: { /headers/authorization }
/nowवह समय जब निष्पादन शुरू हुआ। { /now/seconds }·{ /now/millis }·{ /now/iso }
/<name>उस name को धारण करने वाले पूर्ववर्ती statement का परिणाम। उदाहरण: { /order/sys/id }
/vars/<name>SetVar से घोषित एक script-scoped परिवर्तनीय वेरिएबल। उदाहरण: { /vars/total }
/errorकेवल Try के catch block के भीतर उपयोग होता है। पकड़ी गई त्रुटि { message }। उदाहरण: { /error/message }

/<name> को छोड़कर बाकी छह नाम (payload·rawPayload·headers·now·vars·error) reserved हैं, इसलिए इन्हें किसी statement के name के रूप में उपयोग नहीं किया जा सकता। वही नाम रखने पर वह उस रूट को अधिलेखित कर देगा, इसलिए सहेजते समय ही अस्वीकृत हो जाता है (साझा field का बाइंडिंग नाम नियम)।

/rawPayload: भेजी गई ज्यों-की-त्यों body

/payload पार्स किया गया मान है, और /rawPayload उसी body की मूल string है। दोनों एक ही चीज़ की ओर संकेत करते हैं, पर एक समान नहीं हैं। पार्स किए गए मान को दोबारा string बनाने पर space, अंकों का लेखन, escape और डुप्लिकेट keys सब सामान्यीकृत हो जाते हैं, जिससे वह भेजे गए bytes पर नहीं लौटता।

इसीलिए जिन मानों की गणना भेजे गए bytes पर होती है, उन्हें केवल /rawPayload से ही संभाला जा सकता है। इसका प्रतिनिधि उदाहरण भुगतान प्रदाता के webhook का हस्ताक्षर सत्यापन है (Signature)। मान निकालकर उपयोग करने वाला रोज़मर्रा का संदर्भ /payload से किया जाता है।

call की body केवल JSON ऑब्जेक्ट ही स्वीकार करती है। body खाली हो तो उसे न होने के रूप में देखा जाता है, और वह JSON ऑब्जेक्ट न हो (टूटा JSON, array, स्केलर, लिटरल null) तो निष्पादन किए बिना अस्वीकृत कर दिया जाता है (त्रुटियाँ देखें)।

/now: वह समय जब निष्पादन शुरू हुआ

/now इस निष्पादन के शुरू होने का समय तीन रूपों में रखता है।

पॉइंटरमान
{ /now/seconds }epoch सेकंड (पूर्णांक)
{ /now/millis }epoch मिलीसेकंड (पूर्णांक)
{ /now/iso }sys.createdAt जैसी प्लेटफ़ॉर्म की समय-लेखन string (UTC)
  • एक निष्पादन में समय केवल एक ही होता है। यह घड़ी पढ़ने वाला statement नहीं, बल्कि निष्पादन शुरू होते समय रोप दिया जाने वाला मान है, इसलिए दो statements को अलग-अलग मान दिखने की स्थिति नहीं बनती। Parallel की हर शाखा को भी वही समय विरासत में मिलता है। यह statement नहीं है, इसलिए statement संख्या में भी नहीं गिना जाता।
  • समय-क्षेत्र (time zone) चुनने वाला कोई field नहीं है। epoch मान हर जगह एक ही संख्या होता है, और iso UTC लेखन है।
  • इसका उपयोग webhook के replay window (हस्ताक्षर में शामिल timestamp अब से कितने सेकंड के भीतर है) के सत्यापन में किया जाता है। timestamp आमतौर पर string के रूप में आता है, पर अंकगणितीय संक्रिया उसे संख्या में बदल देती है, इसलिए उसकी तुलना ज्यों-की-त्यों की जाती है।
// हस्ताक्षर में शामिल timestamp 5 मिनट (300 सेकंड) के भीतर है या नहीं
{ "<": [ { "-": [ "{ /now/seconds }", "{ /sig/1 }" ] }, 300 ] }

statement परिणाम का आकार

name धारण करने वाले statement के परिणाम का आकार टाइप के अनुसार भिन्न होता है।

statementपरिणाम आकारसंदर्भ उदाहरण
Http{ status, body }{ /resp/status }, { /resp/body/choices/0/message/content }
ResourceCreate, ResourceRead(एकल), ResourceFind(एकल)संसाधन स्वयं{ /post/sys/id }, { /post/fields/title/en-US }
ResourceForEach(पुनरावृत्ति के दौरान) name वर्तमान आइटम = संसाधन स्वयं। केवल onEach के भीतर संदर्भित{ /post/sys/id }, { /post/fields/title/en-US }
ParseJsonपार्स किया गया मान स्वयं (ऑब्जेक्ट·array·स्केलर){ /quote/items/0/price }
SignatureBoolean (सत्यापन पास हुआ या नहीं){ /verified }
Hashstring (घोषित रूप का डाइजेस्ट){ /expectedSign }
RegexMatch में BooleanCapture में array (0 = पूरा मिलान, 1 से capture group), और मिलान न हो तो null{ /isOrderId }, { /sig/1 }
  • ResourceFind कोई मैच न होने पर null bind करता है। अस्तित्व के आधार पर शाखा बनाने के लिए { "==": [ "{ /found }", null ] } का उपयोग करें।
  • ResourceRead(एकल) में target न होने पर यह त्रुटि है (Try से संभाला जा सकता है)। विस्तृत जानकारी Statement कैटलॉग का संसाधन पठन में दी गई है।
  • ServiceUser पढ़ने पर परिणाम सदस्य संसाधन स्वयं होता है ({ /member/sys/id })। Content और Media के विपरीत इसके field locale map नहीं, बल्कि सीधे मान होते हैं। नियम सदस्य डायरेक्टरी का पठन में दिए गए हैं।

संक्रिया और शर्त: JsonLogic

जब कोई गणना या शर्त आवश्यक हो, तो jsonlogic.com spec के ऑपरेटर ऑब्जेक्ट का उपयोग करें।

  • डेटा एक्सेस को vanilla var (dot-path) से नहीं, बल्कि { /ptr } संदर्भ पर मानकीकृत किया गया है। इंजन पहले ऑपरेंड के पॉइंटर को resolve करता है, फिर ऑपरेटर लागू करता है।
  • ऑपरेटर उस ऑब्जेक्ट की एकमात्र key होना चाहिए। डेटा स्थान में केवल $ लगी key ही संक्रिया है, और अभिव्यक्ति स्थान में $ हो या न हो, वह संक्रिया ही है (डेटा स्थान और अभिव्यक्ति स्थान देखें)।

ऑपरेटर तालिका

तालिका में दिए नाम ऑपरेटर टोकन हैं। डेटा स्थान में उपयोग करते समय इनके आगे $ लगाएं (cat का $cat)। अभिव्यक्ति स्थान में दोनों चलते हैं।

श्रेणीऑपरेटरअर्थ और उदाहरण
शर्तif (उपनाम ?:){ "if": [शर्त, सत्य मान, शर्त2, सत्य मान2, …, डिफ़ॉल्ट मान] }. पहली सत्य शर्त का मान, न हो तो अंतिम डिफ़ॉल्ट मान।
तर्कand, orशॉर्ट-सर्किट मूल्यांकन। and पहला falsy (या अंतिम), or पहला truthy (या अंतिम) ऑपरेंड मान के रूप में लौटाता है।
तर्क! (not), !! (to-bool){ "!": x } truthy का निषेध करता है, { "!!": x } truthy होना बताता है। अस्तित्व जाँच के लिए !! अक्सर उपयोग होता है।
समानता==, !=ढीली तुलना (संख्या में रूपांतरण के बाद तुलना; "1"==1 सत्य है)।
समानता===, !==सख्त तुलना (टाइप सहित)।
तुलना<, <=, >, >=शृंखलाबद्ध: { "<": [1,2,3] } का अर्थ 1<2 AND 2<3 है। संख्या में परिवर्तित न हो सके (NaN) तो false।
अंकगणित+सभी ऑपरेंड का योग।
अंकगणित-एक ऑपरेंड हो तो ऋणात्मक बनाना, दो हों तो घटाव।
अंकगणित*, /, %गुणा, भाग, शेष।
समुच्चयनmin, maxऑपरेंड में से न्यूनतम, अधिकतम।
स्ट्रिंगcatसभी ऑपरेंड को string के रूप में जोड़ना।
समावेशin{ "in": [needle, haystack] }. haystack यदि string हो तो सबस्ट्रिंग, collection हो तो तत्व समावेश।
arraymergeकई array या मानों को एक ही array में समतल करना (संचय के लिए उपयोग)।

array पर पुनरावृत्ति करने वाले ऑपरेटर (map, filter, reduce, all, some, none) समर्थित नहीं हैं। Script किसी array पर Loop से पुनरावृत्ति करता है (Statement कैटलॉग का Loop)।

संख्या रूपांतरण और उदाहरण

संख्या रूपांतरण के नियम इस प्रकार हैं। संख्या को ज्यों-का-त्यों रखा जाता है, true को 1, false को 0 में बदला जाता है, string को पार्स किया जाता है (पार्स न हो सके तो गणना विफल हो जाती है), और null को 0 में बदला जाता है।

नीचे दिए स्निपेट अभिव्यक्ति स्थान के हिसाब से लिखे गए हैं। इन्हें डेटा स्थान (fields, Http.body, Return.value, SetVar.value) में रखते समय सबसे ऊपरी ऑपरेटर पर $ लगाएं और भीतर के ऑपरेंड ज्यों-के-त्यों छोड़ दें।

{ "-":  [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] }   // बैलेंस - लागत
{ "<":  [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] }   // बैलेंस < लागत → boolean
{ "and": [ { "<": [ "{ /a/body/risk }", 0.5 ] }, { ">=": [ "{ /b/body/score }", 700 ] } ] }
{ "cat": [ "id-", "{ /payload/sys/id }" ] }                                    // "id-<uuid>"
{ "!!": "{ /found/sys/id }" }                                                  // मौजूद हो तो true
{ "$merge": [ "{ /vars/ids }", [ "{ /row/sys/id }" ] ] }                       // array संचय: SetVar.value डेटा स्थान है इसलिए $
{ "if": [ "{ /payload/fields/next }", "{ /payload/fields/next }", "END" ] }     // next हो तो next, न हो तो "END"

सत्य और असत्य का निर्धारण (Truthiness)

if, and, or, !, !! तथा If.condition, Loop.while नीचे दिए नियमों से सत्य और असत्य तय करते हैं।

  • falsy: null, false, संख्या 0, खाली string "", खाली collection (खाली array)।
  • truthy: बाकी सब कुछ (0 से भिन्न संख्या, गैर-खाली string और array, हर ऑब्जेक्ट)।

keys भी संदर्भ हो सकती हैं

fields जैसे map की keys भी { /ptr } संदर्भ का समर्थन करती हैं। key runtime पर resolve होती है।

"fields": { "{ /payload/fields/fieldName }": { "en-US": "{ /payload/fields/fieldValue }" } }

यदि दो keys एक ही मान में resolve होती हैं, तो टकराव होता है और यह इंजन त्रुटि है।

locale map: Content और Media के लिए विशिष्ट नियम

WEEGLOO के Content और Media का प्रत्येक field एक मान नहीं, बल्कि locale-वार map होता है (उदाहरण: balance जो { "en-US": 1, "ko-KR": 10 } है)। इसलिए पढ़ते और लिखते समय locale को साथ में संभालना पड़ता है। Media में भी title और description (स्केलर), तथा file (ingest निर्देश) locale map हैं। /payload या HTTP प्रतिक्रिया जैसे, जो Content या Media नहीं हैं, ऐसे JSON इस नियम से असंबद्ध हैं (वे schema द्वारा निर्धारित संरचना जैसे-के-वैसे रहते हैं, और स्केलर हो तो स्केलर रहते हैं)।

पठन

  • स्केलर पाने के लिए locale तक निर्दिष्ट करें: { /<name>/fields/<field>/<locale> } (उदाहरण: { /post/fields/title/en-US })।
  • locale के बिना { /<name>/fields/<field> } देने पर पूरा locale map ऑब्जेक्ट लौटता है।
  • localized:false field केवल डिफ़ॉल्ट locale बकेट में होता है, इसलिए उसे उस डिफ़ॉल्ट locale कोड से पढ़ें।

लेखन (ResourceCreate, ResourceUpdate, ResourcePatch के fields)

मान एक locale map { "<locale>": <स्केलर मान अभिव्यक्ति> } होता है। यह पठन के सममित है।

"fields": {
  "title":  { "en-US": "Hello", "ko-KR": "안녕" },   // कई locales के लिए बकेट सूचीबद्ध
  "status": { "en-US": "paid" }
}
  • ResourceCreate populate किए जाने वाले हर field में Space की डिफ़ॉल्ट locale बकेट अनिवार्यतः शामिल करनी चाहिए (default-locale नियम)।
  • ResourceUpdate संपूर्ण प्रतिस्थापन हैfields में अनुपस्थित fields और locales हटा दिए जाते हैं (file सहित)।
  • ResourcePatch केवल निर्दिष्ट fields और बकेट को ही अपडेट करता है (बाकी fields और locales बनाए रखे जाते हैं)।
  • लिटरल null से हटाएं: यदि मान लिटरल null है, तो वह (field, locale) बकेट हटा दी जाती है (Patch में किसी विशिष्ट locale को खाली करने का मानक तरीका)। "" (खाली string) हटाना नहीं, बल्कि खाली मान सेट करना है। यदि कोई मान अभिव्यक्ति ({ /ptr }) runtime पर null में मूल्यांकित होती है, तो यह हटाना नहीं, बल्कि त्रुटि है (payload की अनुपस्थिति को चुपचाप नहीं निगला जाता)। हटाना केवल लिटरल null पर ही लागू होता है।
  • Media का file: मान स्केलर नहीं, बल्कि एक ingest निर्देश { "source": …, "encoding": "url"|"base64" } है। ingest वास्तव में क्या करता है, यह Statement कैटलॉग का ResourceCreate में दिया गया है।
  • localized:false field को केवल डिफ़ॉल्ट locale बकेट में डालें।
  • locale कोड (map की key) भी { /ptr } संदर्भ हो सकता है (ऊपर keys भी संदर्भ हो सकती हैं देखें)। गतिशील locale बनाते समय इसका उपयोग करें।

locale सुविधा field

ResourceCreate, ResourceUpdate, ResourcePatch को locale देने पर, इंजन fields के प्रत्येक मान को स्वतः { <locale>: मान } बकेट में लपेट देता है। अर्थात् केवल स्केलर देना पर्याप्त है।

// नीचे दिए दोनों समान हैं
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
  "locale": "en-US", "fields": { "title": "Hello" } }
 
{ "type": "ResourceCreate", "resource": "Content", "contentType": { "sys": { "id": "ct_post" } },
  "fields": { "title": { "en-US": "Hello" } } }

locale देते हुए यदि मान में पहले से एक locale map ({ "en-US": … }) नेस्ट किया गया हो, तो यह { <locale>: { "en-US": … } } की तरह दोहरा नेस्ट हो जाता है (लेखक की गलती)। एक ही शैली पर टिके रहें: locale का उपयोग करें तो केवल स्केलर, न करें तो केवल स्पष्ट locale map।

where और order की locale

  • where और order में fields.X पर इंजन Space की डिफ़ॉल्ट locale स्वतः लागू करता है (CMA क्वेरी के समान)।
  • किसी विशिष्ट locale को निर्दिष्ट करने के लिए fields.X.<locale> के रूप में स्पष्ट करें।
"where": { "fields.slug": { "eq": "{ /payload/fields/slug }" } }   // डिफ़ॉल्ट locale slug
"where": { "fields.title.ko-KR": { "prefix": "안" } }              // विशिष्ट locale

त्रुटियाँ

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

कोडशर्त
WGL400056डेटा स्थान में $ संक्रिया key को उसी ऑब्जेक्ट की किसी दूसरी key के साथ रखा गया है।
WGL400055डेटा स्थान में ऐसी $ key लिखी गई है जो किसी ऑपरेटर के रूप में परिभाषित नहीं है।