config.json


config.json फाइल ट्रैक के कॉन्फिगरेशन का वर्णन करती है। इसमें ट्रैक के अभ्यासों और कॉन्सेप्ट जैसी ज़रूरी जानकारी रहती है।

मेटाडेटा

ट्रैक का सामान्य मेटाडेटा इन टॉप-लेवल प्रॉपर्टी में रहता है:

  • language: ट्रैक की भाषा (जैसे "C#")। इसकी लंबाई <= 255 होनी चाहिए। (आवश्यक)
  • slug: ट्रैक की भाषा, छोटे अक्षरों में लिखी कीबैब-केस स्ट्रिंग के रूप में (जैसे "csharp")। इसकी लंबाई <= 255 होनी चाहिए। (आवश्यक)
  • active: एक boolean वैल्यू जो बताती है कि ट्रैक सक्रिय है या नहीं (यानी शिक्षार्थी वेबसाइट पर ट्रैक जॉइन कर सकते हैं) (आवश्यक)
  • blurb: भाषा का छोटा विवरण। इसकी लंबाई <= 400 होनी चाहिए। (आवश्यक)
  • version: config.json फाइल का वर्ज़न (अभी यह 3 पर तय है) (आवश्यक)
  • online_editor: एक ऑब्जेक्ट जो ऑनलाइन एडिटर के लिए इस्तेमाल होने वाली सेटिंग्स का वर्णन करता है: (आवश्यक)
    • indent_style: "space" या "tab" में से कोई एक (आवश्यक)
    • indent_size: इंडेंटेशन का आकार, एक पूर्णांक के रूप में (जैसे 4) (आवश्यक)
    • highlightjs_language: Highlight.js के लिए भाषा पहचानकर्ता (देखिए पहचानकर्ताओं की पूरी सूची) (वैकल्पिक)
  • status: एक ऑब्जेक्ट जो बताता है कि कौन से v3 फीचर सक्षम होने चाहिए: (आवश्यक)
    • concept_exercises: एक boolean वैल्यू जो बताती है कि कॉन्सेप्ट अभ्यास बनाए जा चुके हैं या नहीं (आवश्यक)। जब यह true होता है, तो Exercism वेबसाइट का इंटरफेस बदल जाता है और बताता है कि इस ट्रैक के लिए कॉन्सेप्ट अभ्यास उपलब्ध हैं।
    • test_runner: एक boolean वैल्यू जो बताती है कि टेस्ट रनर लागू किया गया है या नहीं (आवश्यक)। जब यह true होता है, तो हम जमा किए गए हल हमारे टेस्टिंग इन्फ्रास्ट्रक्चर से गुज़ारते हैं और वेबसाइट पर नतीजे दिखाते हैं। वेबसाइट शिक्षार्थियों को ऑनलाइन एडिटर के भीतर से ही टेस्ट रन शुरू करने की सुविधा भी देती है।
    • representer: एक boolean वैल्यू जो बताती है कि रिप्रेज़ेंटर लागू किया गया है या नहीं (आवश्यक)
    • analyzer: एक boolean वैल्यू जो बताती है कि एनालाइज़र लागू किया गया है या नहीं (आवश्यक)
  • files: किसी अभ्यास में इस्तेमाल होने वाली फाइलों के स्थान के पैटर्न, अभ्यास की डायरेक्टरी के सापेक्ष। (वैकल्पिक)
    • solution: स्टब इम्प्लीमेंटेशन फाइल का पैटर्न (वैकल्पिक)
    • test: टेस्ट फाइल का पैटर्न (वैकल्पिक)
    • example: उदाहरण इम्प्लीमेंटेशन फाइल का पैटर्न (वैकल्पिक)
    • exemplar: एक्ज़ेम्प्लर इम्प्लीमेंटेशन फाइल का पैटर्न (वैकल्पिक)
    • editor: अतिरिक्त रीड-ओनली एडिटर फाइल के पैटर्न (वैकल्पिक)
  • test_runner: एक ऑब्जेक्ट जो ट्रैक के टेस्ट रनर का वर्णन करता है (अगर कोई हो): (status.test_runner के true होने पर आवश्यक)
    • average_run_time: टेस्ट रनर को चलने में औसतन कितने सेकंड लगते हैं, इसके लिए एक पूर्णांक number वैल्यू (जैसे 4) (status.test_runner के true होने पर आवश्यक)
  • approaches: एक ऑब्जेक्ट जिसमें ट्रैक के अप्रोच पर मेटाडेटा रहता है: (ट्रैक में कोई अप्रोच होने पर आवश्यक)
    • snippet_extension: स्निपेट फाइल के एक्सटेंशन के लिए इस्तेमाल होने वाली स्ट्रिंग वैल्यू (जैसे rb) (ट्रैक में कोई अप्रोच होने पर आवश्यक)

फाइलें

यह की पूरे ट्रैक के लिए फाइलों के स्थान तय करने में इस्तेमाल होती है। मेंटेनर को हर अभ्यास की config.json फाइल में खुद से files की सेट करने की ज़रूरत के बजाय configlet इन पूरे-ट्रैक पैटर्न की मदद से इसे अपने आप भर सकता है।

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

  • %{kebab_slug}: kebab-case में लिखा अभ्यास का स्लग (जैसे bit-manipulation)
  • %{snake_slug}: snake_case में लिखा अभ्यास का स्लग (जैसे bit_manipulation)
  • %{camel_slug}: camelCase में लिखा अभ्यास का स्लग (जैसे bitManipulation)
  • %{pascal_slug}: PascalCase में लिखा अभ्यास का स्लग (जैसे BitManipulation)

configlet में यह सुविधा जोड़ी जाएगी कि वह इन पैटर्न का इस्तेमाल करके किसी अभ्यास की .meta/config.json फाइल में files की भर सके।

उदाहरण

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  }
}

अभ्यास

टॉप-लेवल exercises की एक ऑब्जेक्ट है जिसमें तीन संभावित की हो सकती हैं:

  • concept: यह एक ऐरे है जिसमें ट्रैक के कॉन्सेप्ट अभ्यासों की सूची रहती है
  • practice: यह एक ऐरे है जिसमें ट्रैक के प्रैक्टिस अभ्यासों की सूची रहती है
  • foregone: यह एक ऐरे है जिसमें उन अभ्यासों के स्लग की सूची रहती है जिन्हें ट्रैक लागू नहीं करेगा

कॉन्सेप्ट अभ्यास

exercises.concept ऐरे में हर कॉन्सेप्ट अभ्यास की एक एंट्री होती है। वेबसाइट पर अभ्यास उसी क्रम में दिखते हैं जिस क्रम में वे इस फाइल में लिखे होते हैं, और यह क्रम उसी सामान्य क्रम से मेल खाना चाहिए जिसमें उन्हें हल किया जाना चाहिए। एक कॉन्सेप्ट अभ्यास इन फील्ड से बनता है:

  • uuid: एक V4 UUID जो अभ्यास को विशिष्ट रूप से पहचानता है। यह UUID ट्रैक के भीतर भी और सभी ट्रैकों में भी अद्वितीय होना चाहिए, और कभी नहीं बदलना चाहिए
  • slug: अभ्यास का स्लग, जो छोटे अक्षरों वाली कीबैब-केस स्ट्रिंग होती है। यह स्लग ट्रैक के सभी कॉन्सेप्ट और प्रैक्टिस अभ्यासों के स्लग में अद्वितीय होना चाहिए। इसकी लंबाई <= 255 होनी चाहिए।
  • name: अभ्यास का नाम। इसकी लंबाई <= 255 होनी चाहिए।
  • concepts: उन कॉन्सेप्ट स्लगों का ऐरे जो यह कॉन्सेप्ट अभ्यास सिखाता है
  • prerequisites: उन कॉन्सेप्ट स्लगों का ऐरे जो शिक्षार्थी के इस अभ्यास को शुरू करने से पहले अनलॉक हो चुके होने चाहिए
  • status (वैकल्पिक): अभ्यास की स्थिति, जो "wip", "beta", "active" या "deprecated" में से एक होती है; न बताई जाए तो डिफॉल्ट "active" होती है
    • wip: एक ऐसा अभ्यास जो अभी बन रहा है और सबके लिए तैयार नहीं है। इस टैग वाले अभ्यास शिक्षार्थियों को UI पर नहीं दिखाए जाते और अनलॉक करने वाले नियम में भी इस्तेमाल नहीं होते। ये मेंटेनर को दिख सकते हैं।
    • beta: यह ऐसे सक्रिय अभ्यासों को दर्शाता है जो नए हैं और जिन पर हमें फीडबैक चाहिए। इन अभ्यासों के लिए साइट पर एक बीटा लेबल दिखाया जाता है, साथ में "कृपया हमें फीडबैक दीजिए।" का कॉल टू एक्शन।
    • active: सक्रिय अभ्यासों की सामान्य स्थिति
    • deprecated: ऐसे अभ्यास जो उन शिक्षार्थियों को अब नहीं दिखाए जाते जिन्होंने उन्हें शुरू नहीं किया (इस चरण में ये इस्तेमाल करने लायक नहीं हैं)। ज़्यादा जानकारी के लिए डेप्रिकेटेड अभ्यास देखिए।

उदाहरण

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ]
      },
      ...
    ]
  }
}

अभी बन रहे अभ्यास का उदाहरण

{
  "exercises": {
    "concept": [
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      },
      ...
    ]
  }
}

प्रैक्टिस अभ्यास

exercises.practice ऐरे में हर प्रैक्टिस अभ्यास की एक एंट्री होती है। एक प्रैक्टिस अभ्यास इन फील्ड से बनता है:

  • uuid: एक V4 UUID जो अभ्यास को विशिष्ट रूप से पहचानता है। यह UUID ट्रैक के भीतर भी और सभी ट्रैकों में भी अद्वितीय होना चाहिए, और कभी नहीं बदलना चाहिए
  • slug: अभ्यास का स्लग, जो छोटे अक्षरों वाली कीबैब-केस स्ट्रिंग होती है। यह स्लग ट्रैक के सभी कॉन्सेप्ट और प्रैक्टिस अभ्यासों के स्लग में अद्वितीय होना चाहिए। इसकी लंबाई <= 255 होनी चाहिए।
  • name: अभ्यास का नाम। इसकी लंबाई <= 255 होनी चाहिए।
  • practices: उन कॉन्सेप्ट स्लगों का ऐरे जिनका अभ्यास शिक्षार्थियों को इस अभ्यास से कराया जाता है
  • prerequisites: उन कॉन्सेप्ट स्लगों का ऐरे जो शिक्षार्थी के इस अभ्यास को शुरू करने से पहले अनलॉक हो चुके होने चाहिए
  • difficulty: अभ्यास की कठिनाई बताने वाली एक संख्या। यह संख्या 1 (सबसे आसान) से 10 (सबसे कठिन) के बीच होनी चाहिए। वेबसाइट कठिनाई को इस तरह समझती है:
    • 1,2,3: आसान
    • 4,5,6,7: मध्यम
    • 8,9,10: कठिन
  • status (वैकल्पिक): अभ्यास की स्थिति, जो "wip", "beta", "active" या "deprecated" में से एक होती है; न बताई जाए तो डिफॉल्ट "active" होती है
    • wip: एक ऐसा अभ्यास जो अभी बन रहा है और सबके लिए तैयार नहीं है। इस टैग वाले अभ्यास शिक्षार्थियों को UI पर नहीं दिखाए जाते और अनलॉक करने वाले नियम में भी इस्तेमाल नहीं होते। ये मेंटेनर को दिख सकते हैं।
    • beta: यह ऐसे सक्रिय अभ्यासों को दर्शाता है जो नए हैं और जिन पर हमें फीडबैक चाहिए। इन अभ्यासों के लिए साइट पर एक बीटा लेबल दिखाया जाता है, साथ में "कृपया हमें फीडबैक दीजिए" का कॉल टू एक्शन
    • active: सक्रिय अभ्यासों की सामान्य स्थिति
    • deprecated: ऐसे अभ्यास जो उन शिक्षार्थियों को अब नहीं दिखाए जाते जिन्होंने उन्हें शुरू नहीं किया (इस चरण में ये इस्तेमाल करने लायक नहीं हैं)।

वेबसाइट पर प्रैक्टिस अभ्यासों का "अनुशंसित क्रम" practice ऐरे में अभ्यासों के क्रम के अनुसार ही होता है।

उदाहरण

{
  "exercises": {
    "practice": [
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 1
      },
      ...
    ]
  }
}

बीटा का उदाहरण

{
  "exercises": {
    "practice": [
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 1,
        "status": "beta"
      },
      ...
    ]
  }
}

छोड़े गए अभ्यास

अगर किसी ट्रैक को पता है कि वह Problem Specifications रेपो में तय किसी अभ्यास को लागू नहीं करना चाहता, तो उस अभ्यास का स्लग exercises.foregone की में जोड़ा जा सकता है। ट्रैक के लागू न किए गए अभ्यासों की सूची बनाते समय configlet छोड़े गए अभ्यासों को अनदेखा कर देगा।

किसी ट्रैक का कोई अभ्यास लागू करने का मन न होने की कुछ वजहें ये हो सकती हैं:

  • वह अभ्यास उस भाषा में ठीक से लागू ही न किया जा सके। जैसे lens-person अभ्यास के लिए ज़रूरी है कि भाषा lenses का समर्थन करे।
  • अभ्यास का विषय भाषा से मेल न खाए। जैसे कुछ हाई-लेवल भाषाओं के लिए लो-लेवल बिट-मैनिपुलेशन वाला अभ्यास बेमतलब लग सकता है।

उदाहरण

{
  "exercises": {
    "foregone": [
      "lens-person"
    ]
  }
}

कॉन्सेप्ट

टॉप-लेवल concepts ऐरे में हर कॉन्सेप्ट की एक एंट्री होती है। एक कॉन्सेप्ट इन फील्ड से बनता है:

  • uuid: एक V4 UUID जो कॉन्सेप्ट को विशिष्ट रूप से पहचानता है। यह UUID ट्रैक के भीतर भी और सभी ट्रैकों में भी अद्वितीय होना चाहिए, और कभी नहीं बदलना चाहिए
  • slug: कॉन्सेप्ट का स्लग, जो छोटे अक्षरों वाली कीबैब-केस स्ट्रिंग होती है। यह स्लग ट्रैक के सभी कॉन्सेप्ट में अद्वितीय होना चाहिए। इसकी लंबाई <= 255 होनी चाहिए।
  • name: कॉन्सेप्ट का नाम। इसकी लंबाई <= 255 होनी चाहिए।
  • tags: यह तय करता है कि कोई सबमिशन किस हालत में किसी अप्रोच से जुड़ता है। (वैकल्पिक)
    • all: ऐसे टैगों का ऐरे जो सब के सब किसी सबमिशन पर मौजूद होने चाहिए (वैकल्पिक, जब तक कि any खाली न हो)
    • any: ऐसे टैगों का ऐरे जिनमें से कम से कम एक किसी सबमिशन पर मौजूद होना चाहिए (वैकल्पिक, जब तक कि all खाली न हो)
    • not: इनमें से कोई भी टैग किसी सबमिशन पर मौजूद नहीं होना चाहिए (वैकल्पिक)

उदाहरण

{
  "concepts": [
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers",
      "tags": {
        "all": [
          "concept:number"
        ]
      }
    }
  ]
}

मुख्य विशेषताएँ

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

मुख्य विशेषताएँ टॉप-लेवल key_features फील्ड में तय होती हैं, जो इन फील्ड वाले ऑब्जेक्ट का ऐरे होता है:

  • title: मुख्य विशेषता के लिए छोटा शीर्षक। इसकी लंबाई <= 25 होनी चाहिए। Markdown का समर्थन नहीं है।
  • content: मुख्य विशेषता का विवरण। इसकी लंबाई <= 100 होनी चाहिए। Markdown का समर्थन नहीं है।
  • icon: विशेषता के लिए दिखाने वाला आइकन। आप अपनी पसंद का कोई भी आइकन चुन सकते हैं, चाहे उसका नाम कुछ भी हो। ये आइकन इस्तेमाल किए जा सकते हैं:
    • community
    • concurrency
    • cross-platform
    • documentation
    • dynamically-typed
    • easy
    • embeddable
    • evolving
    • expressive
    • extensible
    • fast
    • fun
    • functional
    • garbage-collected
    • general-purpose
    • homoiconic
    • immutable
    • interactive
    • interop
    • multi-paradigm
    • portable
    • powerful
    • productive
    • safe
    • scientific
    • small
    • stable
    • statically-typed
    • tooling
    • web
    • widely-used

आप इन आइकन का रूप मुख्य विशेषता आइकन वाले हिस्से पर देख सकते हैं।

ठीक 6 मुख्य विशेषताएँ बतानी होंगी।

उदाहरण

{
  "key_features": [
    {
      "title": "Fault-tolerant",
      "content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
      "icon": "safe"
    },
    ...
  ],
}

टैग

ट्रैकों पर टैग लगाए जा सकते हैं, जिससे किसी खास टैग-संयोजन वाले ट्रैक खोजे जा सकते हैं।

किसी ट्रैक को अपने टैग अपनी भाषा के आम इस्तेमाल के आधार पर चुनने चाहिए। जैसे सोचिए, कोई शिक्षार्थी मन में सोच रहा है: "मुझे मशीन लर्निंग करनी है, कौन सी भाषा चुनूँ?", या "मुझे फंक्शनल प्रोग्रामिंग सीखनी है, कौन सी भाषा चुनूँ?"। अगर आपकी भाषा इसके लिए अच्छी रहेगी, तो उसे वह टैग दीजिए। अगर आपकी भाषा कुछ फंक्शनल विचारों का समर्थन करती है पर उनका इस्तेमाल शायद ही होता है, या बहुत कम लोग उसमें मशीन लर्निंग करते हैं, तो वे टैग मत लगाइए।

टैग टॉप-लेवल tags फील्ड में तय होते हैं, जो स्ट्रिंग का ऐरे होता है। ये टैग इस्तेमाल किए जा सकते हैं (श्रेणी के हिसाब से):

पैराडाइम

  • paradigm/array: भाषा एक ऐरे प्रोग्रामिंग भाषा है
  • paradigm/declarative: भाषा प्रोग्रामिंग की डिक्लेरेटिव शैली का समर्थन करती है
  • paradigm/functional: भाषा प्रोग्रामिंग की फंक्शनल शैली का समर्थन करती है
  • paradigm/imperative: भाषा प्रोग्रामिंग की इम्पेरेटिव शैली का समर्थन करती है
  • paradigm/logic: भाषा प्रोग्रामिंग की लॉजिक आधारित शैली का समर्थन करती है
  • paradigm/object_oriented: भाषा प्रोग्रामिंग की ऑब्जेक्ट-ओरिएंटेड शैली का समर्थन करती है
  • paradigm/procedural: भाषा प्रोग्रामिंग की प्रोसीजरल शैली का समर्थन करती है
  • paradigm/stack-oriented: भाषा प्रोग्रामिंग की स्टैक-ओरिएंटेड शैली का समर्थन करती है

टाइपिंग

  • typing/static: भाषा स्टैटिक टाइपिंग इस्तेमाल करती है
  • typing/gradual: भाषा ग्रैजुअल टाइपिंग इस्तेमाल करती है
  • typing/dynamic: भाषा डाइनैमिक टाइपिंग इस्तेमाल करती है
  • typing/strong: भाषा स्ट्रॉन्ग टाइपिंग इस्तेमाल करती है
  • typing/weak: भाषा वीक टाइपिंग इस्तेमाल करती है

एक्ज़ीक्यूशन मोड

  • execution_mode/compiled: कोड चलाने से पहले उसे कंपाइल किया जाता है
  • execution_mode/interpreted: कोड सीधे इंटरप्रेट किया जाता है

प्लेटफॉर्म

  • platform/windows: Windows पर चलता है
  • platform/mac: Mac पर चलता है
  • platform/linux: Linux पर चलता है
  • platform/ios: iOS पर चलता है
  • platform/android: Android पर चलता है
  • platform/web: ब्राउज़र पर चलता है

रनटाइम

  • runtime/standalone_executable: स्टैंडअलोन एक्ज़ीक्यूटेबल के रूप में चलता है
  • runtime/language_specific: भाषा-खास रनटाइम पर चलता है
  • runtime/clr: Common Language Runtime (.NET) पर चलता है
  • runtime/jvm: JVM (Java) पर चलता है
  • runtime/beam: BEAM (Erlang) पर चलता है
  • runtime/wasmtime: Wasmtime (WebAssembly) पर चलता है

इनके लिए इस्तेमाल

  • used_for/artificial_intelligence: आर्टिफिशियल इंटेलिजेंस
  • used_for/backends: बैकएंड
  • used_for/cross_platform_development: क्रॉस-प्लेटफॉर्म डेवलपमेंट
  • used_for/embedded_systems: एम्बेडेड सिस्टम
  • used_for/financial_systems: वित्तीय सिस्टम
  • used_for/frontends: फ्रंटएंड
  • used_for/games: गेम
  • used_for/guis: GUI
  • used_for/mobile: मोबाइल
  • used_for/robotics: रोबोटिक्स
  • used_for/scientific_calculations: वैज्ञानिक गणनाएँ
  • used_for/scripts: स्क्रिप्ट
  • used_for/web_development: वेब डेवलपमेंट

ध्यान रखिए कि एक ही श्रेणी से कई टैग रखना बिल्कुल ठीक है।

उदाहरण

{
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}

उदाहरण

यह एक उदाहरण है कि एक मान्य config.json फाइल कैसी दिख सकती है:

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  },
  "exercises": {
    "concept": [
      {
        "slug": "lucians-luscious-lasagna",
        "name": "Lucian's Luscious Lasagna",
        "uuid": "7d358894-4fbd-4c91-b49f-d68f1c5aa6bc",
        "concepts": [
          "basics"
        ],
        "prerequisites": []
      },
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      }
    ],
    "practice": [
      {
        "slug": "hello-world",
        "name": "Hello, World!",
        "uuid": "6c88f46b-5acb-4fae-a6ec-b48ae3f8168f",
        "practices": [
          "strings"
        ],
        "prerequisites": [
          "basics"
        ],
        "difficulty": 1
      },
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 2,
        "status": "beta"
      }
    ]
  },
  "concepts": [
    {
      "uuid": "2eb4a463-355f-46ef-ac55-a75ec5afdf86",
      "slug": "basics",
      "name": "Basics"
    },
    {
      "uuid": "4466e33e-dcd2-4b1f-9d9d-2c4315bf5188",
      "slug": "if-statements",
      "name": "If Statements"
    },
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers"
    },
    {
      "uuid": "7a86561d-173b-45c0-a53c-1ffd7b9ff259",
      "slug": "strings",
      "name": "Strings"
    }
  ],
  "key_features": [
    {
      "title": "Modern",
      "content": "C# is a modern, fast-evolving language.",
      "icon": "expressive"
    },
    {
      "title": "Cross-platform",
      "content": "C# runs on almost any platform and chipset.",
      "icon": "cross-platform"
    },
    {
      "title": "Multi-paradigm",
      "content": "C# is primarily an object-oriented language, but also has lots of functional features.",
      "icon": "multi-paradigm"
    },
    {
      "title": "General purpose",
      "content": "C# can be used for a wide variety of workloads, like websites, console applications, and even games.",
      "icon": "general-purpose"
    },
    {
      "title": "Tooling",
      "content": "C# has excellent tooling, with linting and advanced refactoring options built-in.",
      "icon": "tooling"
    },
    {
      "title": "Documentation",
      "content": "Documentation is excellent and exhaustive, making it easy to get started with C#.",
      "icon": "documentation"
    }
  ],
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}